This source file includes following definitions.
- SetUp
- TearDown
- BlockingReceive
- Send
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- adapter_
- Run
- TEST_F
#include "components/nacl/loader/nacl_ipc_adapter.h"
#include <string.h>
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/threading/platform_thread.h"
#include "base/threading/simple_thread.h"
#include "ipc/ipc_test_sink.h"
#include "native_client/src/trusted/desc/nacl_desc_custom.h"
#include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
#include "ppapi/c/ppb_file_io.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
class NaClIPCAdapterTest : public testing::Test {
public:
NaClIPCAdapterTest() {}
virtual void SetUp() OVERRIDE {
sink_ = new IPC::TestSink;
adapter_ = new NaClIPCAdapter(scoped_ptr<IPC::Channel>(sink_),
base::MessageLoopProxy::current().get());
}
virtual void TearDown() OVERRIDE {
sink_ = NULL;
adapter_ = NULL;
message_loop_.RunUntilIdle();
}
protected:
int BlockingReceive(void* buf, size_t buf_size) {
NaClImcMsgIoVec iov = {buf, buf_size};
NaClImcTypedMsgHdr msg = {&iov, 1};
return adapter_->BlockingReceive(&msg);
}
int Send(void* buf, size_t buf_size) {
NaClImcMsgIoVec iov = {buf, buf_size};
NaClImcTypedMsgHdr msg = {&iov, 1};
return adapter_->Send(&msg);
}
base::MessageLoop message_loop_;
scoped_refptr<NaClIPCAdapter> adapter_;
IPC::TestSink* sink_;
};
}
TEST_F(NaClIPCAdapterTest, SimpleReceiveRewriting) {
int routing_id = 0x89898989;
uint32 type = 0x55555555;
IPC::Message input(routing_id, type, IPC::Message::PRIORITY_NORMAL);
uint32 flags = input.flags();
int value = 0x12345678;
input.WriteInt(value);
adapter_->OnMessageReceived(input);
const int kBufSize = 64;
char buf[kBufSize];
int bytes_read = BlockingReceive(buf, kBufSize);
EXPECT_EQ(sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int),
static_cast<size_t>(bytes_read));
const NaClIPCAdapter::NaClMessageHeader* output_header =
reinterpret_cast<const NaClIPCAdapter::NaClMessageHeader*>(buf);
EXPECT_EQ(sizeof(int), output_header->payload_size);
EXPECT_EQ(routing_id, output_header->routing);
EXPECT_EQ(type, output_header->type);
EXPECT_EQ(flags, output_header->flags);
EXPECT_EQ(0u, output_header->num_fds);
EXPECT_EQ(0u, output_header->pad);
EXPECT_EQ(value,
*reinterpret_cast<const int*>(&buf[
sizeof(NaClIPCAdapter::NaClMessageHeader)]));
}
TEST_F(NaClIPCAdapterTest, SendRewriting) {
int routing_id = 0x89898989;
uint32 type = 0x55555555;
int value = 0x12345678;
const int buf_size = sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int);
char buf[buf_size] = {0};
NaClIPCAdapter::NaClMessageHeader* header =
reinterpret_cast<NaClIPCAdapter::NaClMessageHeader*>(buf);
header->payload_size = sizeof(int);
header->routing = routing_id;
header->type = type;
header->flags = 0;
header->num_fds = 0;
*reinterpret_cast<int*>(
&buf[sizeof(NaClIPCAdapter::NaClMessageHeader)]) = value;
int result = Send(buf, buf_size);
EXPECT_EQ(buf_size, result);
message_loop_.RunUntilIdle();
ASSERT_EQ(1u, sink_->message_count());
const IPC::Message* msg = sink_->GetMessageAt(0);
EXPECT_EQ(sizeof(int), msg->payload_size());
EXPECT_EQ(header->routing, msg->routing_id());
EXPECT_EQ(header->type, msg->type());
sink_->ClearMessages();
int first_chunk_size = 7;
result = Send(buf, first_chunk_size);
EXPECT_EQ(first_chunk_size, result);
message_loop_.RunUntilIdle();
ASSERT_EQ(0u, sink_->message_count());
int second_chunk_size = 2;
result = Send(&buf[first_chunk_size], second_chunk_size);
EXPECT_EQ(second_chunk_size, result);
message_loop_.RunUntilIdle();
ASSERT_EQ(0u, sink_->message_count());
int third_chunk_size = buf_size - first_chunk_size - second_chunk_size;
result = Send(&buf[first_chunk_size + second_chunk_size],
third_chunk_size);
EXPECT_EQ(third_chunk_size, result);
message_loop_.RunUntilIdle();
ASSERT_EQ(1u, sink_->message_count());
msg = sink_->GetMessageAt(0);
EXPECT_EQ(sizeof(int), msg->payload_size());
EXPECT_EQ(header->routing, msg->routing_id());
EXPECT_EQ(header->type, msg->type());
}
TEST_F(NaClIPCAdapterTest, PartialReceive) {
int routing_id_1 = 0x89898989;
uint32 type_1 = 0x55555555;
IPC::Message input_1(routing_id_1, type_1, IPC::Message::PRIORITY_NORMAL);
int value_1 = 0x12121212;
input_1.WriteInt(value_1);
adapter_->OnMessageReceived(input_1);
int routing_id_2 = 0x90909090;
uint32 type_2 = 0x66666666;
IPC::Message input_2(routing_id_2, type_2, IPC::Message::PRIORITY_NORMAL);
int value_2 = 0x23232323;
input_2.WriteInt(value_2);
adapter_->OnMessageReceived(input_2);
const int kBufSize = 64;
char buf[kBufSize];
int bytes_requested = 7;
int bytes_read = BlockingReceive(buf, bytes_requested);
ASSERT_EQ(bytes_requested, bytes_read);
bytes_read += BlockingReceive(&buf[bytes_requested],
kBufSize - bytes_requested);
EXPECT_EQ(sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int),
static_cast<size_t>(bytes_read));
const NaClIPCAdapter::NaClMessageHeader* output_header =
reinterpret_cast<const NaClIPCAdapter::NaClMessageHeader*>(buf);
EXPECT_EQ(sizeof(int), output_header->payload_size);
EXPECT_EQ(routing_id_1, output_header->routing);
EXPECT_EQ(type_1, output_header->type);
bytes_read = BlockingReceive(buf, kBufSize);
EXPECT_EQ(sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int),
static_cast<size_t>(bytes_read));
output_header =
reinterpret_cast<const NaClIPCAdapter::NaClMessageHeader*>(buf);
EXPECT_EQ(sizeof(int), output_header->payload_size);
EXPECT_EQ(routing_id_2, output_header->routing);
EXPECT_EQ(type_2, output_header->type);
}
TEST_F(NaClIPCAdapterTest, SendOverflow) {
int routing_id = 0x89898989;
uint32 type = 0x55555555;
int value = 0x12345678;
const int buf_size = sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int);
const int big_buf_size = buf_size + 4;
char buf[big_buf_size] = {0};
NaClIPCAdapter::NaClMessageHeader* header =
reinterpret_cast<NaClIPCAdapter::NaClMessageHeader*>(buf);
header->payload_size = sizeof(int);
header->routing = routing_id;
header->type = type;
header->flags = 0;
header->num_fds = 0;
*reinterpret_cast<int*>(
&buf[sizeof(NaClIPCAdapter::NaClMessageHeader)]) = value;
int result = Send(buf, big_buf_size);
EXPECT_EQ(-1, result);
message_loop_.RunUntilIdle();
ASSERT_EQ(0u, sink_->message_count());
int first_chunk_size = 7;
result = Send(buf, first_chunk_size);
EXPECT_EQ(first_chunk_size, result);
message_loop_.RunUntilIdle();
ASSERT_EQ(0u, sink_->message_count());
int second_chunk_size = big_buf_size - first_chunk_size;
result = Send(&buf[first_chunk_size], second_chunk_size);
EXPECT_EQ(-1, result);
message_loop_.RunUntilIdle();
ASSERT_EQ(0u, sink_->message_count());
}
TEST_F(NaClIPCAdapterTest, ReadWithChannelError) {
class MyThread : public base::SimpleThread {
public:
explicit MyThread(NaClIPCAdapter* adapter)
: SimpleThread("NaClIPCAdapterThread"),
adapter_(adapter) {}
virtual void Run() OVERRIDE {
base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
adapter_->OnChannelError();
}
private:
scoped_refptr<NaClIPCAdapter> adapter_;
};
MyThread thread(adapter_.get());
thread.Start();
const int kBufSize = 64;
char buf[kBufSize];
int result = BlockingReceive(buf, kBufSize);
EXPECT_EQ(-1, result);
result = BlockingReceive(buf, kBufSize);
EXPECT_EQ(-1, result);
thread.Join();
}
TEST_F(NaClIPCAdapterTest, TranslatePepperFileReadWriteOpenFlags) {
EXPECT_EQ(NACL_ABI_O_RDONLY,
TranslatePepperFileReadWriteOpenFlagsForTesting(PP_FILEOPENFLAG_READ));
EXPECT_EQ(NACL_ABI_O_WRONLY,
TranslatePepperFileReadWriteOpenFlagsForTesting(PP_FILEOPENFLAG_WRITE));
EXPECT_EQ(NACL_ABI_O_WRONLY | NACL_ABI_O_APPEND,
TranslatePepperFileReadWriteOpenFlagsForTesting(
PP_FILEOPENFLAG_APPEND));
EXPECT_EQ(NACL_ABI_O_RDWR,
TranslatePepperFileReadWriteOpenFlagsForTesting(
PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_WRITE));
EXPECT_EQ(NACL_ABI_O_WRONLY | NACL_ABI_O_APPEND,
TranslatePepperFileReadWriteOpenFlagsForTesting(
PP_FILEOPENFLAG_APPEND));
EXPECT_EQ(NACL_ABI_O_RDWR | NACL_ABI_O_APPEND,
TranslatePepperFileReadWriteOpenFlagsForTesting(
PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_APPEND));
EXPECT_EQ(NACL_ABI_O_WRONLY,
TranslatePepperFileReadWriteOpenFlagsForTesting(
PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE));
EXPECT_EQ(NACL_ABI_O_WRONLY,
TranslatePepperFileReadWriteOpenFlagsForTesting(
PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_TRUNCATE));
EXPECT_EQ(NACL_ABI_O_WRONLY,
TranslatePepperFileReadWriteOpenFlagsForTesting(
PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_EXCLUSIVE));
EXPECT_EQ(NACL_ABI_O_RDONLY,
TranslatePepperFileReadWriteOpenFlagsForTesting(0));
EXPECT_EQ(NACL_ABI_O_RDONLY,
TranslatePepperFileReadWriteOpenFlagsForTesting(
PP_FILEOPENFLAG_CREATE));
EXPECT_EQ(NACL_ABI_O_RDONLY,
TranslatePepperFileReadWriteOpenFlagsForTesting(
PP_FILEOPENFLAG_TRUNCATE));
EXPECT_EQ(NACL_ABI_O_RDONLY,
TranslatePepperFileReadWriteOpenFlagsForTesting(
PP_FILEOPENFLAG_EXCLUSIVE));
}