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