Roll src/third_party/WebKit f36d5e0:68b67cd (svn 193299:193303)
[chromium-blink-merge.git] / components / nacl / loader / nacl_ipc_adapter_unittest.cc
blob826b41d535d526c05a1e1a0a13eaccae88922ff4
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/nacl/loader/nacl_ipc_adapter.h"
7 #include <string.h>
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "base/threading/platform_thread.h"
13 #include "base/threading/simple_thread.h"
14 #include "ipc/ipc_test_sink.h"
15 #include "native_client/src/trusted/desc/nacl_desc_custom.h"
16 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
17 #include "ppapi/c/ppb_file_io.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 namespace {
22 class NaClIPCAdapterTest : public testing::Test {
23 public:
24 NaClIPCAdapterTest() {}
26 // testing::Test implementation.
27 void SetUp() override {
28 sink_ = new IPC::TestSink;
30 // Takes ownership of the sink_ pointer. Note we provide the current message
31 // loop instead of using a real IO thread. This should work OK since we do
32 // not need real IPC for the tests.
33 adapter_ = new NaClIPCAdapter(scoped_ptr<IPC::Channel>(sink_),
34 base::MessageLoopProxy::current().get());
36 void TearDown() override {
37 sink_ = NULL; // This pointer is actually owned by the IPCAdapter.
38 adapter_ = NULL;
39 // The adapter destructor has to post a task to destroy the Channel on the
40 // IO thread. For the purposes of the test, we just need to make sure that
41 // task gets run, or it will appear as a leak.
42 message_loop_.RunUntilIdle();
45 protected:
46 int BlockingReceive(void* buf, size_t buf_size) {
47 NaClImcMsgIoVec iov = {buf, buf_size};
48 NaClImcTypedMsgHdr msg = {&iov, 1};
49 return adapter_->BlockingReceive(&msg);
52 int Send(void* buf, size_t buf_size) {
53 NaClImcMsgIoVec iov = {buf, buf_size};
54 NaClImcTypedMsgHdr msg = {&iov, 1};
55 return adapter_->Send(&msg);
58 base::MessageLoop message_loop_;
60 scoped_refptr<NaClIPCAdapter> adapter_;
62 // Messages sent from nacl to the adapter end up here. Note that we create
63 // this pointer and pass ownership of it to the IPC adapter, who will keep
64 // it alive as long as the adapter is alive. This means that when the
65 // adapter goes away, this pointer will become invalid.
67 // In real life the adapter needs to take ownership so the channel can be
68 // destroyed on the right thread.
69 IPC::TestSink* sink_;
72 } // namespace
74 // Tests a simple message getting rewritten sent from native code to NaCl.
75 TEST_F(NaClIPCAdapterTest, SimpleReceiveRewriting) {
76 int routing_id = 0x89898989;
77 uint32 type = 0x55555555;
78 IPC::Message input(routing_id, type, IPC::Message::PRIORITY_NORMAL);
79 uint32 flags = input.flags();
81 int value = 0x12345678;
82 input.WriteInt(value);
83 adapter_->OnMessageReceived(input);
85 // Buffer just need to be big enough for our message with one int.
86 const int kBufSize = 64;
87 char buf[kBufSize];
89 int bytes_read = BlockingReceive(buf, kBufSize);
90 EXPECT_EQ(sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int),
91 static_cast<size_t>(bytes_read));
93 const NaClIPCAdapter::NaClMessageHeader* output_header =
94 reinterpret_cast<const NaClIPCAdapter::NaClMessageHeader*>(buf);
95 EXPECT_EQ(sizeof(int), output_header->payload_size);
96 EXPECT_EQ(routing_id, output_header->routing);
97 EXPECT_EQ(type, output_header->type);
98 EXPECT_EQ(flags, output_header->flags);
99 EXPECT_EQ(0u, output_header->num_fds);
100 EXPECT_EQ(0u, output_header->pad);
102 // Validate the payload.
103 EXPECT_EQ(value,
104 *reinterpret_cast<const int*>(&buf[
105 sizeof(NaClIPCAdapter::NaClMessageHeader)]));
108 // Tests a simple message getting rewritten sent from NaCl to native code.
109 TEST_F(NaClIPCAdapterTest, SendRewriting) {
110 int routing_id = 0x89898989;
111 uint32 type = 0x55555555;
112 int value = 0x12345678;
114 // Send a message with one int inside it.
115 const int buf_size = sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int);
116 char buf[buf_size] = {0};
118 NaClIPCAdapter::NaClMessageHeader* header =
119 reinterpret_cast<NaClIPCAdapter::NaClMessageHeader*>(buf);
120 header->payload_size = sizeof(int);
121 header->routing = routing_id;
122 header->type = type;
123 header->flags = 0;
124 header->num_fds = 0;
125 *reinterpret_cast<int*>(
126 &buf[sizeof(NaClIPCAdapter::NaClMessageHeader)]) = value;
128 int result = Send(buf, buf_size);
129 EXPECT_EQ(buf_size, result);
131 // Check that the message came out the other end in the test sink
132 // (messages are posted, so we have to pump).
133 message_loop_.RunUntilIdle();
134 ASSERT_EQ(1u, sink_->message_count());
135 const IPC::Message* msg = sink_->GetMessageAt(0);
137 EXPECT_EQ(sizeof(int), msg->payload_size());
138 EXPECT_EQ(header->routing, msg->routing_id());
139 EXPECT_EQ(header->type, msg->type());
141 // Now test the partial send case. We should be able to break the message
142 // into two parts and it should still work.
143 sink_->ClearMessages();
144 int first_chunk_size = 7;
145 result = Send(buf, first_chunk_size);
146 EXPECT_EQ(first_chunk_size, result);
148 // First partial send should not have made any messages.
149 message_loop_.RunUntilIdle();
150 ASSERT_EQ(0u, sink_->message_count());
152 // Second partial send should do the same.
153 int second_chunk_size = 2;
154 result = Send(&buf[first_chunk_size], second_chunk_size);
155 EXPECT_EQ(second_chunk_size, result);
156 message_loop_.RunUntilIdle();
157 ASSERT_EQ(0u, sink_->message_count());
159 // Send the rest of the message in a third chunk.
160 int third_chunk_size = buf_size - first_chunk_size - second_chunk_size;
161 result = Send(&buf[first_chunk_size + second_chunk_size],
162 third_chunk_size);
163 EXPECT_EQ(third_chunk_size, result);
165 // Last send should have generated one message.
166 message_loop_.RunUntilIdle();
167 ASSERT_EQ(1u, sink_->message_count());
168 msg = sink_->GetMessageAt(0);
169 EXPECT_EQ(sizeof(int), msg->payload_size());
170 EXPECT_EQ(header->routing, msg->routing_id());
171 EXPECT_EQ(header->type, msg->type());
174 // Tests when a buffer is too small to receive the entire message.
175 TEST_F(NaClIPCAdapterTest, PartialReceive) {
176 int routing_id_1 = 0x89898989;
177 uint32 type_1 = 0x55555555;
178 IPC::Message input_1(routing_id_1, type_1, IPC::Message::PRIORITY_NORMAL);
179 int value_1 = 0x12121212;
180 input_1.WriteInt(value_1);
181 adapter_->OnMessageReceived(input_1);
183 int routing_id_2 = 0x90909090;
184 uint32 type_2 = 0x66666666;
185 IPC::Message input_2(routing_id_2, type_2, IPC::Message::PRIORITY_NORMAL);
186 int value_2 = 0x23232323;
187 input_2.WriteInt(value_2);
188 adapter_->OnMessageReceived(input_2);
190 const int kBufSize = 64;
191 char buf[kBufSize];
193 // Read part of the first message.
194 int bytes_requested = 7;
195 int bytes_read = BlockingReceive(buf, bytes_requested);
196 ASSERT_EQ(bytes_requested, bytes_read);
198 // Read the rest, this should give us the rest of the first message only.
199 bytes_read += BlockingReceive(&buf[bytes_requested],
200 kBufSize - bytes_requested);
201 EXPECT_EQ(sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int),
202 static_cast<size_t>(bytes_read));
204 // Make sure we got the right message.
205 const NaClIPCAdapter::NaClMessageHeader* output_header =
206 reinterpret_cast<const NaClIPCAdapter::NaClMessageHeader*>(buf);
207 EXPECT_EQ(sizeof(int), output_header->payload_size);
208 EXPECT_EQ(routing_id_1, output_header->routing);
209 EXPECT_EQ(type_1, output_header->type);
211 // Read the second message to make sure we went on to it.
212 bytes_read = BlockingReceive(buf, kBufSize);
213 EXPECT_EQ(sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int),
214 static_cast<size_t>(bytes_read));
215 output_header =
216 reinterpret_cast<const NaClIPCAdapter::NaClMessageHeader*>(buf);
217 EXPECT_EQ(sizeof(int), output_header->payload_size);
218 EXPECT_EQ(routing_id_2, output_header->routing);
219 EXPECT_EQ(type_2, output_header->type);
222 // Tests sending messages that are too large. We test sends that are too
223 // small implicitly here and in the success case because in that case it
224 // succeeds and buffers the data.
225 TEST_F(NaClIPCAdapterTest, SendOverflow) {
226 int routing_id = 0x89898989;
227 uint32 type = 0x55555555;
228 int value = 0x12345678;
230 // Make a message with one int inside it. Reserve some extra space so
231 // we can test what happens when we send too much data.
232 const int buf_size = sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int);
233 const int big_buf_size = buf_size + 4;
234 char buf[big_buf_size] = {0};
236 NaClIPCAdapter::NaClMessageHeader* header =
237 reinterpret_cast<NaClIPCAdapter::NaClMessageHeader*>(buf);
238 header->payload_size = sizeof(int);
239 header->routing = routing_id;
240 header->type = type;
241 header->flags = 0;
242 header->num_fds = 0;
243 *reinterpret_cast<int*>(
244 &buf[sizeof(NaClIPCAdapter::NaClMessageHeader)]) = value;
246 // Send too much data and make sure that the send fails.
247 int result = Send(buf, big_buf_size);
248 EXPECT_EQ(-1, result);
249 message_loop_.RunUntilIdle();
250 ASSERT_EQ(0u, sink_->message_count());
252 // Send too much data in two chunks and make sure that the send fails.
253 int first_chunk_size = 7;
254 result = Send(buf, first_chunk_size);
255 EXPECT_EQ(first_chunk_size, result);
257 // First partial send should not have made any messages.
258 message_loop_.RunUntilIdle();
259 ASSERT_EQ(0u, sink_->message_count());
261 int second_chunk_size = big_buf_size - first_chunk_size;
262 result = Send(&buf[first_chunk_size], second_chunk_size);
263 EXPECT_EQ(-1, result);
264 message_loop_.RunUntilIdle();
265 ASSERT_EQ(0u, sink_->message_count());
268 // Tests that when the IPC channel reports an error, that waiting reads are
269 // unblocked and return a -1 error code.
270 TEST_F(NaClIPCAdapterTest, ReadWithChannelError) {
271 // Have a background thread that waits a bit and calls the channel error
272 // handler. This should wake up any waiting threads and immediately return
273 // -1. There is an inherent race condition in that we can't be sure if the
274 // other thread is actually waiting when this happens. This is OK, since the
275 // behavior (which we also explicitly test later) is to return -1 if the
276 // channel has already had an error when you start waiting.
277 class MyThread : public base::SimpleThread {
278 public:
279 explicit MyThread(NaClIPCAdapter* adapter)
280 : SimpleThread("NaClIPCAdapterThread"),
281 adapter_(adapter) {}
282 void Run() override {
283 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
284 adapter_->OnChannelError();
286 private:
287 scoped_refptr<NaClIPCAdapter> adapter_;
289 MyThread thread(adapter_.get());
291 // IMPORTANT: do not return early from here down (including ASSERT_*) because
292 // the thread needs to joined or it will assert.
293 thread.Start();
295 // Request data. This will normally (modulo races) block until data is
296 // received or there is an error, and the thread above will wake us up
297 // after 1s.
298 const int kBufSize = 64;
299 char buf[kBufSize];
300 int result = BlockingReceive(buf, kBufSize);
301 EXPECT_EQ(-1, result);
303 // Test the "previously had an error" case. BlockingReceive should return
304 // immediately if there was an error.
305 result = BlockingReceive(buf, kBufSize);
306 EXPECT_EQ(-1, result);
308 thread.Join();
311 // Tests that TranslatePepperFileOpenFlags translates pepper read/write open
312 // flags into NaCl open flags correctly.
313 TEST_F(NaClIPCAdapterTest, TranslatePepperFileReadWriteOpenFlags) {
314 EXPECT_EQ(NACL_ABI_O_RDONLY,
315 TranslatePepperFileReadWriteOpenFlagsForTesting(PP_FILEOPENFLAG_READ));
316 EXPECT_EQ(NACL_ABI_O_WRONLY,
317 TranslatePepperFileReadWriteOpenFlagsForTesting(PP_FILEOPENFLAG_WRITE));
318 EXPECT_EQ(NACL_ABI_O_WRONLY | NACL_ABI_O_APPEND,
319 TranslatePepperFileReadWriteOpenFlagsForTesting(
320 PP_FILEOPENFLAG_APPEND));
321 EXPECT_EQ(NACL_ABI_O_RDWR,
322 TranslatePepperFileReadWriteOpenFlagsForTesting(
323 PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_WRITE));
324 EXPECT_EQ(NACL_ABI_O_WRONLY | NACL_ABI_O_APPEND,
325 TranslatePepperFileReadWriteOpenFlagsForTesting(
326 PP_FILEOPENFLAG_APPEND));
327 EXPECT_EQ(NACL_ABI_O_RDWR | NACL_ABI_O_APPEND,
328 TranslatePepperFileReadWriteOpenFlagsForTesting(
329 PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_APPEND));
331 // Flags other than PP_FILEOPENFLAG_READ, PP_FILEOPENFLAG_WRITE, and
332 // PP_FILEOPENFLAG_APPEND are discarded.
333 EXPECT_EQ(NACL_ABI_O_WRONLY,
334 TranslatePepperFileReadWriteOpenFlagsForTesting(
335 PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE));
336 EXPECT_EQ(NACL_ABI_O_WRONLY,
337 TranslatePepperFileReadWriteOpenFlagsForTesting(
338 PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_TRUNCATE));
339 EXPECT_EQ(NACL_ABI_O_WRONLY,
340 TranslatePepperFileReadWriteOpenFlagsForTesting(
341 PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_EXCLUSIVE));
343 // If none of PP_FILEOPENFLAG_READ, PP_FILEOPENFLAG_WRITE, and
344 // PP_FILEOPENFLAG_APPEND are set, the result should fall back to
345 // NACL_ABI_O_READONLY.
346 EXPECT_EQ(NACL_ABI_O_RDONLY,
347 TranslatePepperFileReadWriteOpenFlagsForTesting(0));
348 EXPECT_EQ(NACL_ABI_O_RDONLY,
349 TranslatePepperFileReadWriteOpenFlagsForTesting(
350 PP_FILEOPENFLAG_CREATE));
351 EXPECT_EQ(NACL_ABI_O_RDONLY,
352 TranslatePepperFileReadWriteOpenFlagsForTesting(
353 PP_FILEOPENFLAG_TRUNCATE));
354 EXPECT_EQ(NACL_ABI_O_RDONLY,
355 TranslatePepperFileReadWriteOpenFlagsForTesting(
356 PP_FILEOPENFLAG_EXCLUSIVE));