Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / components / nacl / loader / nacl_ipc_adapter_unittest.cc
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.
4
5 #include "components/nacl/loader/nacl_ipc_adapter.h"
6
7 #include <string.h>
8
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"
19
20 namespace {
21
22 class NaClIPCAdapterTest : public testing::Test {
23  public:
24   NaClIPCAdapterTest() {}
25
26   // testing::Test implementation.
27   void SetUp() override {
28     sink_ = new IPC::TestSink;
29
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());
35   }
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();
43   }
44
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);
50   }
51
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);
56   }
57
58   base::MessageLoop message_loop_;
59
60   scoped_refptr<NaClIPCAdapter> adapter_;
61
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.
66   //
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_;
70 };
71
72 }  // namespace
73
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();
80
81   int value = 0x12345678;
82   input.WriteInt(value);
83   adapter_->OnMessageReceived(input);
84
85   // Buffer just need to be big enough for our message with one int.
86   const int kBufSize = 64;
87   char buf[kBufSize];
88
89   int bytes_read = BlockingReceive(buf, kBufSize);
90   EXPECT_EQ(sizeof(NaClIPCAdapter::NaClMessageHeader) + sizeof(int),
91             static_cast<size_t>(bytes_read));
92
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);
101
102   // Validate the payload.
103   EXPECT_EQ(value,
104             *reinterpret_cast<const int*>(&buf[
105                 sizeof(NaClIPCAdapter::NaClMessageHeader)]));
106 }
107
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;
113
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};
117
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;
127
128   int result = Send(buf, buf_size);
129   EXPECT_EQ(buf_size, result);
130
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);
136
137   EXPECT_EQ(sizeof(int), msg->payload_size());
138   EXPECT_EQ(header->routing, msg->routing_id());
139   EXPECT_EQ(header->type, msg->type());
140
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);
147
148   // First partial send should not have made any messages.
149   message_loop_.RunUntilIdle();
150   ASSERT_EQ(0u, sink_->message_count());
151
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());
158
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);
164
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());
172 }
173
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);
182
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);
189
190   const int kBufSize = 64;
191   char buf[kBufSize];
192
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);
197
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));
203
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);
210
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);
220 }
221
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;
229
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};
235
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;
245
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());
251
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);
256
257   // First partial send should not have made any messages.
258   message_loop_.RunUntilIdle();
259   ASSERT_EQ(0u, sink_->message_count());
260
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());
266 }
267
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();
285     }
286    private:
287     scoped_refptr<NaClIPCAdapter> adapter_;
288   };
289   MyThread thread(adapter_.get());
290
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();
294
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);
302
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);
307
308   thread.Join();
309 }
310
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));
330
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));
342
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));
357 }