OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "build/build_config.h" | 5 #include "build/build_config.h" |
6 | 6 |
7 #if defined(OS_POSIX) | 7 #if defined(OS_POSIX) |
8 #if defined(OS_MACOSX) | 8 #if defined(OS_MACOSX) |
9 extern "C" { | 9 extern "C" { |
10 #include <sandbox.h> | 10 #include <sandbox.h> |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 ++num_fds_received_; | 106 ++num_fds_received_; |
107 if (num_fds_received_ == kNumFDsToSend * kNumMessages) | 107 if (num_fds_received_ == kNumFDsToSend * kNumMessages) |
108 base::MessageLoop::current()->QuitWhenIdle(); | 108 base::MessageLoop::current()->QuitWhenIdle(); |
109 } | 109 } |
110 | 110 |
111 private: | 111 private: |
112 ino_t expected_inode_num_; | 112 ino_t expected_inode_num_; |
113 unsigned num_fds_received_; | 113 unsigned num_fds_received_; |
114 }; | 114 }; |
115 | 115 |
116 class IPCSendFdsTest : public IPCChannelMojoTestBase { | 116 |
| 117 class IPCSendFdsTest : public IPCTestBase { |
117 protected: | 118 protected: |
118 void RunServer() { | 119 void RunServer() { |
119 // Set up IPC channel and start client. | 120 // Set up IPC channel and start client. |
120 MyChannelDescriptorListener listener(-1); | 121 MyChannelDescriptorListener listener(-1); |
121 CreateChannel(&listener); | 122 CreateChannel(&listener); |
122 ASSERT_TRUE(ConnectChannel()); | 123 ASSERT_TRUE(ConnectChannel()); |
| 124 ASSERT_TRUE(StartClient()); |
123 | 125 |
124 for (unsigned i = 0; i < kNumMessages; ++i) { | 126 for (unsigned i = 0; i < kNumMessages; ++i) { |
125 IPC::Message* message = | 127 IPC::Message* message = |
126 new IPC::Message(0, 3, IPC::Message::PRIORITY_NORMAL); | 128 new IPC::Message(0, 3, IPC::Message::PRIORITY_NORMAL); |
127 for (unsigned j = 0; j < kNumFDsToSend; ++j) { | 129 for (unsigned j = 0; j < kNumFDsToSend; ++j) { |
128 const int fd = open(kDevZeroPath, O_RDONLY); | 130 const int fd = open(kDevZeroPath, O_RDONLY); |
129 ASSERT_GE(fd, 0); | 131 ASSERT_GE(fd, 0); |
130 base::FileDescriptor descriptor(fd, true); | 132 base::FileDescriptor descriptor(fd, true); |
131 IPC::ParamTraits<base::FileDescriptor>::Write(message, descriptor); | 133 IPC::ParamTraits<base::FileDescriptor>::Write(message, descriptor); |
132 } | 134 } |
133 ASSERT_TRUE(sender()->Send(message)); | 135 ASSERT_TRUE(sender()->Send(message)); |
134 } | 136 } |
135 | 137 |
136 // Run message loop. | 138 // Run message loop. |
137 base::RunLoop().Run(); | 139 base::RunLoop().Run(); |
138 | 140 |
139 // Close the channel so the client's OnChannelError() gets fired. | 141 // Close the channel so the client's OnChannelError() gets fired. |
140 channel()->Close(); | 142 channel()->Close(); |
141 | 143 |
142 EXPECT_TRUE(WaitForClientShutdown()); | 144 EXPECT_TRUE(WaitForClientShutdown()); |
143 DestroyChannel(); | 145 DestroyChannel(); |
144 } | 146 } |
145 }; | 147 }; |
146 | 148 |
147 TEST_F(IPCSendFdsTest, DescriptorTest) { | 149 TEST_F(IPCSendFdsTest, DescriptorTest) { |
148 Init("SendFdsClient"); | 150 Init("SendFdsClient"); |
149 RunServer(); | 151 RunServer(); |
150 } | 152 } |
151 | 153 |
152 class SendFdsTestClientFixture : public IpcChannelMojoTestClient { | 154 int SendFdsClientCommon(const std::string& test_client_name, |
153 protected: | 155 ino_t expected_inode_num) { |
154 void SendFdsClientCommon(const std::string& test_client_name, | 156 base::MessageLoopForIO main_message_loop; |
155 ino_t expected_inode_num) { | 157 MyChannelDescriptorListener listener(expected_inode_num); |
156 MyChannelDescriptorListener listener(expected_inode_num); | |
157 | 158 |
158 // Set up IPC channel. | 159 // Set up IPC channel. |
159 Connect(&listener); | 160 std::unique_ptr<IPC::Channel> channel(IPC::Channel::CreateClient( |
| 161 IPCTestBase::GetChannelName(test_client_name), &listener, |
| 162 main_message_loop.task_runner())); |
| 163 CHECK(channel->Connect()); |
160 | 164 |
161 // Run message loop. | 165 // Run message loop. |
162 base::RunLoop().Run(); | 166 base::RunLoop().Run(); |
163 | 167 |
164 // Verify that the message loop was exited due to getting the correct number | 168 // Verify that the message loop was exited due to getting the correct number |
165 // of descriptors, and not because of the channel closing unexpectedly. | 169 // of descriptors, and not because of the channel closing unexpectedly. |
166 EXPECT_TRUE(listener.GotExpectedNumberOfDescriptors()); | 170 CHECK(listener.GotExpectedNumberOfDescriptors()); |
167 | 171 |
168 Close(); | 172 return 0; |
169 } | 173 } |
170 }; | |
171 | 174 |
172 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE( | 175 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendFdsClient) { |
173 SendFdsClient, | |
174 SendFdsTestClientFixture) { | |
175 struct stat st; | 176 struct stat st; |
176 int fd = open(kDevZeroPath, O_RDONLY); | 177 int fd = open(kDevZeroPath, O_RDONLY); |
177 fstat(fd, &st); | 178 fstat(fd, &st); |
178 EXPECT_GE(IGNORE_EINTR(close(fd)), 0); | 179 EXPECT_GE(IGNORE_EINTR(close(fd)), 0); |
179 SendFdsClientCommon("SendFdsClient", st.st_ino); | 180 return SendFdsClientCommon("SendFdsClient", st.st_ino); |
180 } | 181 } |
181 | 182 |
182 #if defined(OS_MACOSX) | 183 #if defined(OS_MACOSX) |
183 // Test that FDs are correctly sent to a sandboxed process. | 184 // Test that FDs are correctly sent to a sandboxed process. |
184 // TODO(port): Make this test cross-platform. | 185 // TODO(port): Make this test cross-platform. |
185 TEST_F(IPCSendFdsTest, DescriptorTestSandboxed) { | 186 TEST_F(IPCSendFdsTest, DescriptorTestSandboxed) { |
186 Init("SendFdsSandboxedClient"); | 187 Init("SendFdsSandboxedClient"); |
187 RunServer(); | 188 RunServer(); |
188 } | 189 } |
189 | 190 |
190 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE( | 191 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendFdsSandboxedClient) { |
191 SendFdsSandboxedClient, | |
192 SendFdsTestClientFixture) { | |
193 struct stat st; | 192 struct stat st; |
194 const int fd = open(kDevZeroPath, O_RDONLY); | 193 const int fd = open(kDevZeroPath, O_RDONLY); |
195 fstat(fd, &st); | 194 fstat(fd, &st); |
196 ASSERT_LE(0, IGNORE_EINTR(close(fd))); | 195 if (IGNORE_EINTR(close(fd)) < 0) |
| 196 return -1; |
197 | 197 |
198 // Enable the sandbox. | 198 // Enable the sandbox. |
199 char* error_buff = NULL; | 199 char* error_buff = NULL; |
200 int error = sandbox::Seatbelt::Init( | 200 int error = sandbox::Seatbelt::Init( |
201 sandbox::Seatbelt::kProfilePureComputation, SANDBOX_NAMED, &error_buff); | 201 sandbox::Seatbelt::kProfilePureComputation, SANDBOX_NAMED, &error_buff); |
202 ASSERT_EQ(0, error); | 202 bool success = (error == 0 && error_buff == NULL); |
203 ASSERT_FALSE(error_buff); | 203 if (!success) |
| 204 return -1; |
204 | 205 |
205 sandbox::Seatbelt::FreeError(error_buff); | 206 sandbox::Seatbelt::FreeError(error_buff); |
206 | 207 |
207 // Make sure sandbox is really enabled. | 208 // Make sure sandbox is really enabled. |
208 ASSERT_EQ(-1, open(kDevZeroPath, O_RDONLY)) | 209 if (open(kDevZeroPath, O_RDONLY) != -1) { |
209 << "Sandbox wasn't properly enabled"; | 210 LOG(ERROR) << "Sandbox wasn't properly enabled"; |
| 211 return -1; |
| 212 } |
210 | 213 |
211 // See if we can receive a file descriptor. | 214 // See if we can receive a file descriptor. |
212 SendFdsClientCommon("SendFdsSandboxedClient", st.st_ino); | 215 return SendFdsClientCommon("SendFdsSandboxedClient", st.st_ino); |
213 } | 216 } |
214 #endif // defined(OS_MACOSX) | 217 #endif // defined(OS_MACOSX) |
215 | 218 |
216 | 219 |
217 class MyCBListener : public MyChannelDescriptorListenerBase { | 220 class MyCBListener : public MyChannelDescriptorListenerBase { |
218 public: | 221 public: |
219 MyCBListener(base::Callback<void(int)> cb, int fds_to_send) | 222 MyCBListener(base::Callback<void(int)> cb, int fds_to_send) |
220 : MyChannelDescriptorListenerBase(), | 223 : MyChannelDescriptorListenerBase(), |
221 cb_(cb) { | 224 cb_(cb) { |
222 } | 225 } |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 base::WaitableEvent received_; | 388 base::WaitableEvent received_; |
386 }; | 389 }; |
387 | 390 |
388 TEST_F(IPCMultiSendingFdsTest, StressTest) { | 391 TEST_F(IPCMultiSendingFdsTest, StressTest) { |
389 Run(); | 392 Run(); |
390 } | 393 } |
391 | 394 |
392 } // namespace | 395 } // namespace |
393 | 396 |
394 #endif // defined(OS_POSIX) | 397 #endif // defined(OS_POSIX) |
OLD | NEW |