| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/nacl/loader/nacl_ipc_adapter.h" | 5 #include "components/nacl/loader/nacl_ipc_adapter.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 | 10 |
| 11 #include <memory> | 11 #include <memory> |
| 12 | 12 |
| 13 #include "base/run_loop.h" |
| 13 #include "base/threading/platform_thread.h" | 14 #include "base/threading/platform_thread.h" |
| 14 #include "base/threading/simple_thread.h" | 15 #include "base/threading/simple_thread.h" |
| 15 #include "base/threading/thread_task_runner_handle.h" | 16 #include "base/threading/thread_task_runner_handle.h" |
| 16 #include "ipc/ipc_test_sink.h" | 17 #include "ipc/ipc_test_sink.h" |
| 17 #include "native_client/src/public/nacl_desc_custom.h" | 18 #include "native_client/src/public/nacl_desc_custom.h" |
| 18 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h" | 19 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h" |
| 19 #include "ppapi/c/ppb_file_io.h" | 20 #include "ppapi/c/ppb_file_io.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 34 // not need real IPC for the tests. | 35 // not need real IPC for the tests. |
| 35 adapter_ = new NaClIPCAdapter(std::unique_ptr<IPC::Channel>(sink_), | 36 adapter_ = new NaClIPCAdapter(std::unique_ptr<IPC::Channel>(sink_), |
| 36 base::ThreadTaskRunnerHandle::Get().get()); | 37 base::ThreadTaskRunnerHandle::Get().get()); |
| 37 } | 38 } |
| 38 void TearDown() override { | 39 void TearDown() override { |
| 39 sink_ = NULL; // This pointer is actually owned by the IPCAdapter. | 40 sink_ = NULL; // This pointer is actually owned by the IPCAdapter. |
| 40 adapter_ = NULL; | 41 adapter_ = NULL; |
| 41 // The adapter destructor has to post a task to destroy the Channel on the | 42 // The adapter destructor has to post a task to destroy the Channel on the |
| 42 // IO thread. For the purposes of the test, we just need to make sure that | 43 // IO thread. For the purposes of the test, we just need to make sure that |
| 43 // task gets run, or it will appear as a leak. | 44 // task gets run, or it will appear as a leak. |
| 44 message_loop_.RunUntilIdle(); | 45 base::RunLoop().RunUntilIdle(); |
| 45 } | 46 } |
| 46 | 47 |
| 47 protected: | 48 protected: |
| 48 int BlockingReceive(void* buf, size_t buf_size) { | 49 int BlockingReceive(void* buf, size_t buf_size) { |
| 49 NaClImcMsgIoVec iov = {buf, buf_size}; | 50 NaClImcMsgIoVec iov = {buf, buf_size}; |
| 50 NaClImcTypedMsgHdr msg = {&iov, 1}; | 51 NaClImcTypedMsgHdr msg = {&iov, 1}; |
| 51 return adapter_->BlockingReceive(&msg); | 52 return adapter_->BlockingReceive(&msg); |
| 52 } | 53 } |
| 53 | 54 |
| 54 int Send(void* buf, size_t buf_size) { | 55 int Send(void* buf, size_t buf_size) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 header->flags = 0; | 126 header->flags = 0; |
| 126 header->num_fds = 0; | 127 header->num_fds = 0; |
| 127 *reinterpret_cast<int*>( | 128 *reinterpret_cast<int*>( |
| 128 &buf[sizeof(NaClIPCAdapter::NaClMessageHeader)]) = value; | 129 &buf[sizeof(NaClIPCAdapter::NaClMessageHeader)]) = value; |
| 129 | 130 |
| 130 int result = Send(buf, buf_size); | 131 int result = Send(buf, buf_size); |
| 131 EXPECT_EQ(buf_size, result); | 132 EXPECT_EQ(buf_size, result); |
| 132 | 133 |
| 133 // Check that the message came out the other end in the test sink | 134 // Check that the message came out the other end in the test sink |
| 134 // (messages are posted, so we have to pump). | 135 // (messages are posted, so we have to pump). |
| 135 message_loop_.RunUntilIdle(); | 136 base::RunLoop().RunUntilIdle(); |
| 136 ASSERT_EQ(1u, sink_->message_count()); | 137 ASSERT_EQ(1u, sink_->message_count()); |
| 137 const IPC::Message* msg = sink_->GetMessageAt(0); | 138 const IPC::Message* msg = sink_->GetMessageAt(0); |
| 138 | 139 |
| 139 EXPECT_EQ(sizeof(int), msg->payload_size()); | 140 EXPECT_EQ(sizeof(int), msg->payload_size()); |
| 140 EXPECT_EQ(header->routing, msg->routing_id()); | 141 EXPECT_EQ(header->routing, msg->routing_id()); |
| 141 EXPECT_EQ(header->type, msg->type()); | 142 EXPECT_EQ(header->type, msg->type()); |
| 142 | 143 |
| 143 // Now test the partial send case. We should be able to break the message | 144 // Now test the partial send case. We should be able to break the message |
| 144 // into two parts and it should still work. | 145 // into two parts and it should still work. |
| 145 sink_->ClearMessages(); | 146 sink_->ClearMessages(); |
| 146 int first_chunk_size = 7; | 147 int first_chunk_size = 7; |
| 147 result = Send(buf, first_chunk_size); | 148 result = Send(buf, first_chunk_size); |
| 148 EXPECT_EQ(first_chunk_size, result); | 149 EXPECT_EQ(first_chunk_size, result); |
| 149 | 150 |
| 150 // First partial send should not have made any messages. | 151 // First partial send should not have made any messages. |
| 151 message_loop_.RunUntilIdle(); | 152 base::RunLoop().RunUntilIdle(); |
| 152 ASSERT_EQ(0u, sink_->message_count()); | 153 ASSERT_EQ(0u, sink_->message_count()); |
| 153 | 154 |
| 154 // Second partial send should do the same. | 155 // Second partial send should do the same. |
| 155 int second_chunk_size = 2; | 156 int second_chunk_size = 2; |
| 156 result = Send(&buf[first_chunk_size], second_chunk_size); | 157 result = Send(&buf[first_chunk_size], second_chunk_size); |
| 157 EXPECT_EQ(second_chunk_size, result); | 158 EXPECT_EQ(second_chunk_size, result); |
| 158 message_loop_.RunUntilIdle(); | 159 base::RunLoop().RunUntilIdle(); |
| 159 ASSERT_EQ(0u, sink_->message_count()); | 160 ASSERT_EQ(0u, sink_->message_count()); |
| 160 | 161 |
| 161 // Send the rest of the message in a third chunk. | 162 // Send the rest of the message in a third chunk. |
| 162 int third_chunk_size = buf_size - first_chunk_size - second_chunk_size; | 163 int third_chunk_size = buf_size - first_chunk_size - second_chunk_size; |
| 163 result = Send(&buf[first_chunk_size + second_chunk_size], | 164 result = Send(&buf[first_chunk_size + second_chunk_size], |
| 164 third_chunk_size); | 165 third_chunk_size); |
| 165 EXPECT_EQ(third_chunk_size, result); | 166 EXPECT_EQ(third_chunk_size, result); |
| 166 | 167 |
| 167 // Last send should have generated one message. | 168 // Last send should have generated one message. |
| 168 message_loop_.RunUntilIdle(); | 169 base::RunLoop().RunUntilIdle(); |
| 169 ASSERT_EQ(1u, sink_->message_count()); | 170 ASSERT_EQ(1u, sink_->message_count()); |
| 170 msg = sink_->GetMessageAt(0); | 171 msg = sink_->GetMessageAt(0); |
| 171 EXPECT_EQ(sizeof(int), msg->payload_size()); | 172 EXPECT_EQ(sizeof(int), msg->payload_size()); |
| 172 EXPECT_EQ(header->routing, msg->routing_id()); | 173 EXPECT_EQ(header->routing, msg->routing_id()); |
| 173 EXPECT_EQ(header->type, msg->type()); | 174 EXPECT_EQ(header->type, msg->type()); |
| 174 } | 175 } |
| 175 | 176 |
| 176 // Tests when a buffer is too small to receive the entire message. | 177 // Tests when a buffer is too small to receive the entire message. |
| 177 TEST_F(NaClIPCAdapterTest, PartialReceive) { | 178 TEST_F(NaClIPCAdapterTest, PartialReceive) { |
| 178 int routing_id_1 = 0x89898989; | 179 int routing_id_1 = 0x89898989; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 header->routing = routing_id; | 242 header->routing = routing_id; |
| 242 header->type = type; | 243 header->type = type; |
| 243 header->flags = 0; | 244 header->flags = 0; |
| 244 header->num_fds = 0; | 245 header->num_fds = 0; |
| 245 *reinterpret_cast<int*>( | 246 *reinterpret_cast<int*>( |
| 246 &buf[sizeof(NaClIPCAdapter::NaClMessageHeader)]) = value; | 247 &buf[sizeof(NaClIPCAdapter::NaClMessageHeader)]) = value; |
| 247 | 248 |
| 248 // Send too much data and make sure that the send fails. | 249 // Send too much data and make sure that the send fails. |
| 249 int result = Send(buf, big_buf_size); | 250 int result = Send(buf, big_buf_size); |
| 250 EXPECT_EQ(-1, result); | 251 EXPECT_EQ(-1, result); |
| 251 message_loop_.RunUntilIdle(); | 252 base::RunLoop().RunUntilIdle(); |
| 252 ASSERT_EQ(0u, sink_->message_count()); | 253 ASSERT_EQ(0u, sink_->message_count()); |
| 253 | 254 |
| 254 // Send too much data in two chunks and make sure that the send fails. | 255 // Send too much data in two chunks and make sure that the send fails. |
| 255 int first_chunk_size = 7; | 256 int first_chunk_size = 7; |
| 256 result = Send(buf, first_chunk_size); | 257 result = Send(buf, first_chunk_size); |
| 257 EXPECT_EQ(first_chunk_size, result); | 258 EXPECT_EQ(first_chunk_size, result); |
| 258 | 259 |
| 259 // First partial send should not have made any messages. | 260 // First partial send should not have made any messages. |
| 260 message_loop_.RunUntilIdle(); | 261 base::RunLoop().RunUntilIdle(); |
| 261 ASSERT_EQ(0u, sink_->message_count()); | 262 ASSERT_EQ(0u, sink_->message_count()); |
| 262 | 263 |
| 263 int second_chunk_size = big_buf_size - first_chunk_size; | 264 int second_chunk_size = big_buf_size - first_chunk_size; |
| 264 result = Send(&buf[first_chunk_size], second_chunk_size); | 265 result = Send(&buf[first_chunk_size], second_chunk_size); |
| 265 EXPECT_EQ(-1, result); | 266 EXPECT_EQ(-1, result); |
| 266 message_loop_.RunUntilIdle(); | 267 base::RunLoop().RunUntilIdle(); |
| 267 ASSERT_EQ(0u, sink_->message_count()); | 268 ASSERT_EQ(0u, sink_->message_count()); |
| 268 } | 269 } |
| 269 | 270 |
| 270 // Tests that when the IPC channel reports an error, that waiting reads are | 271 // Tests that when the IPC channel reports an error, that waiting reads are |
| 271 // unblocked and return a -1 error code. | 272 // unblocked and return a -1 error code. |
| 272 TEST_F(NaClIPCAdapterTest, ReadWithChannelError) { | 273 TEST_F(NaClIPCAdapterTest, ReadWithChannelError) { |
| 273 // Have a background thread that waits a bit and calls the channel error | 274 // Have a background thread that waits a bit and calls the channel error |
| 274 // handler. This should wake up any waiting threads and immediately return | 275 // handler. This should wake up any waiting threads and immediately return |
| 275 // -1. There is an inherent race condition in that we can't be sure if the | 276 // -1. There is an inherent race condition in that we can't be sure if the |
| 276 // other thread is actually waiting when this happens. This is OK, since the | 277 // other thread is actually waiting when this happens. This is OK, since the |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 EXPECT_EQ(NACL_ABI_O_RDONLY, | 351 EXPECT_EQ(NACL_ABI_O_RDONLY, |
| 351 TranslatePepperFileReadWriteOpenFlagsForTesting( | 352 TranslatePepperFileReadWriteOpenFlagsForTesting( |
| 352 PP_FILEOPENFLAG_CREATE)); | 353 PP_FILEOPENFLAG_CREATE)); |
| 353 EXPECT_EQ(NACL_ABI_O_RDONLY, | 354 EXPECT_EQ(NACL_ABI_O_RDONLY, |
| 354 TranslatePepperFileReadWriteOpenFlagsForTesting( | 355 TranslatePepperFileReadWriteOpenFlagsForTesting( |
| 355 PP_FILEOPENFLAG_TRUNCATE)); | 356 PP_FILEOPENFLAG_TRUNCATE)); |
| 356 EXPECT_EQ(NACL_ABI_O_RDONLY, | 357 EXPECT_EQ(NACL_ABI_O_RDONLY, |
| 357 TranslatePepperFileReadWriteOpenFlagsForTesting( | 358 TranslatePepperFileReadWriteOpenFlagsForTesting( |
| 358 PP_FILEOPENFLAG_EXCLUSIVE)); | 359 PP_FILEOPENFLAG_EXCLUSIVE)); |
| 359 } | 360 } |
| OLD | NEW |