media/mtransport/test/transport_unittests.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set ts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 // Original author: ekr@rtfm.com
michael@0 8
michael@0 9 #include <iostream>
michael@0 10 #include <string>
michael@0 11 #include <map>
michael@0 12
michael@0 13 #include "sigslot.h"
michael@0 14
michael@0 15 #include "logging.h"
michael@0 16 #include "nspr.h"
michael@0 17 #include "nss.h"
michael@0 18 #include "ssl.h"
michael@0 19
michael@0 20 #include "nsThreadUtils.h"
michael@0 21 #include "nsXPCOM.h"
michael@0 22
michael@0 23 #include "dtlsidentity.h"
michael@0 24 #include "nricectx.h"
michael@0 25 #include "nricemediastream.h"
michael@0 26 #include "transportflow.h"
michael@0 27 #include "transportlayer.h"
michael@0 28 #include "transportlayerdtls.h"
michael@0 29 #include "transportlayerice.h"
michael@0 30 #include "transportlayerlog.h"
michael@0 31 #include "transportlayerloopback.h"
michael@0 32
michael@0 33 #include "mtransport_test_utils.h"
michael@0 34 #include "runnable_utils.h"
michael@0 35
michael@0 36 #define GTEST_HAS_RTTI 0
michael@0 37 #include "gtest/gtest.h"
michael@0 38 #include "gtest_utils.h"
michael@0 39
michael@0 40 using namespace mozilla;
michael@0 41 MOZ_MTLOG_MODULE("mtransport")
michael@0 42
michael@0 43 MtransportTestUtils *test_utils;
michael@0 44
michael@0 45 // Layer class which can't be initialized.
michael@0 46 class TransportLayerDummy : public TransportLayer {
michael@0 47 public:
michael@0 48 TransportLayerDummy(bool allow_init, bool *destroyed)
michael@0 49 : allow_init_(allow_init),
michael@0 50 destroyed_(destroyed) {
michael@0 51 *destroyed_ = false;
michael@0 52 }
michael@0 53
michael@0 54 virtual ~TransportLayerDummy() {
michael@0 55 *destroyed_ = true;
michael@0 56 }
michael@0 57
michael@0 58 virtual nsresult InitInternal() {
michael@0 59 return allow_init_ ? NS_OK : NS_ERROR_FAILURE;
michael@0 60 }
michael@0 61
michael@0 62 virtual TransportResult SendPacket(const unsigned char *data, size_t len) {
michael@0 63 MOZ_CRASH(); // Should never be called.
michael@0 64 return 0;
michael@0 65 }
michael@0 66
michael@0 67 TRANSPORT_LAYER_ID("lossy")
michael@0 68
michael@0 69 private:
michael@0 70 bool allow_init_;
michael@0 71 bool *destroyed_;
michael@0 72 };
michael@0 73
michael@0 74 // Class to simulate various kinds of network lossage
michael@0 75 class TransportLayerLossy : public TransportLayer {
michael@0 76 public:
michael@0 77 TransportLayerLossy() : loss_mask_(0), packet_(0) {}
michael@0 78 ~TransportLayerLossy () {}
michael@0 79
michael@0 80 virtual TransportResult SendPacket(const unsigned char *data, size_t len) {
michael@0 81 MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "SendPacket(" << len << ")");
michael@0 82
michael@0 83 if (loss_mask_ & (1 << (packet_ % 32))) {
michael@0 84 MOZ_MTLOG(ML_NOTICE, "Dropping packet");
michael@0 85 ++packet_;
michael@0 86 return len;
michael@0 87 }
michael@0 88
michael@0 89 ++packet_;
michael@0 90
michael@0 91 return downward_->SendPacket(data, len);
michael@0 92 }
michael@0 93
michael@0 94 void SetLoss(uint32_t packet) {
michael@0 95 loss_mask_ |= (1 << (packet & 32));
michael@0 96 }
michael@0 97
michael@0 98 void StateChange(TransportLayer *layer, State state) {
michael@0 99 TL_SET_STATE(state);
michael@0 100 }
michael@0 101
michael@0 102 void PacketReceived(TransportLayer *layer, const unsigned char *data,
michael@0 103 size_t len) {
michael@0 104 SignalPacketReceived(this, data, len);
michael@0 105 }
michael@0 106
michael@0 107 TRANSPORT_LAYER_ID("lossy")
michael@0 108
michael@0 109 protected:
michael@0 110 virtual void WasInserted() {
michael@0 111 downward_->SignalPacketReceived.
michael@0 112 connect(this,
michael@0 113 &TransportLayerLossy::PacketReceived);
michael@0 114 downward_->SignalStateChange.
michael@0 115 connect(this,
michael@0 116 &TransportLayerLossy::StateChange);
michael@0 117
michael@0 118 TL_SET_STATE(downward_->state());
michael@0 119 }
michael@0 120
michael@0 121 private:
michael@0 122 uint32_t loss_mask_;
michael@0 123 uint32_t packet_;
michael@0 124 };
michael@0 125
michael@0 126 namespace {
michael@0 127 class TransportTestPeer : public sigslot::has_slots<> {
michael@0 128 public:
michael@0 129 TransportTestPeer(nsCOMPtr<nsIEventTarget> target, std::string name)
michael@0 130 : name_(name), target_(target),
michael@0 131 received_(0), flow_(new TransportFlow(name)),
michael@0 132 loopback_(new TransportLayerLoopback()),
michael@0 133 logging_(new TransportLayerLogging()),
michael@0 134 lossy_(new TransportLayerLossy()),
michael@0 135 dtls_(new TransportLayerDtls()),
michael@0 136 identity_(DtlsIdentity::Generate()),
michael@0 137 ice_ctx_(NrIceCtx::Create(name,
michael@0 138 name == "P2" ?
michael@0 139 TransportLayerDtls::CLIENT :
michael@0 140 TransportLayerDtls::SERVER)),
michael@0 141 streams_(), candidates_(),
michael@0 142 peer_(nullptr),
michael@0 143 gathering_complete_(false)
michael@0 144 {
michael@0 145 std::vector<NrIceStunServer> stun_servers;
michael@0 146 ScopedDeletePtr<NrIceStunServer> server(NrIceStunServer::Create(
michael@0 147 std::string((char *)"216.93.246.14"), 3478));
michael@0 148 stun_servers.push_back(*server);
michael@0 149 EXPECT_TRUE(NS_SUCCEEDED(ice_ctx_->SetStunServers(stun_servers)));
michael@0 150
michael@0 151 dtls_->SetIdentity(identity_);
michael@0 152 dtls_->SetRole(name == "P2" ?
michael@0 153 TransportLayerDtls::CLIENT :
michael@0 154 TransportLayerDtls::SERVER);
michael@0 155
michael@0 156 nsresult res = identity_->ComputeFingerprint("sha-1",
michael@0 157 fingerprint_,
michael@0 158 sizeof(fingerprint_),
michael@0 159 &fingerprint_len_);
michael@0 160 EXPECT_TRUE(NS_SUCCEEDED(res));
michael@0 161 EXPECT_EQ(20u, fingerprint_len_);
michael@0 162 }
michael@0 163
michael@0 164 ~TransportTestPeer() {
michael@0 165 test_utils->sts_target()->Dispatch(
michael@0 166 WrapRunnable(this, &TransportTestPeer::DestroyFlow),
michael@0 167 NS_DISPATCH_SYNC);
michael@0 168 }
michael@0 169
michael@0 170
michael@0 171 void DestroyFlow() {
michael@0 172 if (flow_) {
michael@0 173 loopback_->Disconnect();
michael@0 174 flow_ = nullptr;
michael@0 175 }
michael@0 176 ice_ctx_ = nullptr;
michael@0 177 }
michael@0 178
michael@0 179 void DisconnectDestroyFlow() {
michael@0 180 loopback_->Disconnect();
michael@0 181 disconnect_all(); // Disconnect from the signals;
michael@0 182 flow_ = nullptr;
michael@0 183 }
michael@0 184
michael@0 185 void SetDtlsAllowAll() {
michael@0 186 nsresult res = dtls_->SetVerificationAllowAll();
michael@0 187 ASSERT_TRUE(NS_SUCCEEDED(res));
michael@0 188 }
michael@0 189
michael@0 190 void SetDtlsPeer(TransportTestPeer *peer, int digests, unsigned int damage) {
michael@0 191 unsigned int mask = 1;
michael@0 192
michael@0 193 for (int i=0; i<digests; i++) {
michael@0 194 unsigned char fingerprint_to_set[TransportLayerDtls::kMaxDigestLength];
michael@0 195
michael@0 196 memcpy(fingerprint_to_set,
michael@0 197 peer->fingerprint_,
michael@0 198 peer->fingerprint_len_);
michael@0 199 if (damage & mask)
michael@0 200 fingerprint_to_set[0]++;
michael@0 201
michael@0 202 nsresult res = dtls_->SetVerificationDigest(
michael@0 203 "sha-1",
michael@0 204 fingerprint_to_set,
michael@0 205 peer->fingerprint_len_);
michael@0 206
michael@0 207 ASSERT_TRUE(NS_SUCCEEDED(res));
michael@0 208
michael@0 209 mask <<= 1;
michael@0 210 }
michael@0 211 }
michael@0 212
michael@0 213
michael@0 214 void ConnectSocket_s(TransportTestPeer *peer) {
michael@0 215 nsresult res;
michael@0 216 res = loopback_->Init();
michael@0 217 ASSERT_EQ((nsresult)NS_OK, res);
michael@0 218
michael@0 219 loopback_->Connect(peer->loopback_);
michael@0 220
michael@0 221 ASSERT_EQ((nsresult)NS_OK, flow_->PushLayer(loopback_));
michael@0 222 ASSERT_EQ((nsresult)NS_OK, flow_->PushLayer(logging_));
michael@0 223 ASSERT_EQ((nsresult)NS_OK, flow_->PushLayer(lossy_));
michael@0 224 ASSERT_EQ((nsresult)NS_OK, flow_->PushLayer(dtls_));
michael@0 225
michael@0 226 flow_->SignalPacketReceived.connect(this, &TransportTestPeer::PacketReceived);
michael@0 227 }
michael@0 228
michael@0 229 void ConnectSocket(TransportTestPeer *peer) {
michael@0 230 RUN_ON_THREAD(test_utils->sts_target(),
michael@0 231 WrapRunnable(this, & TransportTestPeer::ConnectSocket_s,
michael@0 232 peer),
michael@0 233 NS_DISPATCH_SYNC);
michael@0 234 }
michael@0 235
michael@0 236 void InitIce() {
michael@0 237 nsresult res;
michael@0 238
michael@0 239 // Attach our slots
michael@0 240 ice_ctx_->SignalGatheringStateChange.
michael@0 241 connect(this, &TransportTestPeer::GatheringStateChange);
michael@0 242
michael@0 243 char name[100];
michael@0 244 snprintf(name, sizeof(name), "%s:stream%d", name_.c_str(),
michael@0 245 (int)streams_.size());
michael@0 246
michael@0 247 // Create the media stream
michael@0 248 mozilla::RefPtr<NrIceMediaStream> stream =
michael@0 249 ice_ctx_->CreateStream(static_cast<char *>(name), 1);
michael@0 250 ASSERT_TRUE(stream != nullptr);
michael@0 251 streams_.push_back(stream);
michael@0 252
michael@0 253 // Listen for candidates
michael@0 254 stream->SignalCandidate.
michael@0 255 connect(this, &TransportTestPeer::GotCandidate);
michael@0 256
michael@0 257 // Create the transport layer
michael@0 258 ice_ = new TransportLayerIce(name, ice_ctx_, stream, 1);
michael@0 259
michael@0 260 // Assemble the stack
michael@0 261 nsAutoPtr<std::queue<mozilla::TransportLayer *> > layers(
michael@0 262 new std::queue<mozilla::TransportLayer *>);
michael@0 263 layers->push(ice_);
michael@0 264 layers->push(dtls_);
michael@0 265
michael@0 266 test_utils->sts_target()->Dispatch(
michael@0 267 WrapRunnableRet(flow_, &TransportFlow::PushLayers, layers, &res),
michael@0 268 NS_DISPATCH_SYNC);
michael@0 269
michael@0 270 ASSERT_EQ((nsresult)NS_OK, res);
michael@0 271
michael@0 272 // Listen for media events
michael@0 273 flow_->SignalPacketReceived.connect(this, &TransportTestPeer::PacketReceived);
michael@0 274 flow_->SignalStateChange.connect(this, &TransportTestPeer::StateChanged);
michael@0 275
michael@0 276 // Start gathering
michael@0 277 test_utils->sts_target()->Dispatch(
michael@0 278 WrapRunnableRet(ice_ctx_, &NrIceCtx::StartGathering, &res),
michael@0 279 NS_DISPATCH_SYNC);
michael@0 280 ASSERT_TRUE(NS_SUCCEEDED(res));
michael@0 281 }
michael@0 282
michael@0 283 void ConnectIce(TransportTestPeer *peer) {
michael@0 284 peer_ = peer;
michael@0 285
michael@0 286 // If gathering is already complete, push the candidates over
michael@0 287 if (gathering_complete_)
michael@0 288 GatheringComplete();
michael@0 289 }
michael@0 290
michael@0 291 // New candidate
michael@0 292 void GotCandidate(NrIceMediaStream *stream, const std::string &candidate) {
michael@0 293 std::cerr << "Got candidate " << candidate << std::endl;
michael@0 294 candidates_[stream->name()].push_back(candidate);
michael@0 295 }
michael@0 296
michael@0 297 void GatheringStateChange(NrIceCtx* ctx,
michael@0 298 NrIceCtx::GatheringState state) {
michael@0 299 (void)ctx;
michael@0 300 if (state == NrIceCtx::ICE_CTX_GATHER_COMPLETE) {
michael@0 301 GatheringComplete();
michael@0 302 }
michael@0 303 }
michael@0 304
michael@0 305 // Gathering complete, so send our candidates and start
michael@0 306 // connecting on the other peer.
michael@0 307 void GatheringComplete() {
michael@0 308 nsresult res;
michael@0 309
michael@0 310 // Don't send to the other side
michael@0 311 if (!peer_) {
michael@0 312 gathering_complete_ = true;
michael@0 313 return;
michael@0 314 }
michael@0 315
michael@0 316 // First send attributes
michael@0 317 test_utils->sts_target()->Dispatch(
michael@0 318 WrapRunnableRet(peer_->ice_ctx_,
michael@0 319 &NrIceCtx::ParseGlobalAttributes,
michael@0 320 ice_ctx_->GetGlobalAttributes(), &res),
michael@0 321 NS_DISPATCH_SYNC);
michael@0 322 ASSERT_TRUE(NS_SUCCEEDED(res));
michael@0 323
michael@0 324 for (size_t i=0; i<streams_.size(); ++i) {
michael@0 325 test_utils->sts_target()->Dispatch(
michael@0 326 WrapRunnableRet(peer_->streams_[i], &NrIceMediaStream::ParseAttributes,
michael@0 327 candidates_[streams_[i]->name()], &res), NS_DISPATCH_SYNC);
michael@0 328
michael@0 329 ASSERT_TRUE(NS_SUCCEEDED(res));
michael@0 330 }
michael@0 331
michael@0 332 // Start checks on the other peer.
michael@0 333 test_utils->sts_target()->Dispatch(
michael@0 334 WrapRunnableRet(peer_->ice_ctx_, &NrIceCtx::StartChecks, &res),
michael@0 335 NS_DISPATCH_SYNC);
michael@0 336 ASSERT_TRUE(NS_SUCCEEDED(res));
michael@0 337 }
michael@0 338
michael@0 339 TransportResult SendPacket(const unsigned char* data, size_t len) {
michael@0 340 TransportResult ret;
michael@0 341 test_utils->sts_target()->Dispatch(
michael@0 342 WrapRunnableRet(flow_, &TransportFlow::SendPacket, data, len, &ret),
michael@0 343 NS_DISPATCH_SYNC);
michael@0 344
michael@0 345 return ret;
michael@0 346 }
michael@0 347
michael@0 348
michael@0 349 void StateChanged(TransportFlow *flow, TransportLayer::State state) {
michael@0 350 if (state == TransportLayer::TS_OPEN) {
michael@0 351 std::cerr << "Now connected" << std::endl;
michael@0 352 }
michael@0 353 }
michael@0 354
michael@0 355 void PacketReceived(TransportFlow * flow, const unsigned char* data,
michael@0 356 size_t len) {
michael@0 357 std::cerr << "Received " << len << " bytes" << std::endl;
michael@0 358 ++received_;
michael@0 359 }
michael@0 360
michael@0 361 void SetLoss(uint32_t loss) {
michael@0 362 lossy_->SetLoss(loss);
michael@0 363 }
michael@0 364
michael@0 365 TransportLayer::State state() {
michael@0 366 TransportLayer::State tstate;
michael@0 367
michael@0 368 RUN_ON_THREAD(test_utils->sts_target(),
michael@0 369 WrapRunnableRet(flow_, &TransportFlow::state, &tstate),
michael@0 370 NS_DISPATCH_SYNC);
michael@0 371
michael@0 372 return tstate;
michael@0 373 }
michael@0 374
michael@0 375 bool connected() {
michael@0 376 return state() == TransportLayer::TS_OPEN;
michael@0 377 }
michael@0 378
michael@0 379 bool failed() {
michael@0 380 return state() == TransportLayer::TS_ERROR;
michael@0 381 }
michael@0 382
michael@0 383 size_t received() { return received_; }
michael@0 384
michael@0 385 private:
michael@0 386 std::string name_;
michael@0 387 nsCOMPtr<nsIEventTarget> target_;
michael@0 388 size_t received_;
michael@0 389 mozilla::RefPtr<TransportFlow> flow_;
michael@0 390 TransportLayerLoopback *loopback_;
michael@0 391 TransportLayerLogging *logging_;
michael@0 392 TransportLayerLossy *lossy_;
michael@0 393 TransportLayerDtls *dtls_;
michael@0 394 TransportLayerIce *ice_;
michael@0 395 mozilla::RefPtr<DtlsIdentity> identity_;
michael@0 396 mozilla::RefPtr<NrIceCtx> ice_ctx_;
michael@0 397 std::vector<mozilla::RefPtr<NrIceMediaStream> > streams_;
michael@0 398 std::map<std::string, std::vector<std::string> > candidates_;
michael@0 399 TransportTestPeer *peer_;
michael@0 400 bool gathering_complete_;
michael@0 401 unsigned char fingerprint_[TransportLayerDtls::kMaxDigestLength];
michael@0 402 size_t fingerprint_len_;
michael@0 403 };
michael@0 404
michael@0 405
michael@0 406 class TransportTest : public ::testing::Test {
michael@0 407 public:
michael@0 408 TransportTest() {
michael@0 409 fds_[0] = nullptr;
michael@0 410 fds_[1] = nullptr;
michael@0 411 }
michael@0 412
michael@0 413 ~TransportTest() {
michael@0 414 delete p1_;
michael@0 415 delete p2_;
michael@0 416
michael@0 417 // Can't detach these
michael@0 418 // PR_Close(fds_[0]);
michael@0 419 // PR_Close(fds_[1]);
michael@0 420 }
michael@0 421
michael@0 422 void DestroyPeerFlows() {
michael@0 423 p1_->DisconnectDestroyFlow();
michael@0 424 p2_->DisconnectDestroyFlow();
michael@0 425 }
michael@0 426
michael@0 427 void SetUp() {
michael@0 428 nsresult rv;
michael@0 429 target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
michael@0 430 ASSERT_TRUE(NS_SUCCEEDED(rv));
michael@0 431
michael@0 432 p1_ = new TransportTestPeer(target_, "P1");
michael@0 433 p2_ = new TransportTestPeer(target_, "P2");
michael@0 434 }
michael@0 435
michael@0 436 void SetDtlsPeer(int digests = 1, unsigned int damage = 0) {
michael@0 437 p1_->SetDtlsPeer(p2_, digests, damage);
michael@0 438 p2_->SetDtlsPeer(p1_, digests, damage);
michael@0 439 }
michael@0 440
michael@0 441 void SetDtlsAllowAll() {
michael@0 442 p1_->SetDtlsAllowAll();
michael@0 443 p2_->SetDtlsAllowAll();
michael@0 444 }
michael@0 445
michael@0 446 void ConnectSocket() {
michael@0 447 test_utils->sts_target()->Dispatch(
michael@0 448 WrapRunnable(p1_, &TransportTestPeer::ConnectSocket, p2_),
michael@0 449 NS_DISPATCH_SYNC);
michael@0 450 test_utils->sts_target()->Dispatch(
michael@0 451 WrapRunnable(p2_, &TransportTestPeer::ConnectSocket, p1_),
michael@0 452 NS_DISPATCH_SYNC);
michael@0 453
michael@0 454 ASSERT_TRUE_WAIT(p1_->connected(), 10000);
michael@0 455 ASSERT_TRUE_WAIT(p2_->connected(), 10000);
michael@0 456 }
michael@0 457
michael@0 458 void ConnectSocketExpectFail() {
michael@0 459 test_utils->sts_target()->Dispatch(
michael@0 460 WrapRunnable(p1_, &TransportTestPeer::ConnectSocket, p2_),
michael@0 461 NS_DISPATCH_SYNC);
michael@0 462 test_utils->sts_target()->Dispatch(
michael@0 463 WrapRunnable(p2_, &TransportTestPeer::ConnectSocket, p1_),
michael@0 464 NS_DISPATCH_SYNC);
michael@0 465 ASSERT_TRUE_WAIT(p1_->failed(), 10000);
michael@0 466 ASSERT_TRUE_WAIT(p2_->failed(), 10000);
michael@0 467 }
michael@0 468
michael@0 469 void InitIce() {
michael@0 470 p1_->InitIce();
michael@0 471 p2_->InitIce();
michael@0 472 }
michael@0 473
michael@0 474 void ConnectIce() {
michael@0 475 p1_->InitIce();
michael@0 476 p2_->InitIce();
michael@0 477 p1_->ConnectIce(p2_);
michael@0 478 p2_->ConnectIce(p1_);
michael@0 479 ASSERT_TRUE_WAIT(p1_->connected(), 10000);
michael@0 480 ASSERT_TRUE_WAIT(p2_->connected(), 10000);
michael@0 481 }
michael@0 482
michael@0 483 void TransferTest(size_t count) {
michael@0 484 unsigned char buf[1000];
michael@0 485
michael@0 486 for (size_t i= 0; i<count; ++i) {
michael@0 487 memset(buf, count & 0xff, sizeof(buf));
michael@0 488 TransportResult rv = p1_->SendPacket(buf, sizeof(buf));
michael@0 489 ASSERT_TRUE(rv > 0);
michael@0 490 }
michael@0 491
michael@0 492 std::cerr << "Received == " << p2_->received() << std::endl;
michael@0 493 ASSERT_TRUE_WAIT(count == p2_->received(), 10000);
michael@0 494 }
michael@0 495
michael@0 496 protected:
michael@0 497 PRFileDesc *fds_[2];
michael@0 498 TransportTestPeer *p1_;
michael@0 499 TransportTestPeer *p2_;
michael@0 500 nsCOMPtr<nsIEventTarget> target_;
michael@0 501 };
michael@0 502
michael@0 503
michael@0 504 TEST_F(TransportTest, TestNoDtlsVerificationSettings) {
michael@0 505 ConnectSocketExpectFail();
michael@0 506 }
michael@0 507
michael@0 508 TEST_F(TransportTest, TestConnect) {
michael@0 509 SetDtlsPeer();
michael@0 510 ConnectSocket();
michael@0 511 }
michael@0 512
michael@0 513 TEST_F(TransportTest, TestConnectDestroyFlowsMainThread) {
michael@0 514 SetDtlsPeer();
michael@0 515 ConnectSocket();
michael@0 516 DestroyPeerFlows();
michael@0 517 }
michael@0 518
michael@0 519 TEST_F(TransportTest, TestConnectAllowAll) {
michael@0 520 SetDtlsAllowAll();
michael@0 521 ConnectSocket();
michael@0 522 }
michael@0 523
michael@0 524 TEST_F(TransportTest, TestConnectBadDigest) {
michael@0 525 SetDtlsPeer(1, 1);
michael@0 526
michael@0 527 ConnectSocketExpectFail();
michael@0 528 }
michael@0 529
michael@0 530 TEST_F(TransportTest, TestConnectTwoDigests) {
michael@0 531 SetDtlsPeer(2, 0);
michael@0 532
michael@0 533 ConnectSocket();
michael@0 534 }
michael@0 535
michael@0 536 TEST_F(TransportTest, TestConnectTwoDigestsFirstBad) {
michael@0 537 SetDtlsPeer(2, 1);
michael@0 538
michael@0 539 ConnectSocketExpectFail();
michael@0 540 }
michael@0 541
michael@0 542 TEST_F(TransportTest, TestConnectTwoDigestsSecondBad) {
michael@0 543 SetDtlsPeer(2, 2);
michael@0 544
michael@0 545 ConnectSocketExpectFail();
michael@0 546 }
michael@0 547
michael@0 548 TEST_F(TransportTest, TestConnectTwoDigestsBothBad) {
michael@0 549 SetDtlsPeer(2, 3);
michael@0 550
michael@0 551 ConnectSocketExpectFail();
michael@0 552 }
michael@0 553
michael@0 554 TEST_F(TransportTest, TestTransfer) {
michael@0 555 SetDtlsPeer();
michael@0 556 ConnectSocket();
michael@0 557 TransferTest(1);
michael@0 558 }
michael@0 559
michael@0 560 TEST_F(TransportTest, TestConnectLoseFirst) {
michael@0 561 SetDtlsPeer();
michael@0 562 p1_->SetLoss(0);
michael@0 563 ConnectSocket();
michael@0 564 TransferTest(1);
michael@0 565 }
michael@0 566
michael@0 567 TEST_F(TransportTest, TestConnectIce) {
michael@0 568 SetDtlsPeer();
michael@0 569 ConnectIce();
michael@0 570 }
michael@0 571
michael@0 572 TEST_F(TransportTest, TestTransferIce) {
michael@0 573 SetDtlsPeer();
michael@0 574 ConnectIce();
michael@0 575 TransferTest(1);
michael@0 576 }
michael@0 577
michael@0 578 TEST(PushTests, LayerFail) {
michael@0 579 TransportFlow flow;
michael@0 580 nsresult rv;
michael@0 581 bool destroyed1, destroyed2;
michael@0 582
michael@0 583 rv = flow.PushLayer(new TransportLayerDummy(true, &destroyed1));
michael@0 584 ASSERT_TRUE(NS_SUCCEEDED(rv));
michael@0 585
michael@0 586 rv = flow.PushLayer(new TransportLayerDummy(false, &destroyed2));
michael@0 587 ASSERT_TRUE(NS_FAILED(rv));
michael@0 588
michael@0 589 ASSERT_EQ(TransportLayer::TS_ERROR, flow.state());
michael@0 590 ASSERT_EQ(true, destroyed1);
michael@0 591 ASSERT_EQ(true, destroyed2);
michael@0 592
michael@0 593 rv = flow.PushLayer(new TransportLayerDummy(true, &destroyed1));
michael@0 594 ASSERT_TRUE(NS_FAILED(rv));
michael@0 595 ASSERT_EQ(true, destroyed1);
michael@0 596 }
michael@0 597
michael@0 598
michael@0 599 TEST(PushTests, LayersFail) {
michael@0 600 TransportFlow flow;
michael@0 601 nsresult rv;
michael@0 602 bool destroyed1, destroyed2, destroyed3;
michael@0 603
michael@0 604 rv = flow.PushLayer(new TransportLayerDummy(true, &destroyed1));
michael@0 605 ASSERT_TRUE(NS_SUCCEEDED(rv));
michael@0 606
michael@0 607 nsAutoPtr<std::queue<TransportLayer *> > layers(
michael@0 608 new std::queue<TransportLayer *>());
michael@0 609
michael@0 610 layers->push(new TransportLayerDummy(true, &destroyed2));
michael@0 611 layers->push(new TransportLayerDummy(false, &destroyed3));
michael@0 612
michael@0 613 rv = flow.PushLayers(layers);
michael@0 614 ASSERT_TRUE(NS_FAILED(rv));
michael@0 615
michael@0 616 ASSERT_EQ(TransportLayer::TS_ERROR, flow.state());
michael@0 617 ASSERT_EQ(true, destroyed1);
michael@0 618 ASSERT_EQ(true, destroyed2);
michael@0 619 ASSERT_EQ(true, destroyed3);
michael@0 620
michael@0 621 layers = new std::queue<TransportLayer *>();
michael@0 622 layers->push(new TransportLayerDummy(true, &destroyed2));
michael@0 623 layers->push(new TransportLayerDummy(true, &destroyed3));
michael@0 624 rv = flow.PushLayers(layers);
michael@0 625
michael@0 626 ASSERT_TRUE(NS_FAILED(rv));
michael@0 627 ASSERT_EQ(true, destroyed2);
michael@0 628 ASSERT_EQ(true, destroyed3);
michael@0 629 }
michael@0 630
michael@0 631 } // end namespace
michael@0 632
michael@0 633 int main(int argc, char **argv)
michael@0 634 {
michael@0 635 test_utils = new MtransportTestUtils();
michael@0 636
michael@0 637 NSS_NoDB_Init(nullptr);
michael@0 638 NSS_SetDomesticPolicy();
michael@0 639 // Start the tests
michael@0 640 ::testing::InitGoogleTest(&argc, argv);
michael@0 641
michael@0 642 int rv = RUN_ALL_TESTS();
michael@0 643 delete test_utils;
michael@0 644 return rv;
michael@0 645 }

mercurial