| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "ppapi/tests/test_transport.h" | |
| 6 | |
| 7 #include <stdlib.h> | |
| 8 #include <string.h> | |
| 9 | |
| 10 #include <list> | |
| 11 #include <map> | |
| 12 | |
| 13 #include "ppapi/c/dev/ppb_testing_dev.h" | |
| 14 #include "ppapi/c/pp_errors.h" | |
| 15 #include "ppapi/c/pp_macros.h" | |
| 16 #include "ppapi/cpp/dev/transport_dev.h" | |
| 17 #include "ppapi/cpp/instance.h" | |
| 18 #include "ppapi/cpp/module.h" | |
| 19 #include "ppapi/cpp/var.h" | |
| 20 #include "ppapi/tests/test_utils.h" | |
| 21 #include "ppapi/tests/testing_instance.h" | |
| 22 #include "ppapi/utility/completion_callback_factory.h" | |
| 23 | |
| 24 REGISTER_TEST_CASE(Transport); | |
| 25 | |
| 26 namespace { | |
| 27 | |
| 28 const char kTestChannelName[] = "test"; | |
| 29 const int kReadBufferSize = 65536; | |
| 30 | |
| 31 class StreamReader { | |
| 32 public: | |
| 33 StreamReader(pp::Transport_Dev* transport, | |
| 34 int expected_size, | |
| 35 pp::CompletionCallback done_callback) | |
| 36 : expected_size_(expected_size), | |
| 37 done_callback_(done_callback), | |
| 38 PP_ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)), | |
| 39 transport_(transport), | |
| 40 received_size_(0) { | |
| 41 Read(); | |
| 42 } | |
| 43 | |
| 44 const std::list<std::vector<char> >& received() { return received_; } | |
| 45 std::list<std::string> errors() { return errors_; } | |
| 46 | |
| 47 private: | |
| 48 void Read() { | |
| 49 while (true) { | |
| 50 buffer_.resize(kReadBufferSize); | |
| 51 int result = transport_->Recv( | |
| 52 &buffer_[0], buffer_.size(), | |
| 53 callback_factory_.NewOptionalCallback(&StreamReader::OnReadFinished)); | |
| 54 if (result > 0) | |
| 55 DidFinishRead(result); | |
| 56 else | |
| 57 break; | |
| 58 } | |
| 59 } | |
| 60 | |
| 61 void OnReadFinished(int result) { | |
| 62 DidFinishRead(result); | |
| 63 if (result > 0) | |
| 64 Read(); | |
| 65 } | |
| 66 | |
| 67 void DidFinishRead(int result) { | |
| 68 if (result > 0) { | |
| 69 if (result > static_cast<int>(buffer_.size())) { | |
| 70 errors_.push_back(TestCase::MakeFailureMessage( | |
| 71 __FILE__, __LINE__, | |
| 72 "Recv() returned value that is bigger than the buffer.")); | |
| 73 } | |
| 74 buffer_.resize(result); | |
| 75 received_.push_back(buffer_); | |
| 76 received_size_ += buffer_.size(); | |
| 77 if (received_size_ >= expected_size_) | |
| 78 done_callback_.Run(0); | |
| 79 } | |
| 80 } | |
| 81 | |
| 82 int expected_size_; | |
| 83 pp::CompletionCallback done_callback_; | |
| 84 pp::CompletionCallbackFactory<StreamReader> callback_factory_; | |
| 85 pp::Transport_Dev* transport_; | |
| 86 std::vector<char> buffer_; | |
| 87 std::list<std::vector<char> > received_; | |
| 88 int received_size_; | |
| 89 std::list<std::string> errors_; | |
| 90 }; | |
| 91 | |
| 92 } // namespace | |
| 93 | |
| 94 TestTransport::~TestTransport() { | |
| 95 delete transport1_; | |
| 96 delete transport2_; | |
| 97 } | |
| 98 | |
| 99 bool TestTransport::Init() { | |
| 100 transport_interface_ = static_cast<const PPB_Transport_Dev*>( | |
| 101 pp::Module::Get()->GetBrowserInterface(PPB_TRANSPORT_DEV_INTERFACE)); | |
| 102 return transport_interface_ && CheckTestingInterface(); | |
| 103 } | |
| 104 | |
| 105 void TestTransport::RunTests(const std::string& filter) { | |
| 106 RUN_TEST(Create, filter); | |
| 107 RUN_TEST_FORCEASYNC_AND_NOT(Connect, filter); | |
| 108 RUN_TEST(SetProperty, filter); | |
| 109 RUN_TEST_FORCEASYNC_AND_NOT(SendDataUdp, filter); | |
| 110 RUN_TEST_FORCEASYNC_AND_NOT(SendDataTcp, filter); | |
| 111 RUN_TEST_FORCEASYNC_AND_NOT(ConnectAndCloseUdp, filter); | |
| 112 RUN_TEST_FORCEASYNC_AND_NOT(ConnectAndCloseTcp, filter); | |
| 113 } | |
| 114 | |
| 115 std::string TestTransport::InitTargets(PP_TransportType type) { | |
| 116 transport1_ = new pp::Transport_Dev(instance_, kTestChannelName, type); | |
| 117 transport2_ = new pp::Transport_Dev(instance_, kTestChannelName, type); | |
| 118 | |
| 119 ASSERT_NE(NULL, transport1_); | |
| 120 ASSERT_NE(NULL, transport2_); | |
| 121 | |
| 122 PASS(); | |
| 123 } | |
| 124 | |
| 125 std::string TestTransport::Connect() { | |
| 126 TestCompletionCallback connect_cb1(instance_->pp_instance()); | |
| 127 TestCompletionCallback connect_cb2(instance_->pp_instance()); | |
| 128 ASSERT_EQ(transport1_->Connect(connect_cb1), PP_OK_COMPLETIONPENDING); | |
| 129 ASSERT_EQ(transport2_->Connect(connect_cb2), PP_OK_COMPLETIONPENDING); | |
| 130 | |
| 131 pp::Var address1; | |
| 132 pp::Var address2; | |
| 133 TestCompletionCallback next_address_cb1(instance_->pp_instance()); | |
| 134 TestCompletionCallback next_address_cb2(instance_->pp_instance()); | |
| 135 ASSERT_EQ(transport1_->GetNextAddress(&address1, next_address_cb1), | |
| 136 PP_OK_COMPLETIONPENDING); | |
| 137 ASSERT_EQ(transport2_->GetNextAddress(&address2, next_address_cb2), | |
| 138 PP_OK_COMPLETIONPENDING); | |
| 139 ASSERT_EQ(next_address_cb1.WaitForResult(), PP_OK); | |
| 140 ASSERT_EQ(next_address_cb2.WaitForResult(), PP_OK); | |
| 141 ASSERT_EQ(transport1_->GetNextAddress(&address1, next_address_cb1), PP_OK); | |
| 142 ASSERT_EQ(transport2_->GetNextAddress(&address2, next_address_cb2), PP_OK); | |
| 143 | |
| 144 ASSERT_EQ(transport1_->ReceiveRemoteAddress(address2), PP_OK); | |
| 145 ASSERT_EQ(transport2_->ReceiveRemoteAddress(address1), PP_OK); | |
| 146 | |
| 147 | |
| 148 ASSERT_EQ(connect_cb1.WaitForResult(), PP_OK); | |
| 149 ASSERT_EQ(connect_cb2.WaitForResult(), PP_OK); | |
| 150 | |
| 151 ASSERT_TRUE(transport1_->IsWritable()); | |
| 152 ASSERT_TRUE(transport2_->IsWritable()); | |
| 153 | |
| 154 PASS(); | |
| 155 } | |
| 156 | |
| 157 std::string TestTransport::Clean() { | |
| 158 delete transport1_; | |
| 159 transport1_ = NULL; | |
| 160 delete transport2_; | |
| 161 transport2_ = NULL; | |
| 162 | |
| 163 PASS(); | |
| 164 } | |
| 165 | |
| 166 std::string TestTransport::TestCreate() { | |
| 167 ASSERT_SUBTEST_SUCCESS(InitTargets(PP_TRANSPORTTYPE_DATAGRAM)); | |
| 168 | |
| 169 Clean(); | |
| 170 | |
| 171 PASS(); | |
| 172 } | |
| 173 | |
| 174 std::string TestTransport::TestSetProperty() { | |
| 175 ASSERT_SUBTEST_SUCCESS(InitTargets(PP_TRANSPORTTYPE_STREAM)); | |
| 176 | |
| 177 // Try settings STUN and Relay properties. | |
| 178 ASSERT_EQ(transport1_->SetProperty( | |
| 179 PP_TRANSPORTPROPERTY_STUN_SERVER, | |
| 180 pp::Var("stun.example.com:19302")), PP_OK); | |
| 181 | |
| 182 ASSERT_EQ(transport1_->SetProperty( | |
| 183 PP_TRANSPORTPROPERTY_RELAY_SERVER, | |
| 184 pp::Var("ralay.example.com:80")), PP_OK); | |
| 185 | |
| 186 ASSERT_EQ(transport1_->SetProperty( | |
| 187 PP_TRANSPORTPROPERTY_RELAY_USERNAME, | |
| 188 pp::Var("USERNAME")), PP_OK); | |
| 189 ASSERT_EQ(transport1_->SetProperty( | |
| 190 PP_TRANSPORTPROPERTY_RELAY_PASSWORD, | |
| 191 pp::Var("PASSWORD")), PP_OK); | |
| 192 | |
| 193 // Try changing TCP window size. | |
| 194 ASSERT_EQ(transport1_->SetProperty(PP_TRANSPORTPROPERTY_TCP_RECEIVE_WINDOW, | |
| 195 pp::Var(65536)), PP_OK); | |
| 196 ASSERT_EQ(transport1_->SetProperty(PP_TRANSPORTPROPERTY_TCP_RECEIVE_WINDOW, | |
| 197 pp::Var(10000000)), PP_ERROR_BADARGUMENT); | |
| 198 | |
| 199 ASSERT_EQ(transport1_->SetProperty(PP_TRANSPORTPROPERTY_TCP_SEND_WINDOW, | |
| 200 pp::Var(65536)), PP_OK); | |
| 201 ASSERT_EQ(transport1_->SetProperty(PP_TRANSPORTPROPERTY_TCP_SEND_WINDOW, | |
| 202 pp::Var(10000000)), PP_ERROR_BADARGUMENT); | |
| 203 | |
| 204 ASSERT_EQ(transport1_->SetProperty(PP_TRANSPORTPROPERTY_TCP_NO_DELAY, | |
| 205 pp::Var(true)), PP_OK); | |
| 206 | |
| 207 ASSERT_EQ(transport1_->SetProperty(PP_TRANSPORTPROPERTY_TCP_ACK_DELAY, | |
| 208 pp::Var(10)), PP_OK); | |
| 209 ASSERT_EQ(transport1_->SetProperty(PP_TRANSPORTPROPERTY_TCP_ACK_DELAY, | |
| 210 pp::Var(10000)), PP_ERROR_BADARGUMENT); | |
| 211 | |
| 212 TestCompletionCallback connect_cb(instance_->pp_instance()); | |
| 213 ASSERT_EQ(transport1_->Connect(connect_cb), PP_OK_COMPLETIONPENDING); | |
| 214 | |
| 215 // SetProperty() should fail after we've connected. | |
| 216 ASSERT_EQ(transport1_->SetProperty( | |
| 217 PP_TRANSPORTPROPERTY_STUN_SERVER, | |
| 218 pp::Var("stun.example.com:31323")), PP_ERROR_FAILED); | |
| 219 | |
| 220 Clean(); | |
| 221 ASSERT_EQ(connect_cb.WaitForResult(), PP_ERROR_ABORTED); | |
| 222 | |
| 223 PASS(); | |
| 224 } | |
| 225 | |
| 226 std::string TestTransport::TestConnect() { | |
| 227 ASSERT_SUBTEST_SUCCESS(InitTargets(PP_TRANSPORTTYPE_DATAGRAM)); | |
| 228 ASSERT_SUBTEST_SUCCESS(Connect()); | |
| 229 | |
| 230 Clean(); | |
| 231 | |
| 232 PASS(); | |
| 233 } | |
| 234 | |
| 235 // Creating datagram connection and try sending data over it. Verify | |
| 236 // that at least some packets are received (some packets may be lost). | |
| 237 std::string TestTransport::TestSendDataUdp() { | |
| 238 ASSERT_SUBTEST_SUCCESS(InitTargets(PP_TRANSPORTTYPE_DATAGRAM)); | |
| 239 ASSERT_SUBTEST_SUCCESS(Connect()); | |
| 240 | |
| 241 const int kNumPackets = 100; | |
| 242 const int kSendBufferSize = 1200; | |
| 243 const int kUdpWaitTimeMs = 1000; // 1 second. | |
| 244 | |
| 245 TestCompletionCallback done_cb(instance_->pp_instance()); | |
| 246 StreamReader reader(transport1_, kSendBufferSize * kNumPackets, done_cb); | |
| 247 | |
| 248 std::map<int, std::vector<char> > sent_packets; | |
| 249 for (int i = 0; i < kNumPackets; ++i) { | |
| 250 std::vector<char> send_buffer(kSendBufferSize); | |
| 251 for (size_t j = 0; j < send_buffer.size(); ++j) { | |
| 252 send_buffer[j] = rand() % 256; | |
| 253 } | |
| 254 // Put packet index in the beginning. | |
| 255 memcpy(&send_buffer[0], &i, sizeof(i)); | |
| 256 | |
| 257 TestCompletionCallback send_cb(instance_->pp_instance(), force_async_); | |
| 258 int32_t result = transport2_->Send(&send_buffer[0], send_buffer.size(), | |
| 259 send_cb); | |
| 260 if (force_async_) { | |
| 261 ASSERT_EQ(result, PP_OK_COMPLETIONPENDING); | |
| 262 ASSERT_EQ(send_cb.WaitForResult(), static_cast<int>(send_buffer.size())); | |
| 263 } else { | |
| 264 ASSERT_EQ(result, static_cast<int>(send_buffer.size())); | |
| 265 } | |
| 266 sent_packets[i] = send_buffer; | |
| 267 } | |
| 268 | |
| 269 // Limit waiting time. | |
| 270 TestCompletionCallback timeout_cb(instance_->pp_instance()); | |
| 271 pp::Module::Get()->core()->CallOnMainThread(kUdpWaitTimeMs, timeout_cb); | |
| 272 ASSERT_EQ(timeout_cb.WaitForResult(), PP_OK); | |
| 273 | |
| 274 ASSERT_TRUE(reader.errors().size() == 0); | |
| 275 ASSERT_TRUE(reader.received().size() > 0); | |
| 276 for (std::list<std::vector<char> >::const_iterator it = | |
| 277 reader.received().begin(); it != reader.received().end(); ++it) { | |
| 278 int index; | |
| 279 memcpy(&index, &(*it)[0], sizeof(index)); | |
| 280 ASSERT_TRUE(sent_packets[index] == *it); | |
| 281 } | |
| 282 | |
| 283 Clean(); | |
| 284 | |
| 285 PASS(); | |
| 286 } | |
| 287 | |
| 288 // Creating reliable (TCP-like) connection and try sending data over | |
| 289 // it. Verify that all data is received correctly. | |
| 290 std::string TestTransport::TestSendDataTcp() { | |
| 291 ASSERT_SUBTEST_SUCCESS(InitTargets(PP_TRANSPORTTYPE_STREAM)); | |
| 292 ASSERT_SUBTEST_SUCCESS(Connect()); | |
| 293 | |
| 294 const int kTcpSendSize = 100000; | |
| 295 | |
| 296 TestCompletionCallback done_cb(instance_->pp_instance()); | |
| 297 StreamReader reader(transport1_, kTcpSendSize, done_cb); | |
| 298 | |
| 299 std::vector<char> send_buffer(kTcpSendSize); | |
| 300 for (size_t j = 0; j < send_buffer.size(); ++j) { | |
| 301 send_buffer[j] = rand() % 256; | |
| 302 } | |
| 303 | |
| 304 int pos = 0; | |
| 305 while (pos < static_cast<int>(send_buffer.size())) { | |
| 306 TestCompletionCallback send_cb(instance_->pp_instance(), force_async_); | |
| 307 int result = transport2_->Send( | |
| 308 &send_buffer[0] + pos, send_buffer.size() - pos, send_cb); | |
| 309 if (force_async_) | |
| 310 ASSERT_EQ(result, PP_OK_COMPLETIONPENDING); | |
| 311 if (result == PP_OK_COMPLETIONPENDING) | |
| 312 result = send_cb.WaitForResult(); | |
| 313 ASSERT_TRUE(result > 0); | |
| 314 pos += result; | |
| 315 } | |
| 316 | |
| 317 ASSERT_EQ(done_cb.WaitForResult(), PP_OK); | |
| 318 | |
| 319 ASSERT_TRUE(reader.errors().size() == 0); | |
| 320 | |
| 321 std::vector<char> received_data; | |
| 322 for (std::list<std::vector<char> >::const_iterator it = | |
| 323 reader.received().begin(); it != reader.received().end(); ++it) { | |
| 324 received_data.insert(received_data.end(), it->begin(), it->end()); | |
| 325 } | |
| 326 ASSERT_EQ(send_buffer, received_data); | |
| 327 | |
| 328 Clean(); | |
| 329 | |
| 330 PASS(); | |
| 331 } | |
| 332 | |
| 333 std::string TestTransport::TestConnectAndCloseUdp() { | |
| 334 ASSERT_SUBTEST_SUCCESS(InitTargets(PP_TRANSPORTTYPE_DATAGRAM)); | |
| 335 ASSERT_SUBTEST_SUCCESS(Connect()); | |
| 336 | |
| 337 std::vector<char> recv_buffer(kReadBufferSize); | |
| 338 TestCompletionCallback recv_cb(instance_->pp_instance()); | |
| 339 ASSERT_EQ( | |
| 340 transport1_->Recv(&recv_buffer[0], recv_buffer.size(), recv_cb), | |
| 341 PP_OK_COMPLETIONPENDING); | |
| 342 | |
| 343 // Close the transport and verify that callback is aborted. | |
| 344 ASSERT_EQ(transport1_->Close(), PP_OK); | |
| 345 | |
| 346 ASSERT_EQ(recv_cb.run_count(), 1); | |
| 347 ASSERT_EQ(recv_cb.result(), PP_ERROR_ABORTED); | |
| 348 | |
| 349 Clean(); | |
| 350 | |
| 351 PASS(); | |
| 352 } | |
| 353 | |
| 354 std::string TestTransport::TestConnectAndCloseTcp() { | |
| 355 ASSERT_SUBTEST_SUCCESS(InitTargets(PP_TRANSPORTTYPE_STREAM)); | |
| 356 ASSERT_SUBTEST_SUCCESS(Connect()); | |
| 357 | |
| 358 std::vector<char> recv_buffer(kReadBufferSize); | |
| 359 TestCompletionCallback recv_cb(instance_->pp_instance()); | |
| 360 ASSERT_EQ( | |
| 361 transport1_->Recv(&recv_buffer[0], recv_buffer.size(), recv_cb), | |
| 362 PP_OK_COMPLETIONPENDING); | |
| 363 | |
| 364 // Close the transport and verify that callback is aborted. | |
| 365 ASSERT_EQ(transport1_->Close(), PP_OK); | |
| 366 | |
| 367 ASSERT_EQ(recv_cb.run_count(), 1); | |
| 368 ASSERT_EQ(recv_cb.result(), PP_ERROR_ABORTED); | |
| 369 | |
| 370 Clean(); | |
| 371 | |
| 372 PASS(); | |
| 373 } | |
| OLD | NEW |