media/mtransport/test/transport_unittests.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/mtransport/test/transport_unittests.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,645 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=2 et sw=2 tw=80: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +// Original author: ekr@rtfm.com
    1.11 +
    1.12 +#include <iostream>
    1.13 +#include <string>
    1.14 +#include <map>
    1.15 +
    1.16 +#include "sigslot.h"
    1.17 +
    1.18 +#include "logging.h"
    1.19 +#include "nspr.h"
    1.20 +#include "nss.h"
    1.21 +#include "ssl.h"
    1.22 +
    1.23 +#include "nsThreadUtils.h"
    1.24 +#include "nsXPCOM.h"
    1.25 +
    1.26 +#include "dtlsidentity.h"
    1.27 +#include "nricectx.h"
    1.28 +#include "nricemediastream.h"
    1.29 +#include "transportflow.h"
    1.30 +#include "transportlayer.h"
    1.31 +#include "transportlayerdtls.h"
    1.32 +#include "transportlayerice.h"
    1.33 +#include "transportlayerlog.h"
    1.34 +#include "transportlayerloopback.h"
    1.35 +
    1.36 +#include "mtransport_test_utils.h"
    1.37 +#include "runnable_utils.h"
    1.38 +
    1.39 +#define GTEST_HAS_RTTI 0
    1.40 +#include "gtest/gtest.h"
    1.41 +#include "gtest_utils.h"
    1.42 +
    1.43 +using namespace mozilla;
    1.44 +MOZ_MTLOG_MODULE("mtransport")
    1.45 +
    1.46 +MtransportTestUtils *test_utils;
    1.47 +
    1.48 +// Layer class which can't be initialized.
    1.49 +class TransportLayerDummy : public TransportLayer {
    1.50 + public:
    1.51 +  TransportLayerDummy(bool allow_init, bool *destroyed)
    1.52 +      : allow_init_(allow_init),
    1.53 +        destroyed_(destroyed) {
    1.54 +    *destroyed_ = false;
    1.55 +  }
    1.56 +
    1.57 +  virtual ~TransportLayerDummy() {
    1.58 +    *destroyed_ = true;
    1.59 +  }
    1.60 +
    1.61 +  virtual nsresult InitInternal() {
    1.62 +    return allow_init_ ? NS_OK : NS_ERROR_FAILURE;
    1.63 +  }
    1.64 +
    1.65 +  virtual TransportResult SendPacket(const unsigned char *data, size_t len) {
    1.66 +    MOZ_CRASH();  // Should never be called.
    1.67 +    return 0;
    1.68 +  }
    1.69 +
    1.70 +  TRANSPORT_LAYER_ID("lossy")
    1.71 +
    1.72 + private:
    1.73 +  bool allow_init_;
    1.74 +  bool *destroyed_;
    1.75 +};
    1.76 +
    1.77 +// Class to simulate various kinds of network lossage
    1.78 +class TransportLayerLossy : public TransportLayer {
    1.79 + public:
    1.80 +  TransportLayerLossy() : loss_mask_(0), packet_(0) {}
    1.81 +  ~TransportLayerLossy () {}
    1.82 +
    1.83 +  virtual TransportResult SendPacket(const unsigned char *data, size_t len) {
    1.84 +    MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "SendPacket(" << len << ")");
    1.85 +
    1.86 +    if (loss_mask_ & (1 << (packet_ % 32))) {
    1.87 +      MOZ_MTLOG(ML_NOTICE, "Dropping packet");
    1.88 +      ++packet_;
    1.89 +      return len;
    1.90 +    }
    1.91 +
    1.92 +    ++packet_;
    1.93 +
    1.94 +    return downward_->SendPacket(data, len);
    1.95 +  }
    1.96 +
    1.97 +  void SetLoss(uint32_t packet) {
    1.98 +    loss_mask_ |= (1 << (packet & 32));
    1.99 +  }
   1.100 +
   1.101 +  void StateChange(TransportLayer *layer, State state) {
   1.102 +    TL_SET_STATE(state);
   1.103 +  }
   1.104 +
   1.105 +  void PacketReceived(TransportLayer *layer, const unsigned char *data,
   1.106 +                      size_t len) {
   1.107 +    SignalPacketReceived(this, data, len);
   1.108 +  }
   1.109 +
   1.110 +  TRANSPORT_LAYER_ID("lossy")
   1.111 +
   1.112 + protected:
   1.113 +  virtual void WasInserted() {
   1.114 +    downward_->SignalPacketReceived.
   1.115 +        connect(this,
   1.116 +                &TransportLayerLossy::PacketReceived);
   1.117 +    downward_->SignalStateChange.
   1.118 +        connect(this,
   1.119 +                &TransportLayerLossy::StateChange);
   1.120 +
   1.121 +    TL_SET_STATE(downward_->state());
   1.122 +  }
   1.123 +
   1.124 + private:
   1.125 +  uint32_t loss_mask_;
   1.126 +  uint32_t packet_;
   1.127 +};
   1.128 +
   1.129 +namespace {
   1.130 +class TransportTestPeer : public sigslot::has_slots<> {
   1.131 + public:
   1.132 +  TransportTestPeer(nsCOMPtr<nsIEventTarget> target, std::string name)
   1.133 +      : name_(name), target_(target),
   1.134 +        received_(0), flow_(new TransportFlow(name)),
   1.135 +        loopback_(new TransportLayerLoopback()),
   1.136 +        logging_(new TransportLayerLogging()),
   1.137 +        lossy_(new TransportLayerLossy()),
   1.138 +        dtls_(new TransportLayerDtls()),
   1.139 +        identity_(DtlsIdentity::Generate()),
   1.140 +        ice_ctx_(NrIceCtx::Create(name,
   1.141 +                                  name == "P2" ?
   1.142 +                                  TransportLayerDtls::CLIENT :
   1.143 +                                  TransportLayerDtls::SERVER)),
   1.144 +        streams_(), candidates_(),
   1.145 +        peer_(nullptr),
   1.146 +        gathering_complete_(false)
   1.147 + {
   1.148 +    std::vector<NrIceStunServer> stun_servers;
   1.149 +    ScopedDeletePtr<NrIceStunServer> server(NrIceStunServer::Create(
   1.150 +        std::string((char *)"216.93.246.14"), 3478));
   1.151 +    stun_servers.push_back(*server);
   1.152 +    EXPECT_TRUE(NS_SUCCEEDED(ice_ctx_->SetStunServers(stun_servers)));
   1.153 +
   1.154 +    dtls_->SetIdentity(identity_);
   1.155 +    dtls_->SetRole(name == "P2" ?
   1.156 +                   TransportLayerDtls::CLIENT :
   1.157 +                   TransportLayerDtls::SERVER);
   1.158 +
   1.159 +    nsresult res = identity_->ComputeFingerprint("sha-1",
   1.160 +                                             fingerprint_,
   1.161 +                                             sizeof(fingerprint_),
   1.162 +                                             &fingerprint_len_);
   1.163 +    EXPECT_TRUE(NS_SUCCEEDED(res));
   1.164 +    EXPECT_EQ(20u, fingerprint_len_);
   1.165 +  }
   1.166 +
   1.167 +  ~TransportTestPeer() {
   1.168 +    test_utils->sts_target()->Dispatch(
   1.169 +      WrapRunnable(this, &TransportTestPeer::DestroyFlow),
   1.170 +      NS_DISPATCH_SYNC);
   1.171 +  }
   1.172 +
   1.173 +
   1.174 +  void DestroyFlow() {
   1.175 +    if (flow_) {
   1.176 +      loopback_->Disconnect();
   1.177 +      flow_ = nullptr;
   1.178 +    }
   1.179 +    ice_ctx_ = nullptr;
   1.180 +  }
   1.181 +
   1.182 +  void DisconnectDestroyFlow() {
   1.183 +    loopback_->Disconnect();
   1.184 +    disconnect_all();  // Disconnect from the signals;
   1.185 +     flow_ = nullptr;
   1.186 +  }
   1.187 +
   1.188 +  void SetDtlsAllowAll() {
   1.189 +    nsresult res = dtls_->SetVerificationAllowAll();
   1.190 +    ASSERT_TRUE(NS_SUCCEEDED(res));
   1.191 +  }
   1.192 +
   1.193 +  void SetDtlsPeer(TransportTestPeer *peer, int digests, unsigned int damage) {
   1.194 +    unsigned int mask = 1;
   1.195 +
   1.196 +    for (int i=0; i<digests; i++) {
   1.197 +      unsigned char fingerprint_to_set[TransportLayerDtls::kMaxDigestLength];
   1.198 +
   1.199 +      memcpy(fingerprint_to_set,
   1.200 +             peer->fingerprint_,
   1.201 +             peer->fingerprint_len_);
   1.202 +      if (damage & mask)
   1.203 +        fingerprint_to_set[0]++;
   1.204 +
   1.205 +      nsresult res = dtls_->SetVerificationDigest(
   1.206 +          "sha-1",
   1.207 +          fingerprint_to_set,
   1.208 +          peer->fingerprint_len_);
   1.209 +
   1.210 +      ASSERT_TRUE(NS_SUCCEEDED(res));
   1.211 +
   1.212 +      mask <<= 1;
   1.213 +    }
   1.214 +  }
   1.215 +
   1.216 +
   1.217 +  void ConnectSocket_s(TransportTestPeer *peer) {
   1.218 +    nsresult res;
   1.219 +    res = loopback_->Init();
   1.220 +    ASSERT_EQ((nsresult)NS_OK, res);
   1.221 +
   1.222 +    loopback_->Connect(peer->loopback_);
   1.223 +
   1.224 +    ASSERT_EQ((nsresult)NS_OK, flow_->PushLayer(loopback_));
   1.225 +    ASSERT_EQ((nsresult)NS_OK, flow_->PushLayer(logging_));
   1.226 +    ASSERT_EQ((nsresult)NS_OK, flow_->PushLayer(lossy_));
   1.227 +    ASSERT_EQ((nsresult)NS_OK, flow_->PushLayer(dtls_));
   1.228 +
   1.229 +    flow_->SignalPacketReceived.connect(this, &TransportTestPeer::PacketReceived);
   1.230 +  }
   1.231 +
   1.232 +  void ConnectSocket(TransportTestPeer *peer) {
   1.233 +    RUN_ON_THREAD(test_utils->sts_target(),
   1.234 +                  WrapRunnable(this, & TransportTestPeer::ConnectSocket_s,
   1.235 +                               peer),
   1.236 +                  NS_DISPATCH_SYNC);
   1.237 +  }
   1.238 +
   1.239 +  void InitIce() {
   1.240 +    nsresult res;
   1.241 +
   1.242 +    // Attach our slots
   1.243 +    ice_ctx_->SignalGatheringStateChange.
   1.244 +        connect(this, &TransportTestPeer::GatheringStateChange);
   1.245 +
   1.246 +    char name[100];
   1.247 +    snprintf(name, sizeof(name), "%s:stream%d", name_.c_str(),
   1.248 +             (int)streams_.size());
   1.249 +
   1.250 +    // Create the media stream
   1.251 +    mozilla::RefPtr<NrIceMediaStream> stream =
   1.252 +        ice_ctx_->CreateStream(static_cast<char *>(name), 1);
   1.253 +    ASSERT_TRUE(stream != nullptr);
   1.254 +    streams_.push_back(stream);
   1.255 +
   1.256 +    // Listen for candidates
   1.257 +    stream->SignalCandidate.
   1.258 +        connect(this, &TransportTestPeer::GotCandidate);
   1.259 +
   1.260 +    // Create the transport layer
   1.261 +    ice_ = new TransportLayerIce(name, ice_ctx_, stream, 1);
   1.262 +
   1.263 +    // Assemble the stack
   1.264 +    nsAutoPtr<std::queue<mozilla::TransportLayer *> > layers(
   1.265 +      new std::queue<mozilla::TransportLayer *>);
   1.266 +    layers->push(ice_);
   1.267 +    layers->push(dtls_);
   1.268 +
   1.269 +    test_utils->sts_target()->Dispatch(
   1.270 +      WrapRunnableRet(flow_, &TransportFlow::PushLayers, layers, &res),
   1.271 +      NS_DISPATCH_SYNC);
   1.272 +
   1.273 +    ASSERT_EQ((nsresult)NS_OK, res);
   1.274 +
   1.275 +    // Listen for media events
   1.276 +    flow_->SignalPacketReceived.connect(this, &TransportTestPeer::PacketReceived);
   1.277 +    flow_->SignalStateChange.connect(this, &TransportTestPeer::StateChanged);
   1.278 +
   1.279 +    // Start gathering
   1.280 +    test_utils->sts_target()->Dispatch(
   1.281 +        WrapRunnableRet(ice_ctx_, &NrIceCtx::StartGathering, &res),
   1.282 +        NS_DISPATCH_SYNC);
   1.283 +    ASSERT_TRUE(NS_SUCCEEDED(res));
   1.284 +  }
   1.285 +
   1.286 +  void ConnectIce(TransportTestPeer *peer) {
   1.287 +    peer_ = peer;
   1.288 +
   1.289 +    // If gathering is already complete, push the candidates over
   1.290 +    if (gathering_complete_)
   1.291 +      GatheringComplete();
   1.292 +  }
   1.293 +
   1.294 +  // New candidate
   1.295 +  void GotCandidate(NrIceMediaStream *stream, const std::string &candidate) {
   1.296 +    std::cerr << "Got candidate " << candidate << std::endl;
   1.297 +    candidates_[stream->name()].push_back(candidate);
   1.298 +  }
   1.299 +
   1.300 +  void GatheringStateChange(NrIceCtx* ctx,
   1.301 +                            NrIceCtx::GatheringState state) {
   1.302 +    (void)ctx;
   1.303 +    if (state == NrIceCtx::ICE_CTX_GATHER_COMPLETE) {
   1.304 +      GatheringComplete();
   1.305 +    }
   1.306 +  }
   1.307 +
   1.308 +  // Gathering complete, so send our candidates and start
   1.309 +  // connecting on the other peer.
   1.310 +  void GatheringComplete() {
   1.311 +    nsresult res;
   1.312 +
   1.313 +    // Don't send to the other side
   1.314 +    if (!peer_) {
   1.315 +      gathering_complete_ = true;
   1.316 +      return;
   1.317 +    }
   1.318 +
   1.319 +    // First send attributes
   1.320 +    test_utils->sts_target()->Dispatch(
   1.321 +      WrapRunnableRet(peer_->ice_ctx_,
   1.322 +                      &NrIceCtx::ParseGlobalAttributes,
   1.323 +                      ice_ctx_->GetGlobalAttributes(), &res),
   1.324 +      NS_DISPATCH_SYNC);
   1.325 +    ASSERT_TRUE(NS_SUCCEEDED(res));
   1.326 +
   1.327 +    for (size_t i=0; i<streams_.size(); ++i) {
   1.328 +      test_utils->sts_target()->Dispatch(
   1.329 +        WrapRunnableRet(peer_->streams_[i], &NrIceMediaStream::ParseAttributes,
   1.330 +                        candidates_[streams_[i]->name()], &res), NS_DISPATCH_SYNC);
   1.331 +
   1.332 +      ASSERT_TRUE(NS_SUCCEEDED(res));
   1.333 +    }
   1.334 +
   1.335 +    // Start checks on the other peer.
   1.336 +    test_utils->sts_target()->Dispatch(
   1.337 +      WrapRunnableRet(peer_->ice_ctx_, &NrIceCtx::StartChecks, &res),
   1.338 +      NS_DISPATCH_SYNC);
   1.339 +    ASSERT_TRUE(NS_SUCCEEDED(res));
   1.340 +  }
   1.341 +
   1.342 +  TransportResult SendPacket(const unsigned char* data, size_t len) {
   1.343 +    TransportResult ret;
   1.344 +    test_utils->sts_target()->Dispatch(
   1.345 +      WrapRunnableRet(flow_, &TransportFlow::SendPacket, data, len, &ret),
   1.346 +      NS_DISPATCH_SYNC);
   1.347 +
   1.348 +    return ret;
   1.349 +  }
   1.350 +
   1.351 +
   1.352 +  void StateChanged(TransportFlow *flow, TransportLayer::State state) {
   1.353 +    if (state == TransportLayer::TS_OPEN) {
   1.354 +      std::cerr << "Now connected" << std::endl;
   1.355 +    }
   1.356 +  }
   1.357 +
   1.358 +  void PacketReceived(TransportFlow * flow, const unsigned char* data,
   1.359 +                      size_t len) {
   1.360 +    std::cerr << "Received " << len << " bytes" << std::endl;
   1.361 +    ++received_;
   1.362 +  }
   1.363 +
   1.364 +  void SetLoss(uint32_t loss) {
   1.365 +    lossy_->SetLoss(loss);
   1.366 +  }
   1.367 +
   1.368 +  TransportLayer::State state() {
   1.369 +    TransportLayer::State tstate;
   1.370 +
   1.371 +    RUN_ON_THREAD(test_utils->sts_target(),
   1.372 +                  WrapRunnableRet(flow_, &TransportFlow::state, &tstate),
   1.373 +                  NS_DISPATCH_SYNC);
   1.374 +
   1.375 +    return tstate;
   1.376 +  }
   1.377 +
   1.378 +  bool connected() {
   1.379 +    return state() == TransportLayer::TS_OPEN;
   1.380 +  }
   1.381 +
   1.382 +  bool failed() {
   1.383 +    return state() == TransportLayer::TS_ERROR;
   1.384 +  }
   1.385 +
   1.386 +  size_t received() { return received_; }
   1.387 +
   1.388 + private:
   1.389 +  std::string name_;
   1.390 +  nsCOMPtr<nsIEventTarget> target_;
   1.391 +  size_t received_;
   1.392 +    mozilla::RefPtr<TransportFlow> flow_;
   1.393 +  TransportLayerLoopback *loopback_;
   1.394 +  TransportLayerLogging *logging_;
   1.395 +  TransportLayerLossy *lossy_;
   1.396 +  TransportLayerDtls *dtls_;
   1.397 +  TransportLayerIce *ice_;
   1.398 +  mozilla::RefPtr<DtlsIdentity> identity_;
   1.399 +  mozilla::RefPtr<NrIceCtx> ice_ctx_;
   1.400 +  std::vector<mozilla::RefPtr<NrIceMediaStream> > streams_;
   1.401 +  std::map<std::string, std::vector<std::string> > candidates_;
   1.402 +  TransportTestPeer *peer_;
   1.403 +  bool gathering_complete_;
   1.404 +  unsigned char fingerprint_[TransportLayerDtls::kMaxDigestLength];
   1.405 +  size_t fingerprint_len_;
   1.406 +};
   1.407 +
   1.408 +
   1.409 +class TransportTest : public ::testing::Test {
   1.410 + public:
   1.411 +  TransportTest() {
   1.412 +    fds_[0] = nullptr;
   1.413 +    fds_[1] = nullptr;
   1.414 +  }
   1.415 +
   1.416 +  ~TransportTest() {
   1.417 +    delete p1_;
   1.418 +    delete p2_;
   1.419 +
   1.420 +    //    Can't detach these
   1.421 +    //    PR_Close(fds_[0]);
   1.422 +    //    PR_Close(fds_[1]);
   1.423 +  }
   1.424 +
   1.425 +  void DestroyPeerFlows() {
   1.426 +    p1_->DisconnectDestroyFlow();
   1.427 +    p2_->DisconnectDestroyFlow();
   1.428 +  }
   1.429 +
   1.430 +  void SetUp() {
   1.431 +    nsresult rv;
   1.432 +    target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
   1.433 +    ASSERT_TRUE(NS_SUCCEEDED(rv));
   1.434 +
   1.435 +    p1_ = new TransportTestPeer(target_, "P1");
   1.436 +    p2_ = new TransportTestPeer(target_, "P2");
   1.437 +  }
   1.438 +
   1.439 +  void SetDtlsPeer(int digests = 1, unsigned int damage = 0) {
   1.440 +    p1_->SetDtlsPeer(p2_, digests, damage);
   1.441 +    p2_->SetDtlsPeer(p1_, digests, damage);
   1.442 +  }
   1.443 +
   1.444 +  void SetDtlsAllowAll() {
   1.445 +    p1_->SetDtlsAllowAll();
   1.446 +    p2_->SetDtlsAllowAll();
   1.447 +  }
   1.448 +
   1.449 +  void ConnectSocket() {
   1.450 +    test_utils->sts_target()->Dispatch(
   1.451 +      WrapRunnable(p1_, &TransportTestPeer::ConnectSocket, p2_),
   1.452 +      NS_DISPATCH_SYNC);
   1.453 +    test_utils->sts_target()->Dispatch(
   1.454 +      WrapRunnable(p2_, &TransportTestPeer::ConnectSocket, p1_),
   1.455 +      NS_DISPATCH_SYNC);
   1.456 +
   1.457 +    ASSERT_TRUE_WAIT(p1_->connected(), 10000);
   1.458 +    ASSERT_TRUE_WAIT(p2_->connected(), 10000);
   1.459 +  }
   1.460 +
   1.461 +  void ConnectSocketExpectFail() {
   1.462 +    test_utils->sts_target()->Dispatch(
   1.463 +      WrapRunnable(p1_, &TransportTestPeer::ConnectSocket, p2_),
   1.464 +      NS_DISPATCH_SYNC);
   1.465 +    test_utils->sts_target()->Dispatch(
   1.466 +      WrapRunnable(p2_, &TransportTestPeer::ConnectSocket, p1_),
   1.467 +      NS_DISPATCH_SYNC);
   1.468 +    ASSERT_TRUE_WAIT(p1_->failed(), 10000);
   1.469 +    ASSERT_TRUE_WAIT(p2_->failed(), 10000);
   1.470 +  }
   1.471 +
   1.472 +  void InitIce() {
   1.473 +    p1_->InitIce();
   1.474 +    p2_->InitIce();
   1.475 +  }
   1.476 +
   1.477 +  void ConnectIce() {
   1.478 +    p1_->InitIce();
   1.479 +    p2_->InitIce();
   1.480 +    p1_->ConnectIce(p2_);
   1.481 +    p2_->ConnectIce(p1_);
   1.482 +    ASSERT_TRUE_WAIT(p1_->connected(), 10000);
   1.483 +    ASSERT_TRUE_WAIT(p2_->connected(), 10000);
   1.484 +  }
   1.485 +
   1.486 +  void TransferTest(size_t count) {
   1.487 +    unsigned char buf[1000];
   1.488 +
   1.489 +    for (size_t i= 0; i<count; ++i) {
   1.490 +      memset(buf, count & 0xff, sizeof(buf));
   1.491 +      TransportResult rv = p1_->SendPacket(buf, sizeof(buf));
   1.492 +      ASSERT_TRUE(rv > 0);
   1.493 +    }
   1.494 +
   1.495 +    std::cerr << "Received == " << p2_->received() << std::endl;
   1.496 +    ASSERT_TRUE_WAIT(count == p2_->received(), 10000);
   1.497 +  }
   1.498 +
   1.499 + protected:
   1.500 +  PRFileDesc *fds_[2];
   1.501 +  TransportTestPeer *p1_;
   1.502 +  TransportTestPeer *p2_;
   1.503 +  nsCOMPtr<nsIEventTarget> target_;
   1.504 +};
   1.505 +
   1.506 +
   1.507 +TEST_F(TransportTest, TestNoDtlsVerificationSettings) {
   1.508 +  ConnectSocketExpectFail();
   1.509 +}
   1.510 +
   1.511 +TEST_F(TransportTest, TestConnect) {
   1.512 +  SetDtlsPeer();
   1.513 +  ConnectSocket();
   1.514 +}
   1.515 +
   1.516 +TEST_F(TransportTest, TestConnectDestroyFlowsMainThread) {
   1.517 +  SetDtlsPeer();
   1.518 +  ConnectSocket();
   1.519 +  DestroyPeerFlows();
   1.520 +}
   1.521 +
   1.522 +TEST_F(TransportTest, TestConnectAllowAll) {
   1.523 +  SetDtlsAllowAll();
   1.524 +  ConnectSocket();
   1.525 +}
   1.526 +
   1.527 +TEST_F(TransportTest, TestConnectBadDigest) {
   1.528 +  SetDtlsPeer(1, 1);
   1.529 +
   1.530 +  ConnectSocketExpectFail();
   1.531 +}
   1.532 +
   1.533 +TEST_F(TransportTest, TestConnectTwoDigests) {
   1.534 +  SetDtlsPeer(2, 0);
   1.535 +
   1.536 +  ConnectSocket();
   1.537 +}
   1.538 +
   1.539 +TEST_F(TransportTest, TestConnectTwoDigestsFirstBad) {
   1.540 +  SetDtlsPeer(2, 1);
   1.541 +
   1.542 +  ConnectSocketExpectFail();
   1.543 +}
   1.544 +
   1.545 +TEST_F(TransportTest, TestConnectTwoDigestsSecondBad) {
   1.546 +  SetDtlsPeer(2, 2);
   1.547 +
   1.548 +  ConnectSocketExpectFail();
   1.549 +}
   1.550 +
   1.551 +TEST_F(TransportTest, TestConnectTwoDigestsBothBad) {
   1.552 +  SetDtlsPeer(2, 3);
   1.553 +
   1.554 +  ConnectSocketExpectFail();
   1.555 +}
   1.556 +
   1.557 +TEST_F(TransportTest, TestTransfer) {
   1.558 +  SetDtlsPeer();
   1.559 +  ConnectSocket();
   1.560 +  TransferTest(1);
   1.561 +}
   1.562 +
   1.563 +TEST_F(TransportTest, TestConnectLoseFirst) {
   1.564 +  SetDtlsPeer();
   1.565 +  p1_->SetLoss(0);
   1.566 +  ConnectSocket();
   1.567 +  TransferTest(1);
   1.568 +}
   1.569 +
   1.570 +TEST_F(TransportTest, TestConnectIce) {
   1.571 +  SetDtlsPeer();
   1.572 +  ConnectIce();
   1.573 +}
   1.574 +
   1.575 +TEST_F(TransportTest, TestTransferIce) {
   1.576 +  SetDtlsPeer();
   1.577 +  ConnectIce();
   1.578 +  TransferTest(1);
   1.579 +}
   1.580 +
   1.581 +TEST(PushTests, LayerFail) {
   1.582 +  TransportFlow flow;
   1.583 +  nsresult rv;
   1.584 +  bool destroyed1, destroyed2;
   1.585 +
   1.586 +  rv = flow.PushLayer(new TransportLayerDummy(true, &destroyed1));
   1.587 +  ASSERT_TRUE(NS_SUCCEEDED(rv));
   1.588 +
   1.589 +  rv = flow.PushLayer(new TransportLayerDummy(false, &destroyed2));
   1.590 +  ASSERT_TRUE(NS_FAILED(rv));
   1.591 +
   1.592 +  ASSERT_EQ(TransportLayer::TS_ERROR, flow.state());
   1.593 +  ASSERT_EQ(true, destroyed1);
   1.594 +  ASSERT_EQ(true, destroyed2);
   1.595 +
   1.596 +  rv = flow.PushLayer(new TransportLayerDummy(true, &destroyed1));
   1.597 +  ASSERT_TRUE(NS_FAILED(rv));
   1.598 +  ASSERT_EQ(true, destroyed1);
   1.599 +}
   1.600 +
   1.601 +
   1.602 +TEST(PushTests, LayersFail) {
   1.603 +  TransportFlow flow;
   1.604 +  nsresult rv;
   1.605 +  bool destroyed1, destroyed2, destroyed3;
   1.606 +
   1.607 +  rv = flow.PushLayer(new TransportLayerDummy(true, &destroyed1));
   1.608 +  ASSERT_TRUE(NS_SUCCEEDED(rv));
   1.609 +
   1.610 +  nsAutoPtr<std::queue<TransportLayer *> > layers(
   1.611 +      new std::queue<TransportLayer *>());
   1.612 +
   1.613 +  layers->push(new TransportLayerDummy(true, &destroyed2));
   1.614 +  layers->push(new TransportLayerDummy(false, &destroyed3));
   1.615 +
   1.616 +  rv = flow.PushLayers(layers);
   1.617 +  ASSERT_TRUE(NS_FAILED(rv));
   1.618 +
   1.619 +  ASSERT_EQ(TransportLayer::TS_ERROR, flow.state());
   1.620 +  ASSERT_EQ(true, destroyed1);
   1.621 +  ASSERT_EQ(true, destroyed2);
   1.622 +  ASSERT_EQ(true, destroyed3);
   1.623 +
   1.624 +  layers = new std::queue<TransportLayer *>();
   1.625 +  layers->push(new TransportLayerDummy(true, &destroyed2));
   1.626 +  layers->push(new TransportLayerDummy(true, &destroyed3));
   1.627 +  rv = flow.PushLayers(layers);
   1.628 +
   1.629 +  ASSERT_TRUE(NS_FAILED(rv));
   1.630 +  ASSERT_EQ(true, destroyed2);
   1.631 +  ASSERT_EQ(true, destroyed3);
   1.632 +}
   1.633 +
   1.634 +}  // end namespace
   1.635 +
   1.636 +int main(int argc, char **argv)
   1.637 +{
   1.638 +  test_utils = new MtransportTestUtils();
   1.639 +
   1.640 +  NSS_NoDB_Init(nullptr);
   1.641 +  NSS_SetDomesticPolicy();
   1.642 +  // Start the tests
   1.643 +  ::testing::InitGoogleTest(&argc, argv);
   1.644 +
   1.645 +  int rv = RUN_ALL_TESTS();
   1.646 +  delete test_utils;
   1.647 +  return rv;
   1.648 +}

mercurial