This source file includes following definitions.
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- Seq
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
#include "mojo/system/local_data_pipe.h"
#include <string.h>
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "mojo/system/data_pipe.h"
#include "mojo/system/waiter.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace mojo {
namespace system {
namespace {
const uint32_t kSizeOfOptions =
static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions));
TEST(LocalDataPipeTest, Creation) {
{
MojoCreateDataPipeOptions default_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(NULL, &default_options));
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(default_options));
dp->ProducerClose();
dp->ConsumerClose();
}
{
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
1,
1000
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
dp->ProducerClose();
dp->ConsumerClose();
}
{
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
4,
4000
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
dp->ProducerClose();
dp->ConsumerClose();
}
{
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD,
7,
7000000
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
dp->ProducerClose();
dp->ConsumerClose();
}
{
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD,
100,
0
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
dp->ProducerClose();
dp->ConsumerClose();
}
}
TEST(LocalDataPipeTest, SimpleReadWrite) {
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
static_cast<uint32_t>(sizeof(int32_t)),
1000 * sizeof(int32_t)
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
int32_t elements[10] = { 0 };
uint32_t num_bytes = 0;
num_bytes = static_cast<uint32_t>(arraysize(elements) * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
dp->ConsumerReadData(elements, &num_bytes, false));
num_bytes = 0;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(0u, num_bytes);
num_bytes = static_cast<uint32_t>(5u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
dp->ConsumerDiscardData(&num_bytes, false));
num_bytes = sizeof(elements[0]) + 1;
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
dp->ConsumerReadData(elements, &num_bytes, false));
elements[0] = 123;
elements[1] = 456;
num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerWriteData(elements, &num_bytes, false));
EXPECT_EQ(2u * sizeof(elements[0]), num_bytes);
num_bytes = 0;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(2 * sizeof(elements[0]), num_bytes);
elements[0] = -1;
elements[1] = -1;
num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(elements, &num_bytes, false));
EXPECT_EQ(1u * sizeof(elements[0]), num_bytes);
EXPECT_EQ(123, elements[0]);
EXPECT_EQ(-1, elements[1]);
num_bytes = 0;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(1 * sizeof(elements[0]), num_bytes);
elements[0] = -1;
elements[1] = -1;
num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
dp->ConsumerReadData(elements, &num_bytes, true));
EXPECT_EQ(-1, elements[0]);
EXPECT_EQ(-1, elements[1]);
elements[0] = -1;
elements[1] = -1;
num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(elements, &num_bytes, false));
EXPECT_EQ(456, elements[0]);
EXPECT_EQ(-1, elements[1]);
num_bytes = 0;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(0u, num_bytes);
dp->ProducerClose();
dp->ConsumerClose();
}
TEST(LocalDataPipeTest, BasicProducerWaiting) {
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
static_cast<uint32_t>(sizeof(int32_t)),
2 * sizeof(int32_t)
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
Waiter waiter;
waiter.Init();
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 12));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 34));
int32_t elements[2] = { 123, 456 };
uint32_t num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(elements, &num_bytes, true));
EXPECT_EQ(static_cast<uint32_t>(2u * sizeof(elements[0])), num_bytes);
waiter.Init();
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 56));
EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
dp->ProducerRemoveWaiter(&waiter);
waiter.Init();
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 78));
elements[0] = -1;
elements[1] = -1;
num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(elements, &num_bytes, true));
EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
EXPECT_EQ(123, elements[0]);
EXPECT_EQ(-1, elements[1]);
EXPECT_EQ(78, waiter.Wait(1000));
dp->ProducerRemoveWaiter(&waiter);
void* buffer = NULL;
num_bytes = static_cast<uint32_t>(3u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerBeginWriteData(&buffer, &num_bytes, false));
EXPECT_TRUE(buffer != NULL);
EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
static_cast<int32_t*>(buffer)[0] = 789;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerEndWriteData(
static_cast<uint32_t>(1u * sizeof(elements[0]))));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 90));
const void* read_buffer = NULL;
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerBeginReadData(&read_buffer, &num_bytes, false));
EXPECT_TRUE(read_buffer != NULL);
EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
EXPECT_EQ(456, static_cast<const int32_t*>(read_buffer)[0]);
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerEndReadData(
static_cast<uint32_t>(1u * sizeof(elements[0]))));
EXPECT_EQ(90, waiter.Wait(1000));
dp->ProducerRemoveWaiter(&waiter);
elements[0] = 123;
num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(elements, &num_bytes, false));
EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
waiter.Init();
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 12));
dp->ConsumerClose();
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, waiter.Wait(1000));
dp->ProducerRemoveWaiter(&waiter);
dp->ProducerClose();
}
TEST(LocalDataPipeTest, BasicConsumerWaiting) {
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
static_cast<uint32_t>(sizeof(int32_t)),
1000 * sizeof(int32_t)
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
{
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
Waiter waiter;
waiter.Init();
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 12));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 34));
EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
dp->ConsumerRemoveWaiter(&waiter);
int32_t elements[2] = { 123, 456 };
uint32_t num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerWriteData(elements, &num_bytes, true));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 56));
num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerDiscardData(&num_bytes, true));
EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 78));
elements[0] = -1;
elements[1] = -1;
num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(elements, &num_bytes, true));
EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
EXPECT_EQ(456, elements[0]);
EXPECT_EQ(-1, elements[1]);
waiter.Init();
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 90));
elements[0] = 789;
elements[1] = -1;
num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerWriteData(elements, &num_bytes, true));
EXPECT_EQ(90, waiter.Wait(1000));
dp->ConsumerRemoveWaiter(&waiter);
dp->ProducerClose();
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 12));
elements[0] = -1;
elements[1] = -1;
num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(elements, &num_bytes, true));
EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
EXPECT_EQ(789, elements[0]);
EXPECT_EQ(-1, elements[1]);
waiter.Init();
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 34));
dp->ConsumerClose();
}
{
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
Waiter waiter;
int32_t* elements = NULL;
void* buffer = NULL;
uint32_t num_bytes = static_cast<uint32_t>(3u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerBeginWriteData(&buffer, &num_bytes, true));
EXPECT_TRUE(buffer != NULL);
EXPECT_GE(num_bytes, static_cast<uint32_t>(3u * sizeof(elements[0])));
elements = static_cast<int32_t*>(buffer);
elements[0] = 123;
elements[1] = 456;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerEndWriteData(
static_cast<uint32_t>(2u * sizeof(elements[0]))));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 12));
const void* read_buffer = NULL;
num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerBeginReadData(&read_buffer, &num_bytes, true));
EXPECT_TRUE(read_buffer != NULL);
EXPECT_EQ(static_cast<uint32_t>(2u * sizeof(elements[0])), num_bytes);
const int32_t* read_elements = static_cast<const int32_t*>(read_buffer);
EXPECT_EQ(123, read_elements[0]);
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerEndReadData(
static_cast<uint32_t>(1u * sizeof(elements[0]))));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 34));
read_buffer = NULL;
num_bytes = static_cast<uint32_t>(3u * sizeof(elements[0]));
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerBeginReadData(&read_buffer, &num_bytes, false));
EXPECT_TRUE(read_buffer != NULL);
EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
read_elements = static_cast<const int32_t*>(read_buffer);
EXPECT_EQ(456, read_elements[0]);
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerEndReadData(
static_cast<uint32_t>(1u * sizeof(elements[0]))));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 56));
dp->ProducerClose();
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, waiter.Wait(1000));
dp->ConsumerRemoveWaiter(&waiter);
dp->ConsumerClose();
}
}
TEST(LocalDataPipeTest, BasicTwoPhaseWaiting) {
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
static_cast<uint32_t>(sizeof(int32_t)),
1000 * sizeof(int32_t)
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
Waiter waiter;
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 0));
uint32_t num_bytes = static_cast<uint32_t>(1u * sizeof(int32_t));
void* write_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerBeginWriteData(&write_ptr, &num_bytes, false));
EXPECT_TRUE(write_ptr != NULL);
EXPECT_GE(num_bytes, static_cast<uint32_t>(1u * sizeof(int32_t)));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 1));
EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
dp->ProducerRemoveWaiter(&waiter);
waiter.Init();
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 2));
EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
dp->ConsumerRemoveWaiter(&waiter);
static_cast<int32_t*>(write_ptr)[0] = 123;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerEndWriteData(
static_cast<uint32_t>(1u * sizeof(int32_t))));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 3));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 4));
num_bytes = static_cast<uint32_t>(1u * sizeof(int32_t));
write_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerBeginWriteData(&write_ptr, &num_bytes, false));
EXPECT_TRUE(write_ptr != NULL);
EXPECT_GE(num_bytes, static_cast<uint32_t>(1u * sizeof(int32_t)));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 5));
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(0u));
num_bytes = static_cast<uint32_t>(1u * sizeof(int32_t));
const void* read_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerBeginReadData(&read_ptr, &num_bytes, false));
EXPECT_TRUE(read_ptr != NULL);
EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(int32_t)), num_bytes);
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 6));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 7));
EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
dp->ConsumerRemoveWaiter(&waiter);
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(0u));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 8));
dp->ProducerClose();
dp->ConsumerClose();
}
TEST(LocalDataPipeTest, BasicMayDiscardWaiting) {
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD,
static_cast<uint32_t>(sizeof(int32_t)),
1 * sizeof(int32_t)
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
Waiter waiter;
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 0));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 1));
EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
dp->ConsumerRemoveWaiter(&waiter);
uint32_t num_bytes = static_cast<uint32_t>(sizeof(int32_t));
int32_t element = 123;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerWriteData(&element, &num_bytes, false));
EXPECT_EQ(static_cast<uint32_t>(sizeof(int32_t)), num_bytes);
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 2));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 3));
num_bytes = static_cast<uint32_t>(sizeof(int32_t));
element = 456;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerWriteData(&element, &num_bytes, false));
EXPECT_EQ(static_cast<uint32_t>(sizeof(int32_t)), num_bytes);
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 4));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 5));
num_bytes = static_cast<uint32_t>(sizeof(int32_t));
element = 0;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerReadData(&element, &num_bytes, false));
EXPECT_EQ(static_cast<uint32_t>(sizeof(int32_t)), num_bytes);
EXPECT_EQ(456, element);
waiter.Init();
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 6));
waiter.Init();
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 7));
EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
dp->ConsumerRemoveWaiter(&waiter);
dp->ProducerClose();
dp->ConsumerClose();
}
void Seq(int32_t start, size_t count, int32_t* out) {
for (size_t i = 0; i < count; i++)
out[i] = start + static_cast<int32_t>(i);
}
TEST(LocalDataPipeTest, MayDiscard) {
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD,
static_cast<uint32_t>(sizeof(int32_t)),
10 * sizeof(int32_t)
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
int32_t buffer[100] = { 0 };
uint32_t num_bytes = 0;
num_bytes = 20u * sizeof(int32_t);
Seq(0, arraysize(buffer), buffer);
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, false));
EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
num_bytes = 5u * sizeof(int32_t);
memset(buffer, 0xab, sizeof(buffer));
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(buffer, &num_bytes, false));
EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
int32_t expected_buffer[100];
memset(expected_buffer, 0xab, sizeof(expected_buffer));
Seq(0, 5u, expected_buffer);
EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
num_bytes = 8u * sizeof(int32_t);
Seq(100, arraysize(buffer), buffer);
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, false));
EXPECT_EQ(8u * sizeof(int32_t), num_bytes);
num_bytes = 5u * sizeof(int32_t);
memset(buffer, 0xab, sizeof(buffer));
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(buffer, &num_bytes, false));
EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
memset(expected_buffer, 0xab, sizeof(expected_buffer));
expected_buffer[0] = 8;
expected_buffer[1] = 9;
expected_buffer[2] = 100;
expected_buffer[3] = 101;
expected_buffer[4] = 102;
EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
num_bytes = 1u * sizeof(int32_t);
Seq(200, arraysize(buffer), buffer);
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, false));
EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
num_bytes = 5u * sizeof(int32_t);
Seq(300, arraysize(buffer), buffer);
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, false));
EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
num_bytes = sizeof(buffer);
memset(buffer, 0xab, sizeof(buffer));
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(buffer, &num_bytes, false));
EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
memset(expected_buffer, 0xab, sizeof(expected_buffer));
expected_buffer[0] = 104;
expected_buffer[1] = 105;
expected_buffer[2] = 106;
expected_buffer[3] = 107;
expected_buffer[4] = 200;
expected_buffer[5] = 300;
expected_buffer[6] = 301;
expected_buffer[7] = 302;
expected_buffer[8] = 303;
expected_buffer[9] = 304;
EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
num_bytes = 0u;
void* write_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerBeginWriteData(&write_ptr, &num_bytes, false));
EXPECT_TRUE(write_ptr != NULL);
EXPECT_EQ(6u * sizeof(int32_t), num_bytes);
Seq(400, 6, static_cast<int32_t*>(write_ptr));
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(6u * sizeof(int32_t)));
num_bytes = 6u * sizeof(int32_t);
write_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerBeginWriteData(&write_ptr, &num_bytes, false));
EXPECT_EQ(4u * sizeof(int32_t), num_bytes);
static_cast<int32_t*>(write_ptr)[0] = 500;
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(1u * sizeof(int32_t)));
num_bytes = 10u * sizeof(int32_t);
write_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
dp->ProducerBeginWriteData(&write_ptr, &num_bytes, true));
num_bytes = 5u * sizeof(int32_t);
write_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerBeginWriteData(&write_ptr, &num_bytes, true));
EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
Seq(600, 4, static_cast<int32_t*>(write_ptr));
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(4u * sizeof(int32_t)));
num_bytes = 5u * sizeof(int32_t);
write_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerBeginWriteData(&write_ptr, &num_bytes, true));
EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
Seq(700, 3, static_cast<int32_t*>(write_ptr));
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(3u * sizeof(int32_t)));
num_bytes = sizeof(buffer);
memset(buffer, 0xab, sizeof(buffer));
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(buffer, &num_bytes, false));
EXPECT_EQ(8u * sizeof(int32_t), num_bytes);
memset(expected_buffer, 0xab, sizeof(expected_buffer));
expected_buffer[0] = 500;
expected_buffer[1] = 600;
expected_buffer[2] = 601;
expected_buffer[3] = 602;
expected_buffer[4] = 603;
expected_buffer[5] = 700;
expected_buffer[6] = 701;
expected_buffer[7] = 702;
EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
dp->ProducerClose();
dp->ConsumerClose();
}
TEST(LocalDataPipeTest, AllOrNone) {
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
static_cast<uint32_t>(sizeof(int32_t)),
10 * sizeof(int32_t)
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
uint32_t num_bytes = 20u * sizeof(int32_t);
int32_t buffer[100];
Seq(0, arraysize(buffer), buffer);
EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
dp->ProducerWriteData(buffer, &num_bytes, true));
num_bytes = ~0u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(0u, num_bytes);
num_bytes = 5u * sizeof(int32_t);
Seq(100, arraysize(buffer), buffer);
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, true));
EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
num_bytes = 6u * sizeof(int32_t);
Seq(200, arraysize(buffer), buffer);
EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
dp->ProducerWriteData(buffer, &num_bytes, true));
num_bytes = 11u * sizeof(int32_t);
memset(buffer, 0xab, sizeof(buffer));
EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
dp->ConsumerReadData(buffer, &num_bytes, true));
int32_t expected_buffer[100];
memset(expected_buffer, 0xab, sizeof(expected_buffer));
EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
num_bytes = 11u * sizeof(int32_t);
EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
dp->ConsumerDiscardData(&num_bytes, true));
num_bytes = 2u * sizeof(int32_t);
Seq(300, arraysize(buffer), buffer);
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, true));
EXPECT_EQ(2u * sizeof(int32_t), num_bytes);
num_bytes = 3u * sizeof(int32_t);
Seq(400, arraysize(buffer), buffer);
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, true));
EXPECT_EQ(3u * sizeof(int32_t), num_bytes);
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
num_bytes = 5u * sizeof(int32_t);
memset(buffer, 0xab, sizeof(buffer));
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(buffer, &num_bytes, true));
EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
memset(expected_buffer, 0xab, sizeof(expected_buffer));
Seq(100, 5, expected_buffer);
EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
num_bytes = 6u * sizeof(int32_t);
memset(buffer, 0xab, sizeof(buffer));
EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
dp->ConsumerReadData(buffer, &num_bytes, true));
memset(expected_buffer, 0xab, sizeof(expected_buffer));
EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
num_bytes = 6u * sizeof(int32_t);
EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
dp->ConsumerDiscardData(&num_bytes, true));
num_bytes = 2u * sizeof(int32_t);
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerDiscardData(&num_bytes, true));
EXPECT_EQ(2u * sizeof(int32_t), num_bytes);
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(3u * sizeof(int32_t), num_bytes);
dp->ProducerClose();
num_bytes = 4u * sizeof(int32_t);
memset(buffer, 0xab, sizeof(buffer));
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
dp->ConsumerReadData(buffer, &num_bytes, true));
memset(expected_buffer, 0xab, sizeof(expected_buffer));
EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
num_bytes = 4u * sizeof(int32_t);
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
dp->ConsumerDiscardData(&num_bytes, true));
num_bytes = 2u * sizeof(int32_t);
memset(buffer, 0xab, sizeof(buffer));
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(buffer, &num_bytes, true));
EXPECT_EQ(2u * sizeof(int32_t), num_bytes);
memset(expected_buffer, 0xab, sizeof(expected_buffer));
Seq(400, 2, expected_buffer);
EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
num_bytes = 1u * sizeof(int32_t);
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerDiscardData(&num_bytes, true));
EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
num_bytes = ~0u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(0u, num_bytes);
dp->ConsumerClose();
}
TEST(LocalDataPipeTest, AllOrNoneMayDiscard) {
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD,
static_cast<uint32_t>(sizeof(int32_t)),
10 * sizeof(int32_t)
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
uint32_t num_bytes = 20u * sizeof(int32_t);
int32_t buffer[100];
Seq(0, arraysize(buffer), buffer);
EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
dp->ProducerWriteData(buffer, &num_bytes, true));
num_bytes = 5u * sizeof(int32_t);
Seq(100, arraysize(buffer), buffer);
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, true));
EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
num_bytes = 9u * sizeof(int32_t);
Seq(200, arraysize(buffer), buffer);
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, true));
EXPECT_EQ(9u * sizeof(int32_t), num_bytes);
num_bytes = 1u * sizeof(int32_t);
memset(buffer, 0xab, sizeof(buffer));
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(buffer, &num_bytes, true));
EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
int32_t expected_buffer[100];
memset(expected_buffer, 0xab, sizeof(expected_buffer));
expected_buffer[0] = 104;
EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
num_bytes = 10u * sizeof(int32_t);
memset(buffer, 0xab, sizeof(buffer));
EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
dp->ConsumerReadData(buffer, &num_bytes, true));
memset(expected_buffer, 0xab, sizeof(expected_buffer));
EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
num_bytes = 10u * sizeof(int32_t);
EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
dp->ConsumerDiscardData(&num_bytes, true));
num_bytes = 4u * sizeof(int32_t);
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerDiscardData(&num_bytes, true));
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
num_bytes = 10u * sizeof(int32_t);
Seq(300, arraysize(buffer), buffer);
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, true));
EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
num_bytes = 10u * sizeof(int32_t);
memset(buffer, 0xab, sizeof(buffer));
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(buffer, &num_bytes, true));
memset(expected_buffer, 0xab, sizeof(expected_buffer));
EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
Seq(300, 10, expected_buffer);
EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
dp->ProducerClose();
dp->ConsumerClose();
}
TEST(LocalDataPipeTest, TwoPhaseAllOrNone) {
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
static_cast<uint32_t>(sizeof(int32_t)),
10 * sizeof(int32_t)
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
uint32_t num_bytes = 20u * sizeof(int32_t);
void* write_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
dp->ProducerBeginWriteData(&write_ptr, &num_bytes, true));
COMPILE_ASSERT(sizeof(int32_t) > 1u, wow_int32_ts_have_size_1);
num_bytes = 1u;
write_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
dp->ProducerBeginWriteData(&write_ptr, &num_bytes, true));
num_bytes = 20u * sizeof(int32_t);
const void* read_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
dp->ConsumerBeginReadData(&read_ptr, &num_bytes, true));
num_bytes = 5u * sizeof(int32_t);
write_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerBeginWriteData(&write_ptr, &num_bytes, true));
EXPECT_GE(num_bytes, 5u * sizeof(int32_t));
EXPECT_TRUE(write_ptr != NULL);
Seq(0, 5, static_cast<int32_t*>(write_ptr));
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(5u * sizeof(int32_t)));
num_bytes = 1u;
read_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
dp->ConsumerBeginReadData(&read_ptr, &num_bytes, true));
num_bytes = 1u * sizeof(int32_t);
read_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerBeginReadData(&read_ptr, &num_bytes, true));
EXPECT_GE(num_bytes, 1u * sizeof(int32_t));
EXPECT_EQ(0, static_cast<const int32_t*>(read_ptr)[0]);
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(1u * sizeof(int32_t)));
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(4u * sizeof(int32_t), num_bytes);
num_bytes = 6u * sizeof(int32_t);
write_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
dp->ProducerBeginWriteData(&write_ptr, &num_bytes, true));
num_bytes = 6u * sizeof(int32_t);
int32_t buffer[100];
Seq(100, 6, buffer);
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, true));
EXPECT_EQ(6u * sizeof(int32_t), num_bytes);
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
num_bytes = 10u * sizeof(int32_t);
read_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
dp->ConsumerBeginReadData(&read_ptr, &num_bytes, true));
dp->ProducerClose();
num_bytes = 9u * sizeof(int32_t);
read_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerBeginReadData(&read_ptr, &num_bytes, true));
EXPECT_GE(num_bytes, 9u * sizeof(int32_t));
EXPECT_EQ(1, static_cast<const int32_t*>(read_ptr)[0]);
EXPECT_EQ(2, static_cast<const int32_t*>(read_ptr)[1]);
EXPECT_EQ(3, static_cast<const int32_t*>(read_ptr)[2]);
EXPECT_EQ(4, static_cast<const int32_t*>(read_ptr)[3]);
EXPECT_EQ(100, static_cast<const int32_t*>(read_ptr)[4]);
EXPECT_EQ(101, static_cast<const int32_t*>(read_ptr)[5]);
EXPECT_EQ(102, static_cast<const int32_t*>(read_ptr)[6]);
EXPECT_EQ(103, static_cast<const int32_t*>(read_ptr)[7]);
EXPECT_EQ(104, static_cast<const int32_t*>(read_ptr)[8]);
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(9u * sizeof(int32_t)));
num_bytes = 2u * sizeof(int32_t);
read_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
dp->ConsumerBeginReadData(&read_ptr, &num_bytes, true));
dp->ConsumerClose();
}
TEST(LocalDataPipeTest, WrapAround) {
unsigned char test_data[1000];
for (size_t i = 0; i < arraysize(test_data); i++)
test_data[i] = static_cast<unsigned char>(i);
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
1u,
100u
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
ASSERT_EQ(100u, validated_options.capacity_num_bytes);
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
uint32_t num_bytes = 20u;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerWriteData(&test_data[0], &num_bytes, false));
EXPECT_EQ(20u, num_bytes);
unsigned char read_buffer[1000] = { 0 };
num_bytes = 10u;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerReadData(read_buffer, &num_bytes, false));
EXPECT_EQ(10u, num_bytes);
EXPECT_EQ(0, memcmp(read_buffer, &test_data[0], 10u));
void* write_buffer_ptr = NULL;
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerBeginWriteData(&write_buffer_ptr, &num_bytes, false));
EXPECT_TRUE(write_buffer_ptr != NULL);
EXPECT_EQ(80u, num_bytes);
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(0u));
num_bytes = 200u;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerWriteData(&test_data[20], &num_bytes, false));
EXPECT_EQ(90u, num_bytes);
const void* read_buffer_ptr = NULL;
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerBeginReadData(&read_buffer_ptr, &num_bytes, false));
EXPECT_TRUE(read_buffer_ptr != NULL);
EXPECT_EQ(90u, num_bytes);
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(0u));
num_bytes =
static_cast<uint32_t>(arraysize(read_buffer) * sizeof(read_buffer[0]));
memset(read_buffer, 0, num_bytes);
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerReadData(read_buffer, &num_bytes, false));
EXPECT_EQ(100u, num_bytes);
EXPECT_EQ(0, memcmp(read_buffer, &test_data[10], 100u));
dp->ProducerClose();
dp->ConsumerClose();
}
TEST(LocalDataPipeTest, CloseWriteRead) {
const char kTestData[] = "hello world";
const uint32_t kTestDataSize = static_cast<uint32_t>(sizeof(kTestData));
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
1u,
1000u
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
{
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
uint32_t num_bytes = kTestDataSize;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerWriteData(kTestData, &num_bytes, false));
EXPECT_EQ(kTestDataSize, num_bytes);
num_bytes = kTestDataSize;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerWriteData(kTestData, &num_bytes, false));
EXPECT_EQ(kTestDataSize, num_bytes);
void* write_buffer_ptr = NULL;
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerBeginWriteData(&write_buffer_ptr, &num_bytes, false));
EXPECT_TRUE(write_buffer_ptr != NULL);
EXPECT_GT(num_bytes, 0u);
const void* read_buffer_ptr = NULL;
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerBeginReadData(&read_buffer_ptr, &num_bytes, false));
EXPECT_TRUE(read_buffer_ptr != NULL);
EXPECT_EQ(2u * kTestDataSize, num_bytes);
dp->ProducerClose();
EXPECT_EQ(0, memcmp(read_buffer_ptr, kTestData, kTestDataSize));
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(kTestDataSize));
read_buffer_ptr = NULL;
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerBeginReadData(&read_buffer_ptr, &num_bytes, false));
EXPECT_TRUE(read_buffer_ptr != NULL);
EXPECT_EQ(kTestDataSize, num_bytes);
dp->ConsumerClose();
}
{
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
uint32_t num_bytes = kTestDataSize;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerWriteData(kTestData, &num_bytes, false));
EXPECT_EQ(kTestDataSize, num_bytes);
void* write_buffer_ptr = NULL;
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerBeginWriteData(&write_buffer_ptr, &num_bytes, false));
EXPECT_TRUE(write_buffer_ptr != NULL);
ASSERT_GT(num_bytes, kTestDataSize);
const void* read_buffer_ptr = NULL;
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerBeginReadData(&read_buffer_ptr, &num_bytes, false));
EXPECT_TRUE(read_buffer_ptr != NULL);
EXPECT_EQ(kTestDataSize, num_bytes);
dp->ConsumerClose();
memcpy(write_buffer_ptr, kTestData, kTestDataSize);
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(kTestDataSize));
num_bytes = kTestDataSize;
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
dp->ProducerWriteData(kTestData, &num_bytes, false));
write_buffer_ptr = NULL;
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
dp->ProducerBeginWriteData(&write_buffer_ptr, &num_bytes, false));
dp->ProducerClose();
}
{
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
void* write_buffer_ptr = NULL;
uint32_t num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerBeginWriteData(&write_buffer_ptr, &num_bytes, false));
EXPECT_TRUE(write_buffer_ptr != NULL);
ASSERT_GT(num_bytes, kTestDataSize);
dp->ConsumerClose();
dp->ProducerClose();
}
{
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
uint32_t num_bytes = kTestDataSize;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerWriteData(kTestData, &num_bytes, false));
EXPECT_EQ(kTestDataSize, num_bytes);
dp->ProducerClose();
char buffer[1000];
num_bytes = static_cast<uint32_t>(sizeof(buffer));
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerReadData(buffer, &num_bytes, false));
EXPECT_EQ(kTestDataSize, num_bytes);
EXPECT_EQ(0, memcmp(buffer, kTestData, kTestDataSize));
num_bytes = static_cast<uint32_t>(sizeof(buffer));
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
dp->ConsumerReadData(buffer, &num_bytes, false));
const void* read_buffer_ptr = NULL;
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
dp->ConsumerBeginReadData(&read_buffer_ptr, &num_bytes, false));
num_bytes = 10u;
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
dp->ConsumerDiscardData(&num_bytes, false));
dp->ConsumerClose();
}
}
TEST(LocalDataPipeTest, TwoPhaseMoreInvalidArguments) {
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
static_cast<uint32_t>(sizeof(int32_t)),
10 * sizeof(int32_t)
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
uint32_t num_bytes = 1000u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(0u, num_bytes);
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
dp->ProducerEndWriteData(1u * sizeof(int32_t)));
num_bytes = 1000u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(0u, num_bytes);
num_bytes = 0u;
void* write_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerBeginWriteData(&write_ptr, &num_bytes, false));
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
dp->ProducerEndWriteData(
num_bytes + static_cast<uint32_t>(sizeof(int32_t))));
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, dp->ProducerEndWriteData(0u));
num_bytes = 1000u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(0u, num_bytes);
num_bytes = 0u;
write_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ProducerBeginWriteData(&write_ptr, &num_bytes, false));
EXPECT_GE(num_bytes, 1u);
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dp->ProducerEndWriteData(1u));
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, dp->ProducerEndWriteData(0u));
num_bytes = 1000u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(0u, num_bytes);
int32_t element = 123;
num_bytes = 1u * sizeof(int32_t);
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(&element, &num_bytes, false));
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
dp->ConsumerEndReadData(1u * sizeof(int32_t)));
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
num_bytes = 0u;
const void* read_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerBeginReadData(&read_ptr, &num_bytes, false));
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
dp->ConsumerEndReadData(
num_bytes + static_cast<uint32_t>(sizeof(int32_t))));
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
num_bytes = 0u;
read_ptr = NULL;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerBeginReadData(&read_ptr, &num_bytes, false));
EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
EXPECT_EQ(123, static_cast<const int32_t*>(read_ptr)[0]);
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dp->ConsumerEndReadData(1u));
num_bytes = 0u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
dp->ProducerClose();
dp->ConsumerClose();
}
TEST(LocalDataPipeTest, DISABLED_MayDiscardTwoPhaseConsistent) {
const MojoCreateDataPipeOptions options = {
kSizeOfOptions,
MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD,
1,
2
};
MojoCreateDataPipeOptions validated_options = { 0 };
EXPECT_EQ(MOJO_RESULT_OK,
DataPipe::ValidateOptions(&options, &validated_options));
scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
char elements[2] = { 'a', 'b' };
uint32_t num_bytes = 2u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(elements, &num_bytes, false));
EXPECT_EQ(2u, num_bytes);
const void* read_ptr = NULL;
num_bytes = 2u;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerBeginReadData(&read_ptr, &num_bytes, false));
EXPECT_EQ(2u, num_bytes);
EXPECT_EQ('a', static_cast<const char*>(read_ptr)[0]);
EXPECT_EQ('b', static_cast<const char*>(read_ptr)[1]);
elements[0] = 'x';
elements[1] = 'y';
num_bytes = 2u;
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(elements, &num_bytes, false));
EXPECT_EQ('a', static_cast<const char*>(read_ptr)[0]);
EXPECT_EQ('b', static_cast<const char*>(read_ptr)[1]);
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(2u));
EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(elements, &num_bytes, false));
read_ptr = NULL;
num_bytes = 2u;
EXPECT_EQ(MOJO_RESULT_OK,
dp->ConsumerBeginReadData(&read_ptr, &num_bytes, false));
EXPECT_EQ(2u, num_bytes);
EXPECT_EQ('x', static_cast<const char*>(read_ptr)[0]);
EXPECT_EQ('y', static_cast<const char*>(read_ptr)[1]);
EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(2u));
dp->ProducerClose();
dp->ConsumerClose();
}
}
}
}