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 "ppapi/tests/test_tcp_server_socket_private.h" | 5 #include "ppapi/tests/test_tcp_server_socket_private.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "ppapi/cpp/pass_ref.h" | 9 #include "ppapi/cpp/pass_ref.h" |
10 #include "ppapi/cpp/private/net_address_private.h" | 10 #include "ppapi/cpp/private/net_address_private.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 | 53 |
54 return tcp_server_socket_private_is_available && | 54 return tcp_server_socket_private_is_available && |
55 tcp_socket_private_is_available && | 55 tcp_socket_private_is_available && |
56 net_address_private_is_available && | 56 net_address_private_is_available && |
57 init_host_port && | 57 init_host_port && |
58 CheckTestingInterface() && | 58 CheckTestingInterface() && |
59 EnsureRunningOverHTTP(); | 59 EnsureRunningOverHTTP(); |
60 } | 60 } |
61 | 61 |
62 void TestTCPServerSocketPrivate::RunTests(const std::string& filter) { | 62 void TestTCPServerSocketPrivate::RunTests(const std::string& filter) { |
63 RUN_TEST_FORCEASYNC_AND_NOT(Listen, filter); | 63 RUN_CALLBACK_TEST(TestTCPServerSocketPrivate, Listen, filter); |
64 RUN_TEST_FORCEASYNC_AND_NOT(Backlog, filter); | 64 RUN_CALLBACK_TEST(TestTCPServerSocketPrivate, Backlog, filter); |
65 } | 65 } |
66 | 66 |
67 std::string TestTCPServerSocketPrivate::GetLocalAddress( | 67 std::string TestTCPServerSocketPrivate::GetLocalAddress( |
68 PP_NetAddress_Private* address) { | 68 PP_NetAddress_Private* address) { |
69 TCPSocketPrivate socket(instance_); | 69 TCPSocketPrivate socket(instance_); |
70 TestCompletionCallback callback(instance_->pp_instance(), force_async_); | 70 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
71 int32_t rv = socket.Connect(host_.c_str(), port_, callback.GetCallback()); | 71 callback.WaitForResult( |
72 if (force_async_ && rv != PP_OK_COMPLETIONPENDING) | 72 socket.Connect(host_.c_str(), port_, callback.GetCallback())); |
73 return ReportError("PPB_TCPSocket_Private::Connect force_async", rv); | 73 CHECK_CALLBACK_BEHAVIOR(callback); |
74 if (rv == PP_OK_COMPLETIONPENDING) | 74 ASSERT_EQ(PP_OK, callback.result()); |
75 rv = callback.WaitForResult(); | 75 ASSERT_TRUE(socket.GetLocalAddress(address)); |
76 if (rv != PP_OK) | |
77 return ReportError("PPB_TCPSocket_Private::Connect", rv); | |
78 if (!socket.GetLocalAddress(address)) | |
79 return ReportError("PPB_TCPSocket_Private::GetLocalAddress", 0); | |
80 socket.Disconnect(); | 76 socket.Disconnect(); |
81 PASS(); | 77 PASS(); |
82 } | 78 } |
83 | 79 |
84 std::string TestTCPServerSocketPrivate::SyncRead(TCPSocketPrivate* socket, | 80 std::string TestTCPServerSocketPrivate::SyncRead(TCPSocketPrivate* socket, |
85 char* buffer, | 81 char* buffer, |
86 size_t num_bytes) { | 82 size_t num_bytes) { |
87 while (num_bytes > 0) { | 83 while (num_bytes > 0) { |
88 TestCompletionCallback callback(instance_->pp_instance(), force_async_); | 84 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
89 int32_t rv = socket->Read(buffer, num_bytes, callback.GetCallback()); | 85 callback.WaitForResult( |
90 if (force_async_ && rv != PP_OK_COMPLETIONPENDING) | 86 socket->Read(buffer, num_bytes, callback.GetCallback())); |
91 return ReportError("PPB_TCPSocket_Private::Read force_async", rv); | 87 CHECK_CALLBACK_BEHAVIOR(callback); |
92 if (rv == PP_OK_COMPLETIONPENDING) | 88 ASSERT_TRUE(callback.result() >= 0); |
93 rv = callback.WaitForResult(); | 89 buffer += callback.result(); |
94 if (rv < 0) | 90 num_bytes -= callback.result(); |
95 return ReportError("PPB_TCPSocket_Private::Read", rv); | |
96 buffer += rv; | |
97 num_bytes -= rv; | |
98 } | 91 } |
99 PASS(); | 92 PASS(); |
100 } | 93 } |
101 | 94 |
102 std::string TestTCPServerSocketPrivate::SyncWrite(TCPSocketPrivate* socket, | 95 std::string TestTCPServerSocketPrivate::SyncWrite(TCPSocketPrivate* socket, |
103 const char* buffer, | 96 const char* buffer, |
104 size_t num_bytes) { | 97 size_t num_bytes) { |
105 while (num_bytes > 0) { | 98 while (num_bytes > 0) { |
106 TestCompletionCallback callback(instance_->pp_instance(), force_async_); | 99 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
107 int32_t rv = socket->Write(buffer, num_bytes, callback.GetCallback()); | 100 callback.WaitForResult( |
108 if (force_async_ && rv != PP_OK_COMPLETIONPENDING) | 101 socket->Write(buffer, num_bytes, callback.GetCallback())); |
109 return ReportError("PPB_TCPSocket_Private::Write force_async", rv); | 102 CHECK_CALLBACK_BEHAVIOR(callback); |
110 if (rv == PP_OK_COMPLETIONPENDING) | 103 ASSERT_TRUE(callback.result() >= 0); |
111 rv = callback.WaitForResult(); | 104 buffer += callback.result(); |
112 if (rv < 0) | 105 num_bytes -= callback.result(); |
113 return ReportError("PPB_TCPSocket_Private::Write", rv); | |
114 buffer += rv; | |
115 num_bytes -= rv; | |
116 } | 106 } |
117 PASS(); | 107 PASS(); |
118 } | 108 } |
119 | 109 |
120 std::string TestTCPServerSocketPrivate::SyncConnect( | 110 std::string TestTCPServerSocketPrivate::SyncConnect( |
121 TCPSocketPrivate* socket, | 111 TCPSocketPrivate* socket, |
122 PP_NetAddress_Private* address) { | 112 PP_NetAddress_Private* address) { |
123 TestCompletionCallback callback(instance_->pp_instance(), force_async_); | 113 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
124 int32_t rv = socket->ConnectWithNetAddress(address, callback.GetCallback()); | 114 callback.WaitForResult( |
125 if (force_async_ && rv != PP_OK_COMPLETIONPENDING) | 115 socket->ConnectWithNetAddress(address, callback.GetCallback())); |
126 return ReportError("PPB_TCPSocket_Private::Connect force_async", rv); | 116 CHECK_CALLBACK_BEHAVIOR(callback); |
127 if (rv == PP_OK_COMPLETIONPENDING) | 117 ASSERT_EQ(PP_OK, callback.result()); |
128 rv = callback.WaitForResult(); | |
129 if (rv != PP_OK) | |
130 return ReportError("PPB_TCPSocket_Private::Connect", rv); | |
131 PASS(); | 118 PASS(); |
132 } | 119 } |
133 | 120 |
134 void TestTCPServerSocketPrivate::ForceConnect(TCPSocketPrivate* socket, | 121 void TestTCPServerSocketPrivate::ForceConnect(TCPSocketPrivate* socket, |
135 PP_NetAddress_Private* address) { | 122 PP_NetAddress_Private* address) { |
136 std::string error_message; | 123 std::string error_message; |
137 do { | 124 do { |
138 error_message = SyncConnect(socket, address); | 125 error_message = SyncConnect(socket, address); |
139 } while (!error_message.empty()); | 126 } while (!error_message.empty()); |
140 } | 127 } |
141 | 128 |
142 std::string TestTCPServerSocketPrivate::SyncListen( | 129 std::string TestTCPServerSocketPrivate::SyncListen( |
143 TCPServerSocketPrivate* socket, | 130 TCPServerSocketPrivate* socket, |
144 PP_NetAddress_Private* address, | 131 PP_NetAddress_Private* address, |
145 int32_t backlog) { | 132 int32_t backlog) { |
146 PP_NetAddress_Private base_address; | 133 PP_NetAddress_Private base_address; |
147 ASSERT_SUBTEST_SUCCESS(GetLocalAddress(&base_address)); | 134 ASSERT_SUBTEST_SUCCESS(GetLocalAddress(&base_address)); |
148 | 135 |
149 // TODO (ygorshenin): find more efficient way to select available | 136 // TODO (ygorshenin): find more efficient way to select available |
150 // ports. | 137 // ports. |
151 bool is_free_port_found = false; | 138 bool is_free_port_found = false; |
152 for (uint16_t port = kPortScanFrom; port < kPortScanTo; ++port) { | 139 for (uint16_t port = kPortScanFrom; port < kPortScanTo; ++port) { |
153 if (!NetAddressPrivate::ReplacePort(base_address, port, address)) | 140 if (!NetAddressPrivate::ReplacePort(base_address, port, address)) |
154 return ReportError("PPB_NetAddress_Private::ReplacePort", 0); | 141 return ReportError("PPB_NetAddress_Private::ReplacePort", 0); |
155 | 142 |
156 TestCompletionCallback callback(instance_->pp_instance(), force_async_); | 143 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
157 int32_t rv = socket->Listen(address, backlog, callback.GetCallback()); | 144 callback.WaitForResult( |
158 if (force_async_ && rv != PP_OK_COMPLETIONPENDING) | 145 socket->Listen(address, backlog, callback.GetCallback())); |
159 return ReportError("PPB_TCPServerSocket_Private::Listen force_async", rv); | 146 CHECK_CALLBACK_BEHAVIOR(callback); |
160 if (rv == PP_OK_COMPLETIONPENDING) | 147 if (callback.result() == PP_OK) { |
161 rv = callback.WaitForResult(); | |
162 if (rv == PP_OK) { | |
163 is_free_port_found = true; | 148 is_free_port_found = true; |
164 break; | 149 break; |
165 } | 150 } |
166 } | 151 } |
167 | 152 |
168 if (!is_free_port_found) | 153 ASSERT_TRUE(is_free_port_found); |
169 return "Can't find available port"; | |
170 PASS(); | 154 PASS(); |
171 } | 155 } |
172 | 156 |
173 std::string TestTCPServerSocketPrivate::TestListen() { | 157 std::string TestTCPServerSocketPrivate::TestListen() { |
174 static const int kBacklog = 2; | 158 static const int kBacklog = 2; |
175 | 159 |
176 TCPServerSocketPrivate server_socket(instance_); | 160 TCPServerSocketPrivate server_socket(instance_); |
177 | 161 |
178 PP_NetAddress_Private address; | 162 PP_NetAddress_Private address; |
179 ASSERT_SUBTEST_SUCCESS(SyncListen(&server_socket, &address, kBacklog)); | 163 ASSERT_SUBTEST_SUCCESS(SyncListen(&server_socket, &address, kBacklog)); |
180 | 164 |
| 165 // We can't use a blocking callback for Accept, because it will wait forever |
| 166 // for the client to connect, since the client connects after. |
181 TestCompletionCallback accept_callback(instance_->pp_instance(), | 167 TestCompletionCallback accept_callback(instance_->pp_instance(), |
182 force_async_); | 168 PP_REQUIRED); |
| 169 // We need to make sure there's a message loop to run accept_callback on. |
| 170 pp::MessageLoop current_thread_loop(pp::MessageLoop::GetCurrent()); |
| 171 if (current_thread_loop.is_null() && testing_interface_->IsOutOfProcess()) { |
| 172 current_thread_loop = pp::MessageLoop(instance_); |
| 173 current_thread_loop.AttachToCurrentThread(); |
| 174 } |
| 175 |
183 PP_Resource resource; | 176 PP_Resource resource; |
184 int32_t accept_rv = server_socket.Accept(&resource, | 177 int32_t accept_rv = server_socket.Accept(&resource, |
185 accept_callback.GetCallback()); | 178 accept_callback.GetCallback()); |
186 | 179 |
187 TCPSocketPrivate client_socket(instance_); | 180 TCPSocketPrivate client_socket(instance_); |
188 ForceConnect(&client_socket, &address); | 181 ForceConnect(&client_socket, &address); |
189 | 182 |
190 if (force_async_ && accept_rv != PP_OK_COMPLETIONPENDING) { | 183 accept_callback.WaitForResult(accept_rv); |
191 return ReportError("PPB_TCPServerSocket_Private::Accept force_async", | 184 CHECK_CALLBACK_BEHAVIOR(accept_callback); |
192 accept_rv); | 185 ASSERT_EQ(PP_OK, accept_callback.result()); |
193 } | |
194 if (accept_rv == PP_OK_COMPLETIONPENDING) | |
195 accept_rv = accept_callback.WaitForResult(); | |
196 if (accept_rv != PP_OK) | |
197 return ReportError("PPB_TCPServerSocket_Private::Accept", accept_rv); | |
198 | 186 |
199 ASSERT_TRUE(resource != 0); | 187 ASSERT_TRUE(resource != 0); |
200 TCPSocketPrivate accepted_socket(pp::PassRef(), resource); | 188 TCPSocketPrivate accepted_socket(pp::PassRef(), resource); |
201 | 189 |
202 const char kSentByte = 'a'; | 190 const char kSentByte = 'a'; |
203 ASSERT_SUBTEST_SUCCESS(SyncWrite(&client_socket, | 191 ASSERT_SUBTEST_SUCCESS(SyncWrite(&client_socket, |
204 &kSentByte, | 192 &kSentByte, |
205 sizeof(kSentByte))); | 193 sizeof(kSentByte))); |
206 | 194 |
207 char received_byte; | 195 char received_byte; |
(...skipping 16 matching lines...) Expand all Loading... |
224 | 212 |
225 PP_NetAddress_Private address; | 213 PP_NetAddress_Private address; |
226 ASSERT_SUBTEST_SUCCESS(SyncListen(&server_socket, &address, 2 * kBacklog)); | 214 ASSERT_SUBTEST_SUCCESS(SyncListen(&server_socket, &address, 2 * kBacklog)); |
227 | 215 |
228 std::vector<TCPSocketPrivate*> client_sockets(kBacklog); | 216 std::vector<TCPSocketPrivate*> client_sockets(kBacklog); |
229 std::vector<TestCompletionCallback*> connect_callbacks(kBacklog); | 217 std::vector<TestCompletionCallback*> connect_callbacks(kBacklog); |
230 std::vector<int32_t> connect_rv(kBacklog); | 218 std::vector<int32_t> connect_rv(kBacklog); |
231 for (size_t i = 0; i < kBacklog; ++i) { | 219 for (size_t i = 0; i < kBacklog; ++i) { |
232 client_sockets[i] = new TCPSocketPrivate(instance_); | 220 client_sockets[i] = new TCPSocketPrivate(instance_); |
233 connect_callbacks[i] = new TestCompletionCallback(instance_->pp_instance(), | 221 connect_callbacks[i] = new TestCompletionCallback(instance_->pp_instance(), |
234 force_async_); | 222 callback_type()); |
235 connect_rv[i] = client_sockets[i]->ConnectWithNetAddress( | 223 connect_rv[i] = client_sockets[i]->ConnectWithNetAddress( |
236 &address, | 224 &address, |
237 connect_callbacks[i]->GetCallback()); | 225 connect_callbacks[i]->GetCallback()); |
238 if (force_async_ && connect_rv[i] != PP_OK_COMPLETIONPENDING) { | |
239 return ReportError("PPB_TCPSocket_Private::Connect force_async", | |
240 connect_rv[i]); | |
241 } | |
242 } | 226 } |
243 | 227 |
244 std::vector<PP_Resource> resources(kBacklog); | 228 std::vector<PP_Resource> resources(kBacklog); |
245 std::vector<TCPSocketPrivate*> accepted_sockets(kBacklog); | 229 std::vector<TCPSocketPrivate*> accepted_sockets(kBacklog); |
246 for (size_t i = 0; i < kBacklog; ++i) { | 230 for (size_t i = 0; i < kBacklog; ++i) { |
247 TestCompletionCallback callback(instance_->pp_instance(), force_async_); | 231 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
248 int32_t rv = server_socket.Accept(&resources[i], callback.GetCallback()); | 232 callback.WaitForResult( |
249 if (force_async_ && rv != PP_OK_COMPLETIONPENDING) | 233 server_socket.Accept(&resources[i], callback.GetCallback())); |
250 return ReportError("PPB_TCPServerSocket_Private::Accept force_async", rv); | 234 CHECK_CALLBACK_BEHAVIOR(callback); |
251 if (rv == PP_OK_COMPLETIONPENDING) | 235 ASSERT_EQ(PP_OK, callback.result()); |
252 rv = callback.WaitForResult(); | |
253 if (rv != PP_OK) | |
254 return ReportError("PPB_TCPServerSocket_Private::Accept", rv); | |
255 | 236 |
256 ASSERT_TRUE(resources[i] != 0); | 237 ASSERT_TRUE(resources[i] != 0); |
257 accepted_sockets[i] = new TCPSocketPrivate(pp::PassRef(), resources[i]); | 238 accepted_sockets[i] = new TCPSocketPrivate(pp::PassRef(), resources[i]); |
258 } | 239 } |
259 | 240 |
260 for (size_t i = 0; i < kBacklog; ++i) { | 241 for (size_t i = 0; i < kBacklog; ++i) { |
261 if (connect_rv[i] == PP_OK_COMPLETIONPENDING) | 242 connect_callbacks[i]->WaitForResult(connect_rv[i]); |
262 connect_rv[i] = connect_callbacks[i]->WaitForResult(); | 243 CHECK_CALLBACK_BEHAVIOR(*connect_callbacks[i]); |
263 if (connect_rv[i] != PP_OK) | 244 ASSERT_EQ(PP_OK, connect_callbacks[i]->result()); |
264 return ReportError("PPB_TCPSocket_Private::Connect", connect_rv[i]); | |
265 } | 245 } |
266 | 246 |
267 for (size_t i = 0; i < kBacklog; ++i) { | 247 for (size_t i = 0; i < kBacklog; ++i) { |
268 const char byte = 'a' + i; | 248 const char byte = 'a' + i; |
269 ASSERT_SUBTEST_SUCCESS(SyncWrite(client_sockets[i], &byte, sizeof(byte))); | 249 ASSERT_SUBTEST_SUCCESS(SyncWrite(client_sockets[i], &byte, sizeof(byte))); |
270 } | 250 } |
271 | 251 |
272 bool byte_received[kBacklog] = {}; | 252 bool byte_received[kBacklog] = {}; |
273 for (size_t i = 0; i < kBacklog; ++i) { | 253 for (size_t i = 0; i < kBacklog; ++i) { |
274 char byte; | 254 char byte; |
275 ASSERT_SUBTEST_SUCCESS(SyncRead(accepted_sockets[i], &byte, sizeof(byte))); | 255 ASSERT_SUBTEST_SUCCESS(SyncRead(accepted_sockets[i], &byte, sizeof(byte))); |
276 const size_t index = byte - 'a'; | 256 const size_t index = byte - 'a'; |
277 ASSERT_FALSE(byte_received[index]); | 257 ASSERT_FALSE(byte_received[index]); |
278 byte_received[index] = true; | 258 byte_received[index] = true; |
279 } | 259 } |
280 | 260 |
281 for (size_t i = 0; i < kBacklog; ++i) { | 261 for (size_t i = 0; i < kBacklog; ++i) { |
282 client_sockets[i]->Disconnect(); | 262 client_sockets[i]->Disconnect(); |
283 delete client_sockets[i]; | 263 delete client_sockets[i]; |
284 delete connect_callbacks[i]; | 264 delete connect_callbacks[i]; |
285 accepted_sockets[i]->Disconnect(); | 265 accepted_sockets[i]->Disconnect(); |
286 delete accepted_sockets[i]; | 266 delete accepted_sockets[i]; |
287 } | 267 } |
288 | 268 |
289 server_socket.StopListening(); | 269 server_socket.StopListening(); |
290 PASS(); | 270 PASS(); |
291 } | 271 } |
OLD | NEW |