| 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 |