#include "extensions/browser/api/socket/mojo_data_pump.h"
#include <memory>
#include <string>
#include <utility>
#include "base/containers/span.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/base/test_completion_callback.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace extensions {
TEST(MojoDataPumpTest, ReceiveStreamNotReady) {
base::test::TaskEnvironment task_environment;
mojo::ScopedDataPipeProducerHandle receive_producer_handle;
mojo::ScopedDataPipeConsumerHandle receive_consumer_handle;
ASSERT_EQ(mojo::CreateDataPipe(nullptr, receive_producer_handle,
receive_consumer_handle),
MOJO_RESULT_OK);
mojo::ScopedDataPipeProducerHandle send_producer_handle;
mojo::ScopedDataPipeConsumerHandle send_consumer_handle;
ASSERT_EQ(
mojo::CreateDataPipe(nullptr, send_producer_handle, send_consumer_handle),
MOJO_RESULT_OK);
auto pump = std::make_unique<MojoDataPump>(std::move(receive_consumer_handle),
std::move(send_producer_handle));
std::string data("dummy");
base::RunLoop run_loop;
bool callback_called = false;
pump->Read(10 ,
base::BindLambdaForTesting(
[&](int result, scoped_refptr<net::IOBuffer> io_buffer) {
callback_called = true;
ASSERT_EQ(static_cast<int>(data.size()), result);
EXPECT_EQ(data,
std::string(io_buffer->data(), result));
run_loop.Quit();
}));
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(callback_called);
size_t actually_written_bytes = 0;
MojoResult r = receive_producer_handle->WriteData(base::as_byte_span(data),
MOJO_WRITE_DATA_FLAG_NONE,
actually_written_bytes);
ASSERT_EQ(MOJO_RESULT_OK, r);
ASSERT_EQ(data.size(), actually_written_bytes);
run_loop.Run();
EXPECT_TRUE(callback_called);
}
TEST(MojoDataPumpTest, ReceiveStreamClosed) {
base::test::TaskEnvironment task_environment;
mojo::ScopedDataPipeProducerHandle receive_producer_handle;
mojo::ScopedDataPipeConsumerHandle receive_consumer_handle;
ASSERT_EQ(mojo::CreateDataPipe(nullptr, receive_producer_handle,
receive_consumer_handle),
MOJO_RESULT_OK);
mojo::ScopedDataPipeProducerHandle send_producer_handle;
mojo::ScopedDataPipeConsumerHandle send_consumer_handle;
ASSERT_EQ(
mojo::CreateDataPipe(nullptr, send_producer_handle, send_consumer_handle),
MOJO_RESULT_OK);
auto pump = std::make_unique<MojoDataPump>(std::move(receive_consumer_handle),
std::move(send_producer_handle));
base::RunLoop run_loop;
pump->Read(10 ,
base::BindLambdaForTesting(
[&](int result, scoped_refptr<net::IOBuffer> io_buffer) {
EXPECT_EQ(0, result);
EXPECT_EQ(nullptr, io_buffer);
run_loop.Quit();
}));
receive_producer_handle.reset();
run_loop.Run();
}
TEST(MojoDataPumpTest, SendStreamClosed) {
base::test::TaskEnvironment task_environment;
mojo::ScopedDataPipeProducerHandle receive_producer_handle;
mojo::ScopedDataPipeConsumerHandle receive_consumer_handle;
ASSERT_EQ(mojo::CreateDataPipe(nullptr, receive_producer_handle,
receive_consumer_handle),
MOJO_RESULT_OK);
mojo::ScopedDataPipeProducerHandle send_producer_handle;
mojo::ScopedDataPipeConsumerHandle send_consumer_handle;
ASSERT_EQ(
mojo::CreateDataPipe(nullptr, send_producer_handle, send_consumer_handle),
MOJO_RESULT_OK);
auto pump = std::make_unique<MojoDataPump>(std::move(receive_consumer_handle),
std::move(send_producer_handle));
scoped_refptr<net::StringIOBuffer> write_buffer =
base::MakeRefCounted<net::StringIOBuffer>("dummy");
net::TestCompletionCallback callback;
send_consumer_handle.reset();
pump->Write(write_buffer.get(), write_buffer->size(), callback.callback());
EXPECT_EQ(net::ERR_FAILED, callback.WaitForResult());
}
}