media/webrtc/signaling/test/signaling_unittests.cpp

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include <iostream>
     6 #include <map>
     7 #include <algorithm>
     8 #include <string>
     9 #include <unistd.h>
    11 #include "base/basictypes.h"
    12 #include "logging.h"
    14 #define GTEST_HAS_RTTI 0
    15 #include "gtest/gtest.h"
    16 #include "gtest_utils.h"
    18 #include "nspr.h"
    19 #include "nss.h"
    20 #include "ssl.h"
    21 #include "prthread.h"
    23 #include "cpr_stdlib.h"
    24 #include "FakePCObserver.h"
    25 #include "FakeMediaStreams.h"
    26 #include "FakeMediaStreamsImpl.h"
    27 #include "PeerConnectionImpl.h"
    28 #include "PeerConnectionCtx.h"
    29 #include "PeerConnectionMedia.h"
    30 #include "MediaPipeline.h"
    31 #include "runnable_utils.h"
    32 #include "nsServiceManagerUtils.h"
    33 #include "mozilla/Services.h"
    34 #include "nsIPrefService.h"
    35 #include "nsIPrefBranch.h"
    36 #include "nsNetUtil.h"
    37 #include "nsIIOService.h"
    38 #include "nsIDNSService.h"
    39 #include "nsWeakReference.h"
    40 #include "nricectx.h"
    41 #include "rlogringbuffer.h"
    42 #include "mozilla/SyncRunnable.h"
    43 #include "logging.h"
    44 #include "stunserver.h"
    45 #include "stunserver.cpp"
    46 #include "PeerConnectionImplEnumsBinding.cpp"
    48 #include "mtransport_test_utils.h"
    49 #include "gtest_ringbuffer_dumper.h"
    50 MtransportTestUtils *test_utils;
    51 nsCOMPtr<nsIThread> gMainThread;
    52 nsCOMPtr<nsIThread> gGtestThread;
    53 bool gTestsComplete = false;
    55 #ifndef USE_FAKE_MEDIA_STREAMS
    56 #error USE_FAKE_MEDIA_STREAMS undefined
    57 #endif
    58 #ifndef USE_FAKE_PCOBSERVER
    59 #error USE_FAKE_PCOBSERVER undefined
    60 #endif
    62 static int kDefaultTimeout = 7000;
    63 static bool fRtcpMux = true;
    65 static std::string callerName = "caller";
    66 static std::string calleeName = "callee";
    68 #define ARRAY_TO_STL(container, type, array) \
    69         (container<type>((array), (array) + PR_ARRAY_SIZE(array)))
    71 #define ARRAY_TO_SET(type, array) ARRAY_TO_STL(std::set, type, array)
    73 std::string g_stun_server_address((char *)"23.21.150.121");
    74 uint16_t g_stun_server_port(3478);
    75 std::string kBogusSrflxAddress((char *)"192.0.2.1");
    76 uint16_t kBogusSrflxPort(1001);
    78 namespace sipcc {
    80 // We can't use mozilla/dom/MediaConstraintsBinding.h here because it uses
    81 // nsString, so we pass constraints in using MediaConstraintsExternal instead
    83 class MediaConstraints : public MediaConstraintsExternal {
    84 public:
    85   void setBooleanConstraint(const char *namePtr, bool value, bool mandatory) {
    86     cc_boolean_constraint_t &member (getMember(namePtr));
    87     member.was_passed = true;
    88     member.value = value;
    89     member.mandatory = mandatory;
    90   }
    91 private:
    92   cc_boolean_constraint_t &getMember(const char *namePtr) {
    93     if (strcmp(namePtr, "OfferToReceiveAudio") == 0) {
    94         return mConstraints.offer_to_receive_audio;
    95     }
    96     if (strcmp(namePtr, "OfferToReceiveVideo") == 0) {
    97         return mConstraints.offer_to_receive_video;
    98     }
    99     MOZ_ASSERT(false);
   100     return mConstraints.moz_dont_offer_datachannel;
   101   }
   102 };
   103 }
   105 using namespace mozilla;
   106 using namespace mozilla::dom;
   108 namespace test {
   109 std::string indent(const std::string &s, int width = 4) {
   110   std::string prefix;
   111   std::string out;
   112   char previous = '\n';
   113   prefix.assign(width, ' ');
   114   for (std::string::const_iterator i = s.begin(); i != s.end(); i++) {
   115     if (previous == '\n') {
   116       out += prefix;
   117     }
   118     out += *i;
   119     previous = *i;
   120   }
   121   return out;
   122 }
   124 static const std::string strSampleSdpAudioVideoNoIce =
   125   "v=0\r\n"
   126   "o=Mozilla-SIPUA 4949 0 IN IP4 10.86.255.143\r\n"
   127   "s=SIP Call\r\n"
   128   "t=0 0\r\n"
   129   "a=ice-ufrag:qkEP\r\n"
   130   "a=ice-pwd:ed6f9GuHjLcoCN6sC/Eh7fVl\r\n"
   131   "m=audio 16384 RTP/AVP 0 8 9 101\r\n"
   132   "c=IN IP4 10.86.255.143\r\n"
   133   "a=rtpmap:0 PCMU/8000\r\n"
   134   "a=rtpmap:8 PCMA/8000\r\n"
   135   "a=rtpmap:9 G722/8000\r\n"
   136   "a=rtpmap:101 telephone-event/8000\r\n"
   137   "a=fmtp:101 0-15\r\n"
   138   "a=sendrecv\r\n"
   139   "a=candidate:1 1 UDP 2130706431 192.168.2.1 50005 typ host\r\n"
   140   "a=candidate:2 2 UDP 2130706431 192.168.2.2 50006 typ host\r\n"
   141   "m=video 1024 RTP/AVP 97\r\n"
   142   "c=IN IP4 10.86.255.143\r\n"
   143   "a=rtpmap:120 VP8/90000\r\n"
   144   "a=fmtp:97 profile-level-id=42E00C\r\n"
   145   "a=sendrecv\r\n"
   146   "a=candidate:1 1 UDP 2130706431 192.168.2.3 50007 typ host\r\n"
   147   "a=candidate:2 2 UDP 2130706431 192.168.2.4 50008 typ host\r\n";
   149 static const std::string strSampleCandidate =
   150   "a=candidate:1 1 UDP 2130706431 192.168.2.1 50005 typ host\r\n";
   152 static const std::string strSampleMid = "";
   154 static const unsigned short nSamplelevel = 2;
   156 static const std::string strG711SdpOffer =
   157     "v=0\r\n"
   158     "o=- 1 1 IN IP4 148.147.200.251\r\n"
   159     "s=-\r\n"
   160     "b=AS:64\r\n"
   161     "t=0 0\r\n"
   162     "a=fingerprint:sha-256 F3:FA:20:C0:CD:48:C4:5F:02:5F:A5:D3:21:D0:2D:48:"
   163       "7B:31:60:5C:5A:D8:0D:CD:78:78:6C:6D:CE:CC:0C:67\r\n"
   164     "m=audio 9000 RTP/AVP 0 8 126\r\n"
   165     "c=IN IP4 148.147.200.251\r\n"
   166     "b=TIAS:64000\r\n"
   167     "a=rtpmap:0 PCMU/8000\r\n"
   168     "a=rtpmap:8 PCMA/8000\r\n"
   169     "a=rtpmap:126 telephone-event/8000\r\n"
   170     "a=candidate:0 1 udp 2130706432 148.147.200.251 9000 typ host\r\n"
   171     "a=candidate:0 2 udp 2130706432 148.147.200.251 9005 typ host\r\n"
   172     "a=ice-ufrag:cYuakxkEKH+RApYE\r\n"
   173     "a=ice-pwd:bwtpzLZD+3jbu8vQHvEa6Xuq\r\n"
   174     "a=sendrecv\r\n";
   177 enum sdpTestFlags
   178 {
   179   SHOULD_SEND_AUDIO     = (1<<0),
   180   SHOULD_RECV_AUDIO     = (1<<1),
   181   SHOULD_INACTIVE_AUDIO = (1<<2),
   182   SHOULD_REJECT_AUDIO   = (1<<3),
   183   SHOULD_OMIT_AUDIO     = (1<<4),
   184   DONT_CHECK_AUDIO      = (1<<5),
   185   SHOULD_CHECK_AUDIO    = (1<<6),
   187   SHOULD_SEND_VIDEO     = (1<<8),
   188   SHOULD_RECV_VIDEO     = (1<<9),
   189   SHOULD_INACTIVE_VIDEO = (1<<10),
   190   SHOULD_REJECT_VIDEO   = (1<<11),
   191   SHOULD_OMIT_VIDEO     = (1<<12),
   192   DONT_CHECK_VIDEO      = (1<<13),
   193   SHOULD_CHECK_VIDEO    = (1<<14),
   195   SHOULD_INCLUDE_DATA   = (1 << 16),
   196   DONT_CHECK_DATA       = (1 << 17),
   198   SHOULD_SENDRECV_AUDIO = SHOULD_SEND_AUDIO | SHOULD_RECV_AUDIO,
   199   SHOULD_SENDRECV_VIDEO = SHOULD_SEND_VIDEO | SHOULD_RECV_VIDEO,
   200   SHOULD_SENDRECV_AV = SHOULD_SENDRECV_AUDIO | SHOULD_SENDRECV_VIDEO,
   201   SHOULD_CHECK_AV = SHOULD_CHECK_AUDIO | SHOULD_CHECK_VIDEO,
   203   AUDIO_FLAGS = SHOULD_SEND_AUDIO | SHOULD_RECV_AUDIO
   204                 | SHOULD_INACTIVE_AUDIO | SHOULD_REJECT_AUDIO
   205                 | DONT_CHECK_AUDIO | SHOULD_OMIT_AUDIO
   206                 | SHOULD_CHECK_AUDIO,
   208   VIDEO_FLAGS = SHOULD_SEND_VIDEO | SHOULD_RECV_VIDEO
   209                 | SHOULD_INACTIVE_VIDEO | SHOULD_REJECT_VIDEO
   210                 | DONT_CHECK_VIDEO | SHOULD_OMIT_VIDEO
   211                 | SHOULD_CHECK_VIDEO
   212 };
   214 enum offerAnswerFlags
   215 {
   216   OFFER_NONE  = 0, // Sugar to make function calls clearer.
   217   OFFER_AUDIO = (1<<0),
   218   OFFER_VIDEO = (1<<1),
   219   // Leaving some room here for other media types
   220   ANSWER_NONE  = 0, // Sugar to make function calls clearer.
   221   ANSWER_AUDIO = (1<<8),
   222   ANSWER_VIDEO = (1<<9),
   224   OFFER_AV = OFFER_AUDIO | OFFER_VIDEO,
   225   ANSWER_AV = ANSWER_AUDIO | ANSWER_VIDEO
   226 };
   228 enum mediaPipelineFlags
   229 {
   230   PIPELINE_LOCAL = (1<<0),
   231   PIPELINE_RTCP_MUX = (1<<1),
   232   PIPELINE_SEND = (1<<2),
   233   PIPELINE_VIDEO = (1<<3),
   234   PIPELINE_RTCP_NACK = (1<<4)
   235 };
   238 class TestObserver : public AFakePCObserver
   239 {
   240 public:
   241   TestObserver(sipcc::PeerConnectionImpl *peerConnection,
   242                const std::string &aName) :
   243     AFakePCObserver(peerConnection, aName) {}
   245   size_t MatchingCandidates(const std::string& cand) {
   246     size_t count = 0;
   248     for (size_t i=0; i<candidates.size(); ++i) {
   249       if (candidates[i].find(cand) != std::string::npos)
   250         ++count;
   251     }
   253     return count;
   254   }
   256   NS_DECL_THREADSAFE_ISUPPORTS
   257   NS_IMETHODIMP OnCreateOfferSuccess(const char* offer, ER&);
   258   NS_IMETHODIMP OnCreateOfferError(uint32_t code, const char *msg, ER&);
   259   NS_IMETHODIMP OnCreateAnswerSuccess(const char* answer, ER&);
   260   NS_IMETHODIMP OnCreateAnswerError(uint32_t code, const char *msg, ER&);
   261   NS_IMETHODIMP OnSetLocalDescriptionSuccess(ER&);
   262   NS_IMETHODIMP OnSetRemoteDescriptionSuccess(ER&);
   263   NS_IMETHODIMP OnSetLocalDescriptionError(uint32_t code, const char *msg, ER&);
   264   NS_IMETHODIMP OnSetRemoteDescriptionError(uint32_t code, const char *msg, ER&);
   265   NS_IMETHODIMP NotifyConnection(ER&);
   266   NS_IMETHODIMP NotifyClosedConnection(ER&);
   267   NS_IMETHODIMP NotifyDataChannel(nsIDOMDataChannel *channel, ER&);
   268   NS_IMETHODIMP OnStateChange(PCObserverStateType state_type, ER&, void*);
   269   NS_IMETHODIMP OnAddStream(nsIDOMMediaStream *stream, ER&);
   270   NS_IMETHODIMP OnRemoveStream(ER&);
   271   NS_IMETHODIMP OnAddTrack(ER&);
   272   NS_IMETHODIMP OnRemoveTrack(ER&);
   273   NS_IMETHODIMP OnAddIceCandidateSuccess(ER&);
   274   NS_IMETHODIMP OnAddIceCandidateError(uint32_t code, const char *msg, ER&);
   275   NS_IMETHODIMP OnIceCandidate(uint16_t level, const char *mid, const char *cand, ER&);
   276 };
   278 NS_IMPL_ISUPPORTS(TestObserver, nsISupportsWeakReference)
   280 NS_IMETHODIMP
   281 TestObserver::OnCreateOfferSuccess(const char* offer, ER&)
   282 {
   283   lastString = strdup(offer);
   284   state = stateSuccess;
   285   std::cout << name << ": onCreateOfferSuccess = " << std::endl << indent(offer)
   286             << std::endl;
   287   return NS_OK;
   288 }
   290 NS_IMETHODIMP
   291 TestObserver::OnCreateOfferError(uint32_t code, const char *message, ER&)
   292 {
   293   lastStatusCode = static_cast<sipcc::PeerConnectionImpl::Error>(code);
   294   state = stateError;
   295   std::cout << name << ": onCreateOfferError = " << code
   296             << " (" << message << ")" << std::endl;
   297   return NS_OK;
   298 }
   300 NS_IMETHODIMP
   301 TestObserver::OnCreateAnswerSuccess(const char* answer, ER&)
   302 {
   303   lastString = strdup(answer);
   304   state = stateSuccess;
   305   std::cout << name << ": onCreateAnswerSuccess =" << std::endl
   306             << indent(answer) << std::endl;
   307   return NS_OK;
   308 }
   310 NS_IMETHODIMP
   311 TestObserver::OnCreateAnswerError(uint32_t code, const char *message, ER&)
   312 {
   313   lastStatusCode = static_cast<sipcc::PeerConnectionImpl::Error>(code);
   314   std::cout << name << ": onCreateAnswerError = " << code
   315             << " (" << message << ")" << std::endl;
   316   state = stateError;
   317   return NS_OK;
   318 }
   320 NS_IMETHODIMP
   321 TestObserver::OnSetLocalDescriptionSuccess(ER&)
   322 {
   323   lastStatusCode = sipcc::PeerConnectionImpl::kNoError;
   324   state = stateSuccess;
   325   std::cout << name << ": onSetLocalDescriptionSuccess" << std::endl;
   326   return NS_OK;
   327 }
   329 NS_IMETHODIMP
   330 TestObserver::OnSetRemoteDescriptionSuccess(ER&)
   331 {
   332   lastStatusCode = sipcc::PeerConnectionImpl::kNoError;
   333   state = stateSuccess;
   334   std::cout << name << ": onSetRemoteDescriptionSuccess" << std::endl;
   335   return NS_OK;
   336 }
   338 NS_IMETHODIMP
   339 TestObserver::OnSetLocalDescriptionError(uint32_t code, const char *message, ER&)
   340 {
   341   lastStatusCode = static_cast<sipcc::PeerConnectionImpl::Error>(code);
   342   state = stateError;
   343   std::cout << name << ": onSetLocalDescriptionError = " << code
   344             << " (" << message << ")" << std::endl;
   345   return NS_OK;
   346 }
   348 NS_IMETHODIMP
   349 TestObserver::OnSetRemoteDescriptionError(uint32_t code, const char *message, ER&)
   350 {
   351   lastStatusCode = static_cast<sipcc::PeerConnectionImpl::Error>(code);
   352   state = stateError;
   353   std::cout << name << ": onSetRemoteDescriptionError = " << code
   354             << " (" << message << ")" << std::endl;
   355   return NS_OK;
   356 }
   358 NS_IMETHODIMP
   359 TestObserver::NotifyConnection(ER&)
   360 {
   361   std::cout << name << ": NotifyConnection" << std::endl;
   362   return NS_OK;
   363 }
   365 NS_IMETHODIMP
   366 TestObserver::NotifyClosedConnection(ER&)
   367 {
   368   std::cout << name << ": NotifyClosedConnection" << std::endl;
   369   return NS_OK;
   370 }
   372 NS_IMETHODIMP
   373 TestObserver::NotifyDataChannel(nsIDOMDataChannel *channel, ER&)
   374 {
   375   std::cout << name << ": NotifyDataChannel" << std::endl;
   376   return NS_OK;
   377 }
   379 NS_IMETHODIMP
   380 TestObserver::OnStateChange(PCObserverStateType state_type, ER&, void*)
   381 {
   382   nsresult rv;
   383   PCImplReadyState gotready;
   384   PCImplIceConnectionState gotice;
   385   PCImplIceGatheringState goticegathering;
   386   PCImplSipccState gotsipcc;
   387   PCImplSignalingState gotsignaling;
   389   std::cout << name << ": ";
   391   switch (state_type)
   392   {
   393   case PCObserverStateType::ReadyState:
   394     rv = pc->ReadyState(&gotready);
   395     NS_ENSURE_SUCCESS(rv, rv);
   396     std::cout << "Ready State: "
   397               << PCImplReadyStateValues::strings[int(gotready)].value
   398               << std::endl;
   399     break;
   400   case PCObserverStateType::IceConnectionState:
   401     rv = pc->IceConnectionState(&gotice);
   402     NS_ENSURE_SUCCESS(rv, rv);
   403     std::cout << "ICE Connection State: "
   404               << PCImplIceConnectionStateValues::strings[int(gotice)].value
   405               << std::endl;
   406     break;
   407   case PCObserverStateType::IceGatheringState:
   408     rv = pc->IceGatheringState(&goticegathering);
   409     NS_ENSURE_SUCCESS(rv, rv);
   410     std::cout
   411         << "ICE Gathering State: "
   412         << PCImplIceGatheringStateValues::strings[int(goticegathering)].value
   413         << std::endl;
   414     break;
   415   case PCObserverStateType::SdpState:
   416     std::cout << "SDP State: " << std::endl;
   417     // NS_ENSURE_SUCCESS(rv, rv);
   418     break;
   419   case PCObserverStateType::SipccState:
   420     rv = pc->SipccState(&gotsipcc);
   421     NS_ENSURE_SUCCESS(rv, rv);
   422     std::cout << "SIPCC State: "
   423               << PCImplSipccStateValues::strings[int(gotsipcc)].value
   424               << std::endl;
   425     break;
   426   case PCObserverStateType::SignalingState:
   427     rv = pc->SignalingState(&gotsignaling);
   428     NS_ENSURE_SUCCESS(rv, rv);
   429     std::cout << "Signaling State: "
   430               << PCImplSignalingStateValues::strings[int(gotsignaling)].value
   431               << std::endl;
   432     break;
   433   default:
   434     // Unknown State
   435     MOZ_CRASH("Unknown state change type.");
   436     break;
   437   }
   439   lastStateType = state_type;
   440   return NS_OK;
   441 }
   444 NS_IMETHODIMP
   445 TestObserver::OnAddStream(nsIDOMMediaStream *stream, ER&)
   446 {
   447   PR_ASSERT(stream);
   449   DOMMediaStream *ms = static_cast<DOMMediaStream *>(stream);
   451   std::cout << name << ": OnAddStream called hints=" << ms->GetHintContents()
   452             << " thread=" << PR_GetCurrentThread() << std::endl ;
   454   onAddStreamCalled = true;
   456   streams.push_back(ms);
   458   // We know that the media stream is secretly a Fake_SourceMediaStream,
   459   // so now we can start it pulling from us
   460   Fake_SourceMediaStream *fs = static_cast<Fake_SourceMediaStream *>(ms->GetStream());
   462   test_utils->sts_target()->Dispatch(
   463     WrapRunnable(fs, &Fake_SourceMediaStream::Start),
   464     NS_DISPATCH_NORMAL);
   466   return NS_OK;
   467 }
   469 NS_IMETHODIMP
   470 TestObserver::OnRemoveStream(ER&)
   471 {
   472   state = stateSuccess;
   473   return NS_OK;
   474 }
   476 NS_IMETHODIMP
   477 TestObserver::OnAddTrack(ER&)
   478 {
   479   state = stateSuccess;
   480   return NS_OK;
   481 }
   483 NS_IMETHODIMP
   484 TestObserver::OnRemoveTrack(ER&)
   485 {
   486   state = stateSuccess;
   487   return NS_OK;
   488 }
   490 NS_IMETHODIMP
   491 TestObserver::OnIceCandidate(uint16_t level,
   492                              const char * mid,
   493                              const char * candidate, ER&)
   494 {
   495   std::cout << name << ": onIceCandidate [" << level << "/"
   496             << mid << "] " << candidate << std::endl;
   497   candidates.push_back(candidate);
   498   return NS_OK;
   499 }
   501 NS_IMETHODIMP
   502 TestObserver::OnAddIceCandidateSuccess(ER&)
   503 {
   504   lastStatusCode = sipcc::PeerConnectionImpl::kNoError;
   505   state = stateSuccess;
   506   std::cout << name << ": onAddIceCandidateSuccess" << std::endl;
   507   addIceSuccessCount++;
   508   return NS_OK;
   509 }
   511 NS_IMETHODIMP
   512 TestObserver::OnAddIceCandidateError(uint32_t code, const char *message, ER&)
   513 {
   514   lastStatusCode = static_cast<sipcc::PeerConnectionImpl::Error>(code);
   515   state = stateError;
   516   std::cout << name << ": onAddIceCandidateError = " << code
   517             << " (" << message << ")" << std::endl;
   518   return NS_OK;
   519 }
   521 class ParsedSDP {
   522  public:
   523   //Line number with the corresponding SDP line.
   524   typedef std::pair<int, std::string> SdpLine;
   526   ParsedSDP(std::string sdp):
   527     sdp_(),
   528     sdp_without_ice_(),
   529     ice_candidates_(),
   530     levels_(0),
   531     num_lines(0)
   532   {
   533     sdp_ = sdp;
   534     Parse();
   535   }
   537   void DeleteAllLines(std::string objType)
   538   {
   539     int count = sdp_map_.count(objType);
   540     std::cout << "Removing " << count << " lines from SDP (" << objType
   541               << ")" << std::endl;
   543     for (int i = 0; i < count; i++) {
   544       DeleteLine(objType);
   545     }
   546   }
   548   void DeleteLine(std::string objType)
   549   {
   550     ReplaceLine(objType, "");
   551   }
   553   // Replaces the first instance of objType in the SDP with
   554   // a new string.
   555   // If content is an empty string then the line will be removed
   556   void ReplaceLine(std::string objType, std::string content)
   557   {
   558     std::multimap<std::string, SdpLine>::iterator it;
   559     it = sdp_map_.find(objType);
   560     if(it != sdp_map_.end()) {
   561       SdpLine sdp_line_pair = (*it).second;
   562       int line_no = sdp_line_pair.first;
   563       sdp_map_.erase(it);
   564       if(content.empty()) {
   565         return;
   566       }
   567       std::string value = content.substr(objType.length() + 1);
   568       sdp_map_.insert(std::pair<std::string, SdpLine>(objType,
   569         std::make_pair(line_no,value)));
   570     }
   571   }
   573   void AddLine(std::string content)
   574   {
   575     size_t whiteSpace = content.find(' ');
   576     std::string key;
   577     std::string value;
   578     if(whiteSpace == std::string::npos) {
   579       key = content.substr(0,  content.size() - 2);
   580       value = "";
   581     } else {
   582       key = content.substr(0, whiteSpace);
   583       value = content.substr(whiteSpace+1);
   584     }
   585     sdp_map_.insert(std::pair<std::string, SdpLine>(key,
   586       std::make_pair(num_lines,value)));
   587     num_lines++;
   588   }
   590   // Returns the values for all lines of the indicated type
   591   // Removes trailing "\r\n" from values.
   592   std::vector<std::string> GetLines(std::string objType) const
   593   {
   594     std::multimap<std::string, SdpLine>::const_iterator it, end;
   595     std::vector<std::string> values;
   596     it = sdp_map_.lower_bound(objType);
   597     end = sdp_map_.upper_bound(objType);
   598     while (it != end) {
   599       std::string value = it->second.second;
   600       if (value.find("\r") != std::string::npos) {
   601         value = value.substr(0, value.find("\r"));
   602       } else {
   603         ADD_FAILURE();
   604       }
   605       values.push_back(value);
   606       ++it;
   607     }
   608     return values;
   609   }
   611   //Parse SDP as std::string into map that looks like:
   612   // key: sdp content till first space
   613   // value : <line_number, sdp content after the first space>
   614   void Parse()
   615   {
   616     size_t prev = 0;
   617     size_t found = 0;
   618     num_lines = 0;
   619     for(;;) {
   620       found = sdp_.find('\n', found + 1);
   621       if (found == std::string::npos)
   622         break;
   623       std::string line = sdp_.substr(prev, (found - prev) + 1);
   624       size_t whiteSpace = line.find(' ');
   625       std::string key;
   626       std::string value;
   627       if(whiteSpace == std::string::npos) {
   628         //this is the line with no extra contents
   629         //example, v=0, a=sendrecv
   630         key = line.substr(0, line.size() - 2);
   631         //<line_no>:<valeu>
   632         value = "";
   633       } else {
   634         key = line.substr(0, whiteSpace);
   635         //<line_no>:<value>
   636         value = line.substr(whiteSpace+1);
   637       }
   638       SdpLine sdp_line_pair = std::make_pair(num_lines,value);
   639       sdp_map_.insert(std::pair<std::string, SdpLine>(key, sdp_line_pair));
   640       num_lines++;
   641       //storing ice candidates separately for quick acesss as needed
   642       //for the trickle unit tests
   643       if (line.find("a=candidate") == 0) {
   644         // This is a candidate, strip of a= and \r\n
   645         std::string cand = line.substr(2, line.size() - 4);
   646         ice_candidates_.insert(std::pair<int, std::string>(levels_, cand));
   647        } else {
   648         sdp_without_ice_ += line;
   649       }
   650       if (line.find("m=") == 0) {
   651         // This is an m-line
   652         ++levels_;
   653       }
   654       prev = found + 1;
   655     }
   656   }
   658   //Convert Internal SDP representation into String representation
   659   std::string getSdp()
   660   {
   661      std::vector<std::string> sdp_lines(num_lines);
   662      for (std::multimap<std::string, SdpLine>::iterator it = sdp_map_.begin();
   663          it != sdp_map_.end(); ++it) {
   665       SdpLine sdp_line_pair = (*it).second;
   666       std::string value;
   667       if(sdp_line_pair.second.length() == 0) {
   668         value = (*it).first + "\r\n";
   669         sdp_lines[sdp_line_pair.first] = value;
   670       } else {
   671         value = (*it).first + ' ' + sdp_line_pair.second;
   672         sdp_lines[sdp_line_pair.first] = value;
   673       }
   674    }
   676     //generate our final sdp in std::string format
   677     std::string sdp;
   678     for (size_t i = 0; i < sdp_lines.size(); i++)
   679     {
   680       sdp += sdp_lines[i];
   681     }
   683     return sdp;
   684   }
   688   std::string sdp_;
   689   std::string sdp_without_ice_;
   690   std::multimap<int, std::string> ice_candidates_;
   691   std::multimap<std::string, SdpLine> sdp_map_;
   692   int levels_;
   693   int num_lines;
   694 };
   696 class SignalingAgent {
   697  public:
   698   SignalingAgent(const std::string &aName) : pc(nullptr), name(aName) {
   699     cfg_.addStunServer(g_stun_server_address, g_stun_server_port);
   701     pc = sipcc::PeerConnectionImpl::CreatePeerConnection();
   702     EXPECT_TRUE(pc);
   703   }
   705   SignalingAgent(const std::string &aName, const std::string stun_addr,
   706                  uint16_t stun_port) : pc(nullptr), name(aName) {
   707     cfg_.addStunServer(stun_addr, stun_port);
   709     pc = sipcc::PeerConnectionImpl::CreatePeerConnection();
   710     EXPECT_TRUE(pc);
   711   }
   714   ~SignalingAgent() {
   715     mozilla::SyncRunnable::DispatchToThread(gMainThread,
   716       WrapRunnable(this, &SignalingAgent::Close));
   717   }
   719   void Init_m(nsCOMPtr<nsIThread> thread)
   720   {
   721     pObserver = new TestObserver(pc, name);
   722     ASSERT_TRUE(pObserver);
   724     ASSERT_EQ(pc->Initialize(*pObserver, nullptr, cfg_, thread), NS_OK);
   725   }
   727   void Init(nsCOMPtr<nsIThread> thread)
   728   {
   729     mozilla::SyncRunnable::DispatchToThread(thread,
   730       WrapRunnable(this, &SignalingAgent::Init_m, thread));
   732     ASSERT_TRUE_WAIT(sipcc_state() == PCImplSipccState::Started,
   733                      kDefaultTimeout);
   734   }
   736   void WaitForGather() {
   737     ASSERT_TRUE_WAIT(ice_gathering_state() == PCImplIceGatheringState::Complete,
   738                      kDefaultTimeout);
   740     std::cout << name << ": Init Complete" << std::endl;
   741   }
   743   bool WaitForGatherAllowFail() {
   744     EXPECT_TRUE_WAIT(
   745         ice_gathering_state() == PCImplIceGatheringState::Complete ||
   746         ice_connection_state() == PCImplIceConnectionState::Failed,
   747         kDefaultTimeout);
   749     if (ice_connection_state() == PCImplIceConnectionState::Failed) {
   750       std::cout << name << ": Init Failed" << std::endl;
   751       return false;
   752     }
   754     std::cout << name << "Init Complete" << std::endl;
   755     return true;
   756   }
   758   PCImplSipccState sipcc_state()
   759   {
   760     return pc->SipccState();
   761   }
   763   PCImplIceConnectionState ice_connection_state()
   764   {
   765     return pc->IceConnectionState();
   766   }
   768   PCImplIceGatheringState ice_gathering_state()
   769   {
   770     return pc->IceGatheringState();
   771   }
   773   PCImplSignalingState signaling_state()
   774   {
   775     return pc->SignalingState();
   776   }
   778   void Close()
   779   {
   780     if (pc) {
   781       std::cout << name << ": Close" << std::endl;
   783       pc->Close();
   784       pc = nullptr;
   785     }
   787     // Shutdown is synchronous evidently.
   788     // ASSERT_TRUE(pObserver->WaitForObserverCall());
   789     // ASSERT_EQ(pc->sipcc_state(), sipcc::PeerConnectionInterface::kIdle);
   790   }
   792   bool OfferContains(const std::string& str) {
   793     std::string o(offer());
   795     return o.find(str) != std::string::npos;
   796   }
   798   bool AnswerContains(const std::string& str) {
   799     std::string o(answer());
   801     return o.find(str) != std::string::npos;
   802   }
   804   size_t MatchingCandidates(const std::string& cand) {
   805     return pObserver->MatchingCandidates(cand);
   806   }
   808   char* offer() const { return offer_; }
   809   char* answer() const { return answer_; }
   811   std::string getLocalDescription() const {
   812     char *sdp = nullptr;
   813     pc->GetLocalDescription(&sdp);
   814     if (!sdp) {
   815       return "";
   816     }
   817     return sdp;
   818   }
   820   std::string getRemoteDescription() const {
   821     char *sdp = 0;
   822     pc->GetRemoteDescription(&sdp);
   823     if (!sdp) {
   824       return "";
   825     }
   826     return sdp;
   827   }
   829   // Adds a stream to the PeerConnection.
   830   void AddStream(uint32_t hint =
   831          DOMMediaStream::HINT_CONTENTS_AUDIO |
   832          DOMMediaStream::HINT_CONTENTS_VIDEO,
   833        MediaStream *stream = nullptr,
   834        sipcc::MediaConstraints *constraints = nullptr
   835        ) {
   837     sipcc::MediaConstraints noConstraints;
   838     if (!constraints) {
   839       constraints = &noConstraints;
   840     }
   842     nsRefPtr<DOMMediaStream> domMediaStream;
   843     if (stream) {
   844       domMediaStream = new DOMMediaStream(stream);
   845     } else {
   846       domMediaStream = new DOMMediaStream();
   847     }
   849     domMediaStream->SetHintContents(hint);
   850     ASSERT_EQ(pc->AddStream(*domMediaStream, *constraints), NS_OK);
   851     domMediaStream_ = domMediaStream;
   852   }
   855   // Removes a stream from the PeerConnection. If the stream
   856   // parameter is absent, removes the stream that was most
   857   // recently added to the PeerConnection.
   858   void RemoveLastStreamAdded() {
   859     ASSERT_EQ(pc->RemoveStream(*domMediaStream_), NS_OK);
   860   }
   862   void CreateOffer(sipcc::MediaConstraints& constraints,
   863                    uint32_t offerFlags, uint32_t sdpCheck,
   864                    PCImplSignalingState endState =
   865                      PCImplSignalingState::SignalingStable) {
   867     // Create a media stream as if it came from GUM
   868     Fake_AudioStreamSource *audio_stream =
   869       new Fake_AudioStreamSource();
   871     nsresult ret;
   872     mozilla::SyncRunnable::DispatchToThread(
   873       test_utils->sts_target(),
   874       WrapRunnableRet(audio_stream, &Fake_MediaStream::Start, &ret));
   876     ASSERT_TRUE(NS_SUCCEEDED(ret));
   878     uint32_t aHintContents = 0;
   879     if (offerFlags & OFFER_AUDIO) {
   880       aHintContents |= DOMMediaStream::HINT_CONTENTS_AUDIO;
   881     }
   882     if (offerFlags & OFFER_VIDEO) {
   883       aHintContents |= DOMMediaStream::HINT_CONTENTS_VIDEO;
   884     }
   885     AddStream(aHintContents, audio_stream);
   887     // Now call CreateOffer as JS would
   888     pObserver->state = TestObserver::stateNoResponse;
   889     ASSERT_EQ(pc->CreateOffer(constraints), NS_OK);
   890     ASSERT_TRUE_WAIT(pObserver->state != TestObserver::stateNoResponse,
   891                      kDefaultTimeout);
   892     ASSERT_EQ(pObserver->state, TestObserver::stateSuccess);
   893     SDPSanityCheck(pObserver->lastString, sdpCheck, true);
   894     ASSERT_EQ(signaling_state(), endState);
   895     offer_ = pObserver->lastString;
   896   }
   898 void CreateAnswer(sipcc::MediaConstraints& constraints, std::string offer,
   899                     uint32_t offerAnswerFlags,
   900                     uint32_t sdpCheck = DONT_CHECK_AUDIO|
   901                                         DONT_CHECK_VIDEO|
   902                                         DONT_CHECK_DATA,
   903                     PCImplSignalingState endState =
   904                     PCImplSignalingState::SignalingHaveRemoteOffer) {
   906     uint32_t aHintContents = 0;
   907     if (offerAnswerFlags & ANSWER_AUDIO) {
   908       aHintContents |= DOMMediaStream::HINT_CONTENTS_AUDIO;
   909     }
   910     if (offerAnswerFlags & ANSWER_VIDEO) {
   911       aHintContents |= DOMMediaStream::HINT_CONTENTS_VIDEO;
   912     }
   913     AddStream(aHintContents);
   915     // Decide if streams are disabled for offer or answer
   916     // then perform SDP checking based on which stream disabled
   917     pObserver->state = TestObserver::stateNoResponse;
   918     ASSERT_EQ(pc->CreateAnswer(constraints), NS_OK);
   919     ASSERT_TRUE_WAIT(pObserver->state != TestObserver::stateNoResponse,
   920                      kDefaultTimeout);
   921     ASSERT_EQ(pObserver->state, TestObserver::stateSuccess);
   922     SDPSanityCheck(pObserver->lastString, sdpCheck, false);
   923     ASSERT_EQ(signaling_state(), endState);
   925     answer_ = pObserver->lastString;
   926   }
   928   // At present, we use the hints field in a stream to find and
   929   // remove it. This only works if the specified hints flags are
   930   // unique among all streams in the PeerConnection. This is not
   931   // generally true, and will need significant revision once
   932   // multiple streams are supported.
   933   void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints,
   934                                uint32_t hints, uint32_t sdpCheck) {
   936     domMediaStream_->SetHintContents(hints);
   938     // This currently "removes" a stream that has the same audio/video
   939     // hints as were passed in.
   940     // When complete RemoveStream will remove and entire stream and its tracks
   941     // not just disable a track as this is currently doing
   942     ASSERT_EQ(pc->RemoveStream(*domMediaStream_), NS_OK);
   944     // Now call CreateOffer as JS would
   945     pObserver->state = TestObserver::stateNoResponse;
   946     ASSERT_EQ(pc->CreateOffer(constraints), NS_OK);
   947     ASSERT_TRUE_WAIT(pObserver->state != TestObserver::stateNoResponse,
   948                      kDefaultTimeout);
   949     ASSERT_TRUE(pObserver->state == TestObserver::stateSuccess);
   950     SDPSanityCheck(pObserver->lastString, sdpCheck, true);
   951     offer_ = pObserver->lastString;
   952   }
   954   void SetRemote(TestObserver::Action action, std::string remote,
   955                  bool ignoreError = false,
   956                  PCImplSignalingState endState =
   957                    PCImplSignalingState::SignalingInvalid) {
   959     if (endState == PCImplSignalingState::SignalingInvalid) {
   960       endState = (action == TestObserver::OFFER ?
   961                   PCImplSignalingState::SignalingHaveRemoteOffer :
   962                   PCImplSignalingState::SignalingStable);
   963     }
   965     pObserver->state = TestObserver::stateNoResponse;
   966     ASSERT_EQ(pc->SetRemoteDescription(action, remote.c_str()), NS_OK);
   967     ASSERT_TRUE_WAIT(pObserver->state != TestObserver::stateNoResponse,
   968                      kDefaultTimeout);
   969     ASSERT_EQ(signaling_state(), endState);
   970     if (!ignoreError) {
   971       ASSERT_EQ(pObserver->state, TestObserver::stateSuccess);
   972     }
   973   }
   975   void SetLocal(TestObserver::Action action, std::string local,
   976                 bool ignoreError = false,
   977                 PCImplSignalingState endState =
   978                   PCImplSignalingState::SignalingInvalid) {
   980     if (endState == PCImplSignalingState::SignalingInvalid) {
   981       endState = (action == TestObserver::OFFER ?
   982                   PCImplSignalingState::SignalingHaveLocalOffer :
   983                   PCImplSignalingState::SignalingStable);
   984     }
   986     pObserver->state = TestObserver::stateNoResponse;
   987     ASSERT_EQ(pc->SetLocalDescription(action, local.c_str()), NS_OK);
   988     ASSERT_TRUE_WAIT(pObserver->state != TestObserver::stateNoResponse,
   989                      kDefaultTimeout);
   990     ASSERT_EQ(signaling_state(), endState);
   991     if (!ignoreError) {
   992       ASSERT_EQ(pObserver->state, TestObserver::stateSuccess);
   993     }
   994   }
   996   void DoTrickleIce(ParsedSDP &sdp) {
   997     int expectAddIce = 0;
   998     pObserver->addIceSuccessCount = 0;
   999     for (std::multimap<int, std::string>::iterator it =
  1000            sdp.ice_candidates_.begin();
  1001          it != sdp.ice_candidates_.end(); ++it) {
  1002       if ((*it).first != 0) {
  1003         std::cerr << "Adding trickle ICE candidate " << (*it).second
  1004                   << std::endl;
  1005         ASSERT_TRUE(NS_SUCCEEDED(pc->AddIceCandidate((*it).second.c_str(), "", (*it).first)));
  1006         expectAddIce++;
  1009     ASSERT_TRUE_WAIT(pObserver->addIceSuccessCount == expectAddIce,
  1010                      kDefaultTimeout);
  1014   void DoTrickleIceChrome(ParsedSDP &sdp) {
  1015     int expectAddIce = 0;
  1016     pObserver->addIceSuccessCount = 0;
  1017     for (std::multimap<int, std::string>::iterator it =
  1018            sdp.ice_candidates_.begin();
  1019          it != sdp.ice_candidates_.end(); ++it) {
  1020       if ((*it).first != 0) {
  1021         std::string candidate = "a=" + (*it).second + "\r\n";
  1022         std::cerr << "Adding trickle ICE candidate " << candidate << std::endl;
  1024         ASSERT_TRUE(NS_SUCCEEDED(pc->AddIceCandidate(candidate.c_str(), "", (*it).first)));
  1025         expectAddIce++;
  1028     ASSERT_TRUE_WAIT(pObserver->addIceSuccessCount == expectAddIce,
  1029                      kDefaultTimeout);
  1033   bool IceCompleted() {
  1034     return pc->IceConnectionState() == PCImplIceConnectionState::Connected;
  1037   void AddIceCandidate(const char* candidate, const char* mid, unsigned short level,
  1038                        bool expectSuccess) {
  1039     PCImplSignalingState endState = signaling_state();
  1040     pObserver->state = TestObserver::stateNoResponse;
  1041     pc->AddIceCandidate(candidate, mid, level);
  1042     ASSERT_TRUE_WAIT(pObserver->state != TestObserver::stateNoResponse,
  1043                      kDefaultTimeout);
  1044     ASSERT_TRUE(pObserver->state ==
  1045                 expectSuccess ? TestObserver::stateSuccess :
  1046                                 TestObserver::stateError
  1047                );
  1049     // Verify that adding ICE candidates does not change the signaling state
  1050     ASSERT_EQ(signaling_state(), endState);
  1053   int GetPacketsReceived(int stream) {
  1054     std::vector<DOMMediaStream *> streams = pObserver->GetStreams();
  1056     if ((int) streams.size() <= stream) {
  1057       return 0;
  1060     return streams[stream]->GetStream()->AsSourceStream()->GetSegmentsAdded();
  1063   int GetPacketsSent(int stream) {
  1064     return static_cast<Fake_MediaStreamBase *>(
  1065         domMediaStream_->GetStream())->GetSegmentsAdded();
  1068   //Stops generating new audio data for transmission.
  1069   //Should be called before Cleanup of the peer connection.
  1070   void CloseSendStreams() {
  1071     static_cast<Fake_MediaStream*>(
  1072         domMediaStream_->GetStream())->StopStream();
  1075   //Stops pulling audio data off the receivers.
  1076   //Should be called before Cleanup of the peer connection.
  1077   void CloseReceiveStreams() {
  1078     std::vector<DOMMediaStream *> streams =
  1079                             pObserver->GetStreams();
  1080     for (size_t i = 0; i < streams.size(); i++) {
  1081       streams[i]->GetStream()->AsSourceStream()->StopStream();
  1085   mozilla::RefPtr<mozilla::MediaPipeline> GetMediaPipeline(
  1086     bool local, int stream, int track) {
  1087     sipcc::SourceStreamInfo *streamInfo;
  1089     if (local) {
  1090       streamInfo = pc->media()->GetLocalStream(stream);
  1091     } else {
  1092       streamInfo = pc->media()->GetRemoteStream(stream);
  1095     if (!streamInfo) {
  1096       return nullptr;
  1099     const auto &pipelines = streamInfo->GetPipelines();
  1100     auto it = pipelines.find(track);
  1101     return (it == pipelines.end())? nullptr : it->second;
  1104   void CheckMediaPipeline(int stream, int track, uint32_t flags,
  1105     VideoSessionConduit::FrameRequestType frameRequestMethod =
  1106       VideoSessionConduit::FrameRequestNone) {
  1108     std::cout << name << ": Checking media pipeline settings for "
  1109               << ((flags & PIPELINE_LOCAL) ? "local " : "remote ")
  1110               << ((flags & PIPELINE_SEND) ? "sending " : "receiving ")
  1111               << ((flags & PIPELINE_VIDEO) ? "video" : "audio")
  1112               << " pipeline (stream " << stream
  1113               << ", track " << track << "); expect "
  1114               << ((flags & PIPELINE_RTCP_MUX) ? "MUX, " : "no MUX, ")
  1115               << ((flags & PIPELINE_RTCP_NACK) ? "NACK." : "no NACK.")
  1116               << std::endl;
  1118     mozilla::RefPtr<mozilla::MediaPipeline> pipeline =
  1119       GetMediaPipeline((flags & PIPELINE_LOCAL), stream, track);
  1120     ASSERT_TRUE(pipeline);
  1121     ASSERT_EQ(pipeline->IsDoingRtcpMux(), !!(flags & PIPELINE_RTCP_MUX));
  1122     // We cannot yet test send/recv with video.
  1123     if (!(flags & PIPELINE_VIDEO)) {
  1124       if (flags & PIPELINE_SEND) {
  1125         ASSERT_TRUE_WAIT(pipeline->rtp_packets_sent() >= 40 &&
  1126                          pipeline->rtcp_packets_received() >= 1,
  1127                          kDefaultTimeout);
  1128         ASSERT_GE(pipeline->rtp_packets_sent(), 40);
  1129         ASSERT_GE(pipeline->rtcp_packets_received(), 1);
  1130       } else {
  1131         ASSERT_TRUE_WAIT(pipeline->rtp_packets_received() >= 40 &&
  1132                          pipeline->rtcp_packets_sent() >= 1,
  1133                          kDefaultTimeout);
  1134         ASSERT_GE(pipeline->rtp_packets_received(), 40);
  1135         ASSERT_GE(pipeline->rtcp_packets_sent(), 1);
  1140     // Check feedback method for video
  1141     if (flags & PIPELINE_VIDEO) {
  1142         mozilla::MediaSessionConduit *conduit = pipeline->Conduit();
  1143         ASSERT_TRUE(conduit);
  1144         ASSERT_EQ(conduit->type(), mozilla::MediaSessionConduit::VIDEO);
  1145         mozilla::VideoSessionConduit *video_conduit =
  1146           static_cast<mozilla::VideoSessionConduit*>(conduit);
  1147         ASSERT_EQ(!!(flags & PIPELINE_RTCP_NACK),
  1148                   video_conduit->UsingNackBasic());
  1149         ASSERT_EQ(frameRequestMethod, video_conduit->FrameRequestMethod());
  1153 public:
  1154   mozilla::RefPtr<sipcc::PeerConnectionImpl> pc;
  1155   nsRefPtr<TestObserver> pObserver;
  1156   char* offer_;
  1157   char* answer_;
  1158   nsRefPtr<DOMMediaStream> domMediaStream_;
  1159   sipcc::IceConfiguration cfg_;
  1160   const std::string name;
  1162 private:
  1163   void SDPSanityCheck(std::string sdp, uint32_t flags, bool offer)
  1165     ASSERT_TRUE(pObserver->state == TestObserver::stateSuccess);
  1166     ASSERT_NE(sdp.find("v=0"), std::string::npos);
  1167     ASSERT_NE(sdp.find("c=IN IP4"), std::string::npos);
  1168     ASSERT_NE(sdp.find("a=fingerprint:sha-256"), std::string::npos);
  1170     std::cout << name << ": SDPSanityCheck flags for "
  1171               << (offer ? "offer" : "answer")
  1172               << " = " << std::hex << std::showbase
  1173               << flags << std::dec
  1175               << ((flags & SHOULD_SEND_AUDIO)?" SHOULD_SEND_AUDIO":"")
  1176               << ((flags & SHOULD_RECV_AUDIO)?" SHOULD_RECV_AUDIO":"")
  1177               << ((flags & SHOULD_INACTIVE_AUDIO)?" SHOULD_INACTIVE_AUDIO":"")
  1178               << ((flags & SHOULD_REJECT_AUDIO)?" SHOULD_REJECT_AUDIO":"")
  1179               << ((flags & SHOULD_OMIT_AUDIO)?" SHOULD_OMIT_AUDIO":"")
  1180               << ((flags & DONT_CHECK_AUDIO)?" DONT_CHECK_AUDIO":"")
  1182               << ((flags & SHOULD_SEND_VIDEO)?" SHOULD_SEND_VIDEO":"")
  1183               << ((flags & SHOULD_RECV_VIDEO)?" SHOULD_RECV_VIDEO":"")
  1184               << ((flags & SHOULD_INACTIVE_VIDEO)?" SHOULD_INACTIVE_VIDEO":"")
  1185               << ((flags & SHOULD_REJECT_VIDEO)?" SHOULD_REJECT_VIDEO":"")
  1186               << ((flags & SHOULD_OMIT_VIDEO)?" SHOULD_OMIT_VIDEO":"")
  1187               << ((flags & DONT_CHECK_VIDEO)?" DONT_CHECK_VIDEO":"")
  1189               << ((flags & SHOULD_INCLUDE_DATA)?" SHOULD_INCLUDE_DATA":"")
  1190               << ((flags & DONT_CHECK_DATA)?" DONT_CHECK_DATA":"")
  1191               << std::endl;
  1193     switch(flags & AUDIO_FLAGS) {
  1194       case 0:
  1195             ASSERT_EQ(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
  1196         break;
  1197       case SHOULD_CHECK_AUDIO:
  1198             ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
  1199             if (offer) {
  1200               ASSERT_NE(sdp.find("a=rtpmap:0 PCMU/8000"), std::string::npos);
  1202         break;
  1203       case SHOULD_SEND_AUDIO:
  1204             ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
  1205             ASSERT_NE(sdp.find(" 0-15\r\na=sendonly"), std::string::npos);
  1206             if (offer) {
  1207               ASSERT_NE(sdp.find("a=rtpmap:0 PCMU/8000"), std::string::npos);
  1209         break;
  1210       case SHOULD_RECV_AUDIO:
  1211             ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
  1212             ASSERT_NE(sdp.find(" 0-15\r\na=recvonly"), std::string::npos);
  1213             if (offer) {
  1214               ASSERT_NE(sdp.find("a=rtpmap:0 PCMU/8000"), std::string::npos);
  1216         break;
  1217       case SHOULD_SENDRECV_AUDIO:
  1218             ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
  1219             ASSERT_NE(sdp.find(" 0-15\r\na=sendrecv"), std::string::npos);
  1220             if (offer) {
  1221               ASSERT_NE(sdp.find("a=rtpmap:0 PCMU/8000"), std::string::npos);
  1223         break;
  1224       case SHOULD_INACTIVE_AUDIO:
  1225             ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
  1226             ASSERT_NE(sdp.find(" 0-15\r\na=inactive"), std::string::npos);
  1227         break;
  1228       case SHOULD_REJECT_AUDIO:
  1229             ASSERT_EQ(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
  1230             ASSERT_NE(sdp.find("m=audio 0 "), std::string::npos);
  1231         break;
  1232       case SHOULD_OMIT_AUDIO:
  1233             ASSERT_EQ(sdp.find("m=audio"), std::string::npos);
  1234         break;
  1235       case DONT_CHECK_AUDIO:
  1236         break;
  1237       default:
  1238             ASSERT_FALSE("Missing case in switch statement");
  1241     switch(flags & VIDEO_FLAGS) {
  1242       case 0:
  1243             ASSERT_EQ(sdp.find("a=rtpmap:120 VP8/90000"), std::string::npos);
  1244         break;
  1245       case SHOULD_CHECK_VIDEO:
  1246             ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000"), std::string::npos);
  1247         break;
  1248       case SHOULD_SEND_VIDEO:
  1249             ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=sendonly"),
  1250                   std::string::npos);
  1251         break;
  1252       case SHOULD_RECV_VIDEO:
  1253             ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=recvonly"),
  1254                   std::string::npos);
  1255         break;
  1256       case SHOULD_SENDRECV_VIDEO:
  1257             ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=sendrecv"),
  1258                   std::string::npos);
  1259         break;
  1260       case SHOULD_INACTIVE_VIDEO:
  1261             ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=inactive"),
  1262                       std::string::npos);
  1263         break;
  1264       case SHOULD_REJECT_VIDEO:
  1265             ASSERT_NE(sdp.find("m=video 0 "), std::string::npos);
  1266         break;
  1267       case SHOULD_OMIT_VIDEO:
  1268             ASSERT_EQ(sdp.find("m=video"), std::string::npos);
  1269         break;
  1270       case DONT_CHECK_VIDEO:
  1271         break;
  1272       default:
  1273             ASSERT_FALSE("Missing case in switch statement");
  1276     if (flags & SHOULD_INCLUDE_DATA) {
  1277       ASSERT_NE(sdp.find("m=application"), std::string::npos);
  1278     } else if (!(flags & DONT_CHECK_DATA)) {
  1279       ASSERT_EQ(sdp.find("m=application"), std::string::npos);
  1282 };
  1284 class SignalingEnvironment : public ::testing::Environment {
  1285  public:
  1286   void TearDown() {
  1287     // Signaling is shut down in XPCOM shutdown
  1289 };
  1291 class SignalingAgentTest : public ::testing::Test {
  1292  public:
  1293   static void SetUpTestCase() {
  1296   void TearDown() {
  1297     // Delete all the agents.
  1298     for (size_t i=0; i < agents_.size(); i++) {
  1299       delete agents_[i];
  1303   bool CreateAgent() {
  1304     return CreateAgent(g_stun_server_address, g_stun_server_port);
  1307   bool CreateAgent(const std::string stun_addr, uint16_t stun_port,
  1308                    bool wait_for_gather = true) {
  1309     ScopedDeletePtr<SignalingAgent> agent(
  1310         new SignalingAgent("agent", stun_addr, stun_port));
  1312     agent->Init(gMainThread);
  1314     if (wait_for_gather) {
  1315       if (!agent->WaitForGatherAllowFail())
  1316         return false;
  1319     agents_.push_back(agent.forget());
  1321     return true;
  1324   void CreateAgentNoInit() {
  1325     ScopedDeletePtr<SignalingAgent> agent(new SignalingAgent("agent"));
  1326     agents_.push_back(agent.forget());
  1329   SignalingAgent *agent(size_t i) {
  1330     return agents_[i];
  1333  private:
  1334   std::vector<SignalingAgent *> agents_;
  1335 };
  1338 class SignalingTest : public ::testing::Test {
  1339 public:
  1340   SignalingTest()
  1341       : init_(false),
  1342         a1_(nullptr),
  1343         a2_(nullptr),
  1344         wait_for_gather_(true),
  1345         stun_addr_(g_stun_server_address),
  1346         stun_port_(g_stun_server_port) {}
  1348   SignalingTest(const std::string& stun_addr, uint16_t stun_port)
  1349       : a1_(nullptr),
  1350         a2_(nullptr),
  1351         wait_for_gather_(true),
  1352         stun_addr_(stun_addr),
  1353         stun_port_(stun_port) {}
  1355   static void SetUpTestCase() {
  1358   void EnsureInit() {
  1360     if (init_)
  1361       return;
  1363     a1_ = new SignalingAgent(callerName, stun_addr_, stun_port_);
  1364     a2_ = new SignalingAgent(calleeName, stun_addr_, stun_port_);
  1366     a1_->Init(gMainThread);
  1367     a2_->Init(gMainThread);
  1369     if (wait_for_gather_) {
  1370       WaitForGather();
  1374   void WaitForGather() {
  1375     a1_->WaitForGather();
  1376     a2_->WaitForGather();
  1379   static void TearDownTestCase() {
  1382   void CreateOffer(sipcc::MediaConstraints& constraints,
  1383                    uint32_t offerFlags, uint32_t sdpCheck) {
  1384     EnsureInit();
  1385     a1_->CreateOffer(constraints, offerFlags, sdpCheck);
  1388   void CreateSetOffer(sipcc::MediaConstraints& constraints, uint32_t sdpCheck) {
  1389     EnsureInit();
  1390     a1_->CreateOffer(constraints, OFFER_AV, sdpCheck);
  1391     a1_->SetLocal(TestObserver::OFFER, a1_->offer());
  1394   void OfferAnswer(sipcc::MediaConstraints& aconstraints,
  1395                    sipcc::MediaConstraints& bconstraints,
  1396                    uint32_t offerAnswerFlags,
  1397                    bool finishAfterAnswer, uint32_t offerSdpCheck,
  1398                    uint32_t answerSdpCheck) {
  1399     EnsureInit();
  1400     a1_->CreateOffer(aconstraints, offerAnswerFlags, offerSdpCheck);
  1401     a1_->SetLocal(TestObserver::OFFER, a1_->offer());
  1402     a2_->SetRemote(TestObserver::OFFER, a1_->offer());
  1403     a2_->CreateAnswer(bconstraints, a1_->offer(),
  1404                      offerAnswerFlags, answerSdpCheck);
  1405     if(true == finishAfterAnswer) {
  1406         a2_->SetLocal(TestObserver::ANSWER, a2_->answer());
  1407         a1_->SetRemote(TestObserver::ANSWER, a2_->answer());
  1409         ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
  1410         ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
  1414   void OfferModifiedAnswer(sipcc::MediaConstraints& aconstraints,
  1415                            sipcc::MediaConstraints& bconstraints,
  1416                            uint32_t offerSdpCheck, uint32_t answerSdpCheck) {
  1417     EnsureInit();
  1418     a1_->CreateOffer(aconstraints, OFFER_AUDIO, offerSdpCheck);
  1419     a1_->SetLocal(TestObserver::OFFER, a1_->offer());
  1420     a2_->SetRemote(TestObserver::OFFER, a1_->offer());
  1421     a2_->CreateAnswer(bconstraints, a1_->offer(), OFFER_AUDIO | ANSWER_AUDIO,
  1422                      answerSdpCheck);
  1423     a2_->SetLocal(TestObserver::ANSWER, a2_->answer());
  1424     ParsedSDP sdpWrapper(a2_->answer());
  1425     sdpWrapper.ReplaceLine("m=audio", "m=audio 65375 RTP/SAVPF 109 8 101\r\n");
  1426     sdpWrapper.AddLine("a=rtpmap:8 PCMA/8000\r\n");
  1427     std::cout << "Modified SDP " << std::endl
  1428               << indent(sdpWrapper.getSdp()) << std::endl;
  1429     a1_->SetRemote(TestObserver::ANSWER, sdpWrapper.getSdp());
  1430     ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
  1431     ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
  1434   void OfferAnswerTrickle(sipcc::MediaConstraints& aconstraints,
  1435                           sipcc::MediaConstraints& bconstraints,
  1436                           uint32_t offerSdpCheck, uint32_t answerSdpCheck) {
  1437     EnsureInit();
  1438     a1_->CreateOffer(aconstraints, OFFER_AV, offerSdpCheck);
  1439     a1_->SetLocal(TestObserver::OFFER, a1_->offer());
  1440     ParsedSDP a1_offer(a1_->offer());
  1441     a2_->SetRemote(TestObserver::OFFER, a1_offer.sdp_without_ice_);
  1442     a2_->CreateAnswer(bconstraints, a1_offer.sdp_without_ice_,
  1443                      OFFER_AV|ANSWER_AV, answerSdpCheck);
  1444     a2_->SetLocal(TestObserver::ANSWER, a2_->answer());
  1445     ParsedSDP a2_answer(a2_->answer());
  1446     a1_->SetRemote(TestObserver::ANSWER, a2_answer.sdp_without_ice_);
  1447     // Now set the trickle ICE candidates
  1448     a1_->DoTrickleIce(a2_answer);
  1449     a2_->DoTrickleIce(a1_offer);
  1450     ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
  1451     ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
  1455   void OfferAnswerTrickleChrome(sipcc::MediaConstraints& aconstraints,
  1456                           sipcc::MediaConstraints& bconstraints,
  1457                           uint32_t offerSdpCheck, uint32_t answerSdpCheck) {
  1458     EnsureInit();
  1459     a1_->CreateOffer(aconstraints, OFFER_AV, offerSdpCheck);
  1460     a1_->SetLocal(TestObserver::OFFER, a1_->offer());
  1461     ParsedSDP a1_offer(a1_->offer());
  1462     a2_->SetRemote(TestObserver::OFFER, a1_offer.sdp_without_ice_);
  1463     a2_->CreateAnswer(bconstraints, a1_offer.sdp_without_ice_,
  1464                      OFFER_AV|ANSWER_AV, answerSdpCheck);
  1465     a2_->SetLocal(TestObserver::ANSWER, a2_->answer());
  1466     ParsedSDP a2_answer(a2_->answer());
  1467     a1_->SetRemote(TestObserver::ANSWER, a2_answer.sdp_without_ice_);
  1468     // Now set the trickle ICE candidates
  1469     a1_->DoTrickleIceChrome(a2_answer);
  1470     a2_->DoTrickleIceChrome(a1_offer);
  1471     ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
  1472     ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
  1475   void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints,
  1476                                uint32_t hints, uint32_t sdpCheck) {
  1477     EnsureInit();
  1478     sipcc::MediaConstraints aconstraints;
  1479     aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1480     aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1481     a1_->CreateOffer(aconstraints, OFFER_AV, SHOULD_SENDRECV_AV );
  1482     a1_->CreateOfferRemoveStream(constraints, hints, sdpCheck);
  1485   void CreateOfferAudioOnly(sipcc::MediaConstraints& constraints,
  1486                             uint32_t sdpCheck) {
  1487     EnsureInit();
  1488     a1_->CreateOffer(constraints, OFFER_AUDIO, sdpCheck);
  1491   void CreateOfferAddCandidate(sipcc::MediaConstraints& constraints,
  1492                                const char * candidate, const char * mid,
  1493                                unsigned short level, uint32_t sdpCheck) {
  1494     EnsureInit();
  1495     a1_->CreateOffer(constraints, OFFER_AV, sdpCheck);
  1496     a1_->AddIceCandidate(candidate, mid, level, true);
  1499   void AddIceCandidateEarly(const char * candidate, const char * mid,
  1500                             unsigned short level) {
  1501     EnsureInit();
  1502     a1_->AddIceCandidate(candidate, mid, level, false);
  1505   void CheckRtcpFbSdp(const std::string &sdp,
  1506                       const std::set<std::string>& expected) {
  1508     std::set<std::string>::const_iterator it;
  1510     // Iterate through the list of expected feedback types and ensure
  1511     // that none of them are missing.
  1512     for (it = expected.begin(); it != expected.end(); ++it) {
  1513       std::string attr = std::string("\r\na=rtcp-fb:120 ") + (*it) + "\r\n";
  1514       std::cout << " - Checking for a=rtcp-fb: '" << *it << "'" << std::endl;
  1515       ASSERT_NE(sdp.find(attr), std::string::npos);
  1518     // Iterate through all of the rtcp-fb lines in the SDP and ensure
  1519     // that all of them are expected.
  1520     ParsedSDP sdpWrapper(sdp);
  1521     std::vector<std::string> values = sdpWrapper.GetLines("a=rtcp-fb:120");
  1522     std::vector<std::string>::iterator it2;
  1523     for (it2 = values.begin(); it2 != values.end(); ++it2) {
  1524       std::cout << " - Verifying that rtcp-fb is okay: '" << *it2
  1525                 << "'" << std::endl;
  1526       ASSERT_NE(0U, expected.count(*it2));
  1530   void TestRtcpFb(const std::set<std::string>& feedback,
  1531                   uint32_t rtcpFbFlags,
  1532                   VideoSessionConduit::FrameRequestType frameRequestMethod) {
  1533     EnsureInit();
  1534     sipcc::MediaConstraints constraints;
  1536     a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
  1537     a1_->SetLocal(TestObserver::OFFER, a1_->offer());
  1539     ParsedSDP sdpWrapper(a1_->offer());
  1541     // Strip out any existing rtcp-fb lines
  1542     sdpWrapper.DeleteAllLines("a=rtcp-fb:120");
  1544     // Add rtcp-fb lines for the desired feedback types
  1545     // We know that the video section is generated second (last),
  1546     // so appending these to the end of the SDP has the desired effect.
  1547     std::set<std::string>::const_iterator it;
  1548     for (it = feedback.begin(); it != feedback.end(); ++it) {
  1549       sdpWrapper.AddLine(std::string("a=rtcp-fb:120 ") + (*it) + "\r\n");
  1552     std::cout << "Modified SDP " << std::endl
  1553               << indent(sdpWrapper.getSdp()) << std::endl;
  1555     // Double-check that the offered SDP matches what we expect
  1556     CheckRtcpFbSdp(sdpWrapper.getSdp(), feedback);
  1558     a2_->SetRemote(TestObserver::OFFER, sdpWrapper.getSdp());
  1559     a2_->CreateAnswer(constraints, sdpWrapper.getSdp(), OFFER_AV | ANSWER_AV);
  1561     CheckRtcpFbSdp(a2_->answer(), feedback);
  1563     a2_->SetLocal(TestObserver::ANSWER, a2_->answer());
  1564     a1_->SetRemote(TestObserver::ANSWER, a2_->answer());
  1566     ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
  1567     ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
  1569     a1_->CloseSendStreams();
  1570     a1_->CloseReceiveStreams();
  1571     a2_->CloseSendStreams();
  1572     a2_->CloseReceiveStreams();
  1574     // Check caller video settings for remote pipeline
  1575     a1_->CheckMediaPipeline(0, 2, (fRtcpMux ? PIPELINE_RTCP_MUX : 0) |
  1576       PIPELINE_SEND | PIPELINE_VIDEO | rtcpFbFlags, frameRequestMethod);
  1578     // Check callee video settings for remote pipeline
  1579     a2_->CheckMediaPipeline(0, 2, (fRtcpMux ? PIPELINE_RTCP_MUX : 0) |
  1580       PIPELINE_VIDEO | rtcpFbFlags, frameRequestMethod);
  1583   void SetTestStunServer() {
  1584     stun_addr_ = TestStunServer::GetInstance()->addr();
  1585     stun_port_ = TestStunServer::GetInstance()->port();
  1587     TestStunServer::GetInstance()->SetActive(false);
  1588     TestStunServer::GetInstance()->SetResponseAddr(
  1589         kBogusSrflxAddress, kBogusSrflxPort);
  1592   // Check max-fs and max-fr in SDP
  1593   void CheckMaxFsFrSdp(const std::string sdp,
  1594                        int format,
  1595                        int max_fs,
  1596                        int max_fr) {
  1597     ParsedSDP sdpWrapper(sdp);
  1598     std::stringstream ss;
  1599     ss << "a=fmtp:" << format;
  1600     std::vector<std::string> lines = sdpWrapper.GetLines(ss.str());
  1602     // Both max-fs and max-fr not exist
  1603     if (lines.empty()) {
  1604       ASSERT_EQ(max_fs, 0);
  1605       ASSERT_EQ(max_fr, 0);
  1606       return;
  1609     // At most one instance allowed for each format
  1610     ASSERT_EQ(lines.size(), 1U);
  1612     std::string line = lines.front();
  1614     // Make sure that max-fs doesn't exist
  1615     if (max_fs == 0) {
  1616       ASSERT_EQ(line.find("max-fs="), std::string::npos);
  1618     // Check max-fs value
  1619     if (max_fs > 0) {
  1620       std::stringstream ss;
  1621       ss << "max-fs=" << max_fs;
  1622       ASSERT_NE(line.find(ss.str()), std::string::npos);
  1624     // Make sure that max-fr doesn't exist
  1625     if (max_fr == 0) {
  1626       ASSERT_EQ(line.find("max-fr="), std::string::npos);
  1628     // Check max-fr value
  1629     if (max_fr > 0) {
  1630       std::stringstream ss;
  1631       ss << "max-fr=" << max_fr;
  1632       ASSERT_NE(line.find(ss.str()), std::string::npos);
  1636  protected:
  1637   bool init_;
  1638   ScopedDeletePtr<SignalingAgent> a1_;  // Canonically "caller"
  1639   ScopedDeletePtr<SignalingAgent> a2_;  // Canonically "callee"
  1640   bool wait_for_gather_;
  1641   std::string stun_addr_;
  1642   uint16_t stun_port_;
  1643 };
  1645 static void SetIntPrefOnMainThread(nsCOMPtr<nsIPrefBranch> prefs,
  1646   const char *pref_name,
  1647   int new_value) {
  1648   MOZ_ASSERT(NS_IsMainThread());
  1649   prefs->SetIntPref(pref_name, new_value);
  1652 static void SetMaxFsFr(nsCOMPtr<nsIPrefBranch> prefs,
  1653   int max_fs,
  1654   int max_fr) {
  1655   gMainThread->Dispatch(
  1656     WrapRunnableNM(SetIntPrefOnMainThread,
  1657       prefs,
  1658       "media.navigator.video.max_fs",
  1659       max_fs),
  1660     NS_DISPATCH_SYNC);
  1662   gMainThread->Dispatch(
  1663     WrapRunnableNM(SetIntPrefOnMainThread,
  1664       prefs,
  1665       "media.navigator.video.max_fr",
  1666       max_fr),
  1667     NS_DISPATCH_SYNC);
  1670 class FsFrPrefClearer {
  1671   public:
  1672     FsFrPrefClearer(nsCOMPtr<nsIPrefBranch> prefs): mPrefs(prefs) {}
  1673     ~FsFrPrefClearer() {
  1674       gMainThread->Dispatch(
  1675         WrapRunnableNM(FsFrPrefClearer::ClearUserPrefOnMainThread,
  1676           mPrefs,
  1677           "media.navigator.video.max_fs"),
  1678         NS_DISPATCH_SYNC);
  1679       gMainThread->Dispatch(
  1680         WrapRunnableNM(FsFrPrefClearer::ClearUserPrefOnMainThread,
  1681           mPrefs,
  1682           "media.navigator.video.max_fr"),
  1683         NS_DISPATCH_SYNC);
  1686     static void ClearUserPrefOnMainThread(nsCOMPtr<nsIPrefBranch> prefs,
  1687       const char *pref_name) {
  1688       MOZ_ASSERT(NS_IsMainThread());
  1689       prefs->ClearUserPref(pref_name);
  1691   private:
  1692     nsCOMPtr<nsIPrefBranch> mPrefs;
  1693 };
  1695 TEST_F(SignalingTest, JustInit)
  1699 TEST_F(SignalingTest, CreateSetOffer)
  1701   sipcc::MediaConstraints constraints;
  1702   CreateSetOffer(constraints, SHOULD_SENDRECV_AV);
  1705 TEST_F(SignalingTest, CreateOfferAudioVideoConstraintUndefined)
  1707   sipcc::MediaConstraints constraints;
  1708   CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
  1711 TEST_F(SignalingTest, CreateOfferNoVideoStreamRecvVideo)
  1713   sipcc::MediaConstraints constraints;
  1714   constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1715   constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1716   CreateOffer(constraints, OFFER_AUDIO,
  1717               SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO);
  1720 TEST_F(SignalingTest, CreateOfferNoAudioStreamRecvAudio)
  1722   sipcc::MediaConstraints constraints;
  1723   constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1724   constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1725   CreateOffer(constraints, OFFER_VIDEO,
  1726               SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
  1729 TEST_F(SignalingTest, CreateOfferNoVideoStream)
  1731   sipcc::MediaConstraints constraints;
  1732   constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1733   constraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
  1734   CreateOffer(constraints, OFFER_AUDIO,
  1735               SHOULD_SENDRECV_AUDIO | SHOULD_OMIT_VIDEO);
  1738 TEST_F(SignalingTest, CreateOfferNoAudioStream)
  1740   sipcc::MediaConstraints constraints;
  1741   constraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
  1742   constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1743   CreateOffer(constraints, OFFER_VIDEO,
  1744               SHOULD_OMIT_AUDIO | SHOULD_SENDRECV_VIDEO);
  1747 TEST_F(SignalingTest, CreateOfferDontReceiveAudio)
  1749   sipcc::MediaConstraints constraints;
  1750   constraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
  1751   constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1752   CreateOffer(constraints, OFFER_AV,
  1753               SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO);
  1756 TEST_F(SignalingTest, CreateOfferDontReceiveVideo)
  1758   sipcc::MediaConstraints constraints;
  1759   constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1760   constraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
  1761   CreateOffer(constraints, OFFER_AV,
  1762               SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO);
  1765 // XXX Disabled pending resolution of Bug 840728
  1766 TEST_F(SignalingTest, DISABLED_CreateOfferRemoveAudioStream)
  1768   sipcc::MediaConstraints constraints;
  1769   constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1770   constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1771   CreateOfferRemoveStream(constraints, DOMMediaStream::HINT_CONTENTS_AUDIO,
  1772               SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
  1775 // XXX Disabled pending resolution of Bug 840728
  1776 TEST_F(SignalingTest, DISABLED_CreateOfferDontReceiveAudioRemoveAudioStream)
  1778   sipcc::MediaConstraints constraints;
  1779   constraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
  1780   constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1781   CreateOfferRemoveStream(constraints, DOMMediaStream::HINT_CONTENTS_AUDIO,
  1782               SHOULD_SENDRECV_VIDEO);
  1785 // XXX Disabled pending resolution of Bug 840728
  1786 TEST_F(SignalingTest, DISABLED_CreateOfferDontReceiveVideoRemoveVideoStream)
  1788   sipcc::MediaConstraints constraints;
  1789   constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1790   constraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
  1791   CreateOfferRemoveStream(constraints, DOMMediaStream::HINT_CONTENTS_VIDEO,
  1792               SHOULD_SENDRECV_AUDIO);
  1795 TEST_F(SignalingTest, OfferAnswerNothingDisabled)
  1797   sipcc::MediaConstraints constraints;
  1798   OfferAnswer(constraints, constraints, OFFER_AV | ANSWER_AV, false,
  1799               SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
  1802 TEST_F(SignalingTest, OfferAnswerDontReceiveAudioOnOffer)
  1804   sipcc::MediaConstraints offerconstraints;
  1805   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
  1806   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1807   sipcc::MediaConstraints answerconstraints;
  1808   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1809   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1810   OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
  1811               false, SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO,
  1812               SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
  1815 TEST_F(SignalingTest, OfferAnswerDontReceiveVideoOnOffer)
  1817   sipcc::MediaConstraints offerconstraints;
  1818   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1819   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
  1820   sipcc::MediaConstraints answerconstraints;
  1821   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1822   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1823   OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
  1824               false, SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO,
  1825               SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO);
  1828 TEST_F(SignalingTest, OfferAnswerDontReceiveAudioOnAnswer)
  1830   sipcc::MediaConstraints offerconstraints;
  1831   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1832   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1833   sipcc::MediaConstraints answerconstraints;
  1834   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
  1835   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1836   OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
  1837               false, SHOULD_SENDRECV_AV,
  1838               SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO);
  1841 TEST_F(SignalingTest, OfferAnswerDontReceiveVideoOnAnswer)
  1843   sipcc::MediaConstraints offerconstraints;
  1844   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1845   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1846   sipcc::MediaConstraints answerconstraints;
  1847   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1848   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
  1849   OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
  1850               false, SHOULD_SENDRECV_AV,
  1851               SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO);
  1854 TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnOfferRecvAudio)
  1856   sipcc::MediaConstraints offerconstraints;
  1857   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1858   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1859   sipcc::MediaConstraints answerconstraints;
  1860   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1861   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1862   OfferAnswer(offerconstraints, answerconstraints, OFFER_VIDEO | ANSWER_AV,
  1863               false, SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO,
  1864               SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO);
  1867 TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnOffer)
  1869   sipcc::MediaConstraints offerconstraints;
  1870   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
  1871   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1872   sipcc::MediaConstraints answerconstraints;
  1873   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1874   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1875   OfferAnswer(offerconstraints, answerconstraints, OFFER_VIDEO | ANSWER_AV,
  1876               false, SHOULD_OMIT_AUDIO | SHOULD_SENDRECV_VIDEO,
  1877               SHOULD_OMIT_AUDIO | SHOULD_SENDRECV_VIDEO);
  1880 TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnOfferRecvVideo)
  1882   sipcc::MediaConstraints offerconstraints;
  1883   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1884   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1885   sipcc::MediaConstraints answerconstraints;
  1886   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1887   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1888   OfferAnswer(offerconstraints, answerconstraints, OFFER_AUDIO | ANSWER_AV,
  1889               false, SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO,
  1890               SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO);
  1893 TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnOffer)
  1895   sipcc::MediaConstraints offerconstraints;
  1896   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1897   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
  1898   sipcc::MediaConstraints answerconstraints;
  1899   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1900   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1901   OfferAnswer(offerconstraints, answerconstraints, OFFER_AUDIO | ANSWER_AV,
  1902               false, SHOULD_SENDRECV_AUDIO | SHOULD_OMIT_VIDEO,
  1903               SHOULD_SENDRECV_AUDIO | SHOULD_OMIT_VIDEO);
  1906 TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnAnswer)
  1908   sipcc::MediaConstraints offerconstraints;
  1909   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1910   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1911   sipcc::MediaConstraints answerconstraints;
  1912   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1913   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1914   OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_VIDEO,
  1915               false, SHOULD_SENDRECV_AV,
  1916               SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
  1919 TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnAnswer)
  1921   sipcc::MediaConstraints offerconstraints;
  1922   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1923   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1924   sipcc::MediaConstraints answerconstraints;
  1925   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1926   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1927   OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AUDIO,
  1928               false, SHOULD_SENDRECV_AV,
  1929               SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO);
  1932 TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnAnswerDontReceiveVideoOnAnswer)
  1934   sipcc::MediaConstraints offerconstraints;
  1935   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1936   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1937   sipcc::MediaConstraints answerconstraints;
  1938   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1939   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
  1940   OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AUDIO,
  1941               false, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AUDIO );
  1944 TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnAnswerDontReceiveAudioOnAnswer)
  1946   sipcc::MediaConstraints offerconstraints;
  1947   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1948   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1949   sipcc::MediaConstraints answerconstraints;
  1950   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
  1951   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1952   OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_VIDEO,
  1953               false, SHOULD_SENDRECV_AV,
  1954               SHOULD_REJECT_AUDIO | SHOULD_SENDRECV_VIDEO);
  1957 TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnOfferDontReceiveAudioOnOffer)
  1959   sipcc::MediaConstraints offerconstraints;
  1960   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
  1961   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1962   sipcc::MediaConstraints answerconstraints;
  1963   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1964   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1965   OfferAnswer(offerconstraints, answerconstraints, OFFER_VIDEO | ANSWER_AV,
  1966               false, SHOULD_SENDRECV_VIDEO, SHOULD_SENDRECV_VIDEO);
  1969 TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnOfferDontReceiveVideoOnOffer)
  1971   sipcc::MediaConstraints offerconstraints;
  1972   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1973   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
  1974   sipcc::MediaConstraints answerconstraints;
  1975   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1976   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1977   OfferAnswer(offerconstraints, answerconstraints, OFFER_AUDIO | ANSWER_AV,
  1978               false, SHOULD_SENDRECV_AUDIO | SHOULD_OMIT_VIDEO,
  1979               SHOULD_SENDRECV_AUDIO | SHOULD_OMIT_VIDEO);
  1982 TEST_F(SignalingTest, OfferAnswerDontReceiveAudioNoAudioStreamOnOfferDontReceiveVideoOnAnswer)
  1984   sipcc::MediaConstraints offerconstraints;
  1985   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
  1986   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  1987   sipcc::MediaConstraints answerconstraints;
  1988   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  1989   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
  1990   OfferAnswer(offerconstraints, answerconstraints, OFFER_VIDEO | ANSWER_AV,
  1991               false, SHOULD_SENDRECV_VIDEO, SHOULD_SEND_VIDEO);
  1994 TEST_F(SignalingTest, CreateOfferAddCandidate)
  1996   sipcc::MediaConstraints constraints;
  1997   CreateOfferAddCandidate(constraints, strSampleCandidate.c_str(),
  1998                           strSampleMid.c_str(), nSamplelevel,
  1999                           SHOULD_SENDRECV_AV);
  2002 TEST_F(SignalingTest, AddIceCandidateEarly)
  2004   sipcc::MediaConstraints constraints;
  2005   AddIceCandidateEarly(strSampleCandidate.c_str(),
  2006                        strSampleMid.c_str(), nSamplelevel);
  2009 // XXX adam@nostrum.com -- This test seems questionable; we need to think
  2010 // through what actually needs to be tested here.
  2011 TEST_F(SignalingTest, DISABLED_OfferAnswerReNegotiateOfferAnswerDontReceiveVideoNoVideoStream)
  2013   sipcc::MediaConstraints aconstraints;
  2014   aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  2015   aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  2017   sipcc::MediaConstraints bconstraints;
  2018   bconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  2019   bconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
  2021   OfferAnswer(aconstraints, aconstraints, OFFER_AV | ANSWER_AV,
  2022               false, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
  2023   OfferAnswer(bconstraints, bconstraints, OFFER_AUDIO | ANSWER_AV,
  2024               false, SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO,
  2025               SHOULD_SENDRECV_AUDIO | SHOULD_INACTIVE_VIDEO);
  2028 TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnAnswerNoConstraints)
  2030   sipcc::MediaConstraints offerconstraints;
  2031   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  2032   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  2033   sipcc::MediaConstraints answerconstraints;
  2034   OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_VIDEO,
  2035               false, SHOULD_SENDRECV_AV,
  2036               SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
  2039 TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnAnswerNoConstraints)
  2041   sipcc::MediaConstraints offerconstraints;
  2042   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  2043   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  2044   sipcc::MediaConstraints answerconstraints;
  2045   OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AUDIO,
  2046               false, SHOULD_SENDRECV_AV,
  2047               SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO);
  2050 TEST_F(SignalingTest, OfferAnswerDontAddAudioVideoStreamsOnAnswerNoConstraints)
  2052   sipcc::MediaConstraints offerconstraints;
  2053   offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  2054   offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  2055   sipcc::MediaConstraints answerconstraints;
  2056   OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_NONE,
  2057               false, SHOULD_SENDRECV_AV,
  2058               SHOULD_RECV_AUDIO | SHOULD_RECV_VIDEO);
  2061 TEST_F(SignalingTest, FullCall)
  2063   sipcc::MediaConstraints constraints;
  2064   OfferAnswer(constraints, constraints, OFFER_AV | ANSWER_AV,
  2065               true, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
  2067   // Wait for some data to get written
  2068   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
  2069                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
  2071   a1_->CloseSendStreams();
  2072   a2_->CloseReceiveStreams();
  2073   // Check that we wrote a bunch of data
  2074   ASSERT_GE(a1_->GetPacketsSent(0), 40);
  2075   //ASSERT_GE(a2_->GetPacketsSent(0), 40);
  2076   //ASSERT_GE(a1_->GetPacketsReceived(0), 40);
  2077   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
  2079   // Check the low-level media pipeline
  2080   // for RTP and RTCP flows
  2081   // The first Local pipeline gets stored at 0
  2082   a1_->CheckMediaPipeline(0, 0, fRtcpMux ?
  2083     PIPELINE_LOCAL | PIPELINE_RTCP_MUX | PIPELINE_SEND :
  2084     PIPELINE_LOCAL | PIPELINE_SEND);
  2086   // The first Remote pipeline gets stored at 1
  2087   a2_->CheckMediaPipeline(0, 1, (fRtcpMux ?  PIPELINE_RTCP_MUX : 0));
  2090 TEST_F(SignalingTest, FullCallAudioOnly)
  2092   sipcc::MediaConstraints constraints;
  2093   OfferAnswer(constraints, constraints, OFFER_AUDIO | ANSWER_AUDIO,
  2094               true, SHOULD_SENDRECV_AUDIO, SHOULD_SENDRECV_AUDIO);
  2096   // Wait for some data to get written
  2097   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
  2098                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
  2100   a1_->CloseSendStreams();
  2101   a2_->CloseReceiveStreams();
  2102   // Check that we wrote a bunch of data
  2103   ASSERT_GE(a1_->GetPacketsSent(0), 40);
  2104   //ASSERT_GE(a2_->GetPacketsSent(0), 40);
  2105   //ASSERT_GE(a1_->GetPacketsReceived(0), 40);
  2106   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
  2109 TEST_F(SignalingTest, FullCallAnswererRejectsVideo)
  2111   sipcc::MediaConstraints offerconstraints;
  2112   sipcc::MediaConstraints answerconstraints;
  2113   answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  2114   answerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
  2115   OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AUDIO,
  2116               true, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AUDIO);
  2118   // Wait for some data to get written
  2119   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
  2120                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
  2122   a1_->CloseSendStreams();
  2123   a2_->CloseReceiveStreams();
  2124   // Check that we wrote a bunch of data
  2125   ASSERT_GE(a1_->GetPacketsSent(0), 40);
  2126   //ASSERT_GE(a2_->GetPacketsSent(0), 40);
  2127   //ASSERT_GE(a1_->GetPacketsReceived(0), 40);
  2128   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
  2131 TEST_F(SignalingTest, FullCallVideoOnly)
  2133   sipcc::MediaConstraints constraints;
  2134   OfferAnswer(constraints, constraints, OFFER_VIDEO | ANSWER_VIDEO,
  2135               true, SHOULD_SENDRECV_VIDEO, SHOULD_SENDRECV_VIDEO);
  2137   // If we could check for video packets, we would wait for some to be written
  2138   // here. Since we can't, we don't.
  2139   // ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
  2140   //                 a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
  2142   a1_->CloseSendStreams();
  2143   a2_->CloseReceiveStreams();
  2145   // FIXME -- Ideally we would check that packets were sent
  2146   // and received; however, the test driver setup does not
  2147   // currently support sending/receiving with Fake_VideoStreamSource.
  2148   //
  2149   // Check that we wrote a bunch of data
  2150   // ASSERT_GE(a1_->GetPacketsSent(0), 40);
  2151   //ASSERT_GE(a2_->GetPacketsSent(0), 40);
  2152   //ASSERT_GE(a1_->GetPacketsReceived(0), 40);
  2153   // ASSERT_GE(a2_->GetPacketsReceived(0), 40);
  2156 TEST_F(SignalingTest, OfferModifiedAnswer)
  2158   sipcc::MediaConstraints constraints;
  2159   OfferModifiedAnswer(constraints, constraints, SHOULD_SENDRECV_AUDIO,
  2160                       SHOULD_SENDRECV_AUDIO);
  2161   a1_->CloseSendStreams();
  2162   a2_->CloseReceiveStreams();
  2165 TEST_F(SignalingTest, FullCallTrickle)
  2167   sipcc::MediaConstraints constraints;
  2168   OfferAnswerTrickle(constraints, constraints,
  2169                      SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
  2171   std::cerr << "ICE handshake completed" << std::endl;
  2173   // Wait for some data to get written
  2174   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
  2175                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
  2177   a1_->CloseSendStreams();
  2178   a2_->CloseReceiveStreams();
  2179   ASSERT_GE(a1_->GetPacketsSent(0), 40);
  2180   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
  2183 // Offer answer with trickle but with chrome-style candidates
  2184 TEST_F(SignalingTest, FullCallTrickleChrome)
  2186   sipcc::MediaConstraints constraints;
  2187   OfferAnswerTrickleChrome(constraints, constraints,
  2188                            SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
  2190   std::cerr << "ICE handshake completed" << std::endl;
  2192   // Wait for some data to get written
  2193   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
  2194                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
  2196   a1_->CloseSendStreams();
  2197   a2_->CloseReceiveStreams();
  2198   ASSERT_GE(a1_->GetPacketsSent(0), 40);
  2199   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
  2202 // This test comes from Bug 810220
  2203 TEST_F(SignalingTest, AudioOnlyG711Call)
  2205   EnsureInit();
  2207   sipcc::MediaConstraints constraints;
  2208   const std::string& offer(strG711SdpOffer);
  2210   std::cout << "Setting offer to:" << std::endl << indent(offer) << std::endl;
  2211   a2_->SetRemote(TestObserver::OFFER, offer);
  2213   std::cout << "Creating answer:" << std::endl;
  2214   a2_->CreateAnswer(constraints, offer, OFFER_AUDIO | ANSWER_AUDIO,
  2215                    DONT_CHECK_AUDIO | DONT_CHECK_VIDEO | DONT_CHECK_DATA);
  2217   std::string answer = a2_->answer();
  2219   // They didn't offer opus, so our answer shouldn't include it.
  2220   ASSERT_EQ(answer.find(" opus/"), std::string::npos);
  2222   // They also didn't offer video or application
  2223   ASSERT_EQ(answer.find("video"), std::string::npos);
  2224   ASSERT_EQ(answer.find("application"), std::string::npos);
  2226   // We should answer with PCMU and telephone-event
  2227   ASSERT_NE(answer.find(" PCMU/8000"), std::string::npos);
  2228   ASSERT_NE(answer.find(" telephone-event/8000"), std::string::npos);
  2230   // Double-check the directionality
  2231   ASSERT_NE(answer.find("\r\na=sendrecv"), std::string::npos);
  2235 // This test comes from Bug814038
  2236 TEST_F(SignalingTest, ChromeOfferAnswer)
  2238   EnsureInit();
  2240   sipcc::MediaConstraints constraints;
  2242   // This is captured SDP from an early interop attempt with Chrome.
  2243   std::string offer =
  2244     "v=0\r\n"
  2245     "o=- 1713781661 2 IN IP4 127.0.0.1\r\n"
  2246     "s=-\r\n"
  2247     "t=0 0\r\n"
  2248     "a=group:BUNDLE audio video\r\n"
  2250     "m=audio 1 RTP/SAVPF 103 104 111 0 8 107 106 105 13 126\r\n"
  2251     "a=fingerprint:sha-1 4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:"
  2252       "5D:49:6B:19:E5:7C:AB\r\n"
  2253     "c=IN IP4 0.0.0.0\r\n"
  2254     "a=rtcp:1 IN IP4 0.0.0.0\r\n"
  2255     "a=ice-ufrag:lBrbdDfrVBH1cldN\r\n"
  2256     "a=ice-pwd:rzh23jet4QpCaEoj9Sl75pL3\r\n"
  2257     "a=ice-options:google-ice\r\n"
  2258     "a=sendrecv\r\n"
  2259     "a=mid:audio\r\n"
  2260     "a=rtcp-mux\r\n"
  2261     "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:"
  2262       "RzrYlzpkTsvgYFD1hQqNCzQ7y4emNLKI1tODsjim\r\n"
  2263     "a=rtpmap:103 ISAC/16000\r\n"
  2264     "a=rtpmap:104 ISAC/32000\r\n"
  2265     // NOTE: the actual SDP that Chrome sends at the moment
  2266     // doesn't indicate two channels. I've amended their SDP
  2267     // here, under the assumption that the constraints
  2268     // described in draft-spittka-payload-rtp-opus will
  2269     // eventually be implemented by Google.
  2270     "a=rtpmap:111 opus/48000/2\r\n"
  2271     "a=rtpmap:0 PCMU/8000\r\n"
  2272     "a=rtpmap:8 PCMA/8000\r\n"
  2273     "a=rtpmap:107 CN/48000\r\n"
  2274     "a=rtpmap:106 CN/32000\r\n"
  2275     "a=rtpmap:105 CN/16000\r\n"
  2276     "a=rtpmap:13 CN/8000\r\n"
  2277     "a=rtpmap:126 telephone-event/8000\r\n"
  2278     "a=ssrc:661333377 cname:KIXaNxUlU5DP3fVS\r\n"
  2279     "a=ssrc:661333377 msid:A5UL339RyGxT7zwgyF12BFqesxkmbUsaycp5 a0\r\n"
  2280     "a=ssrc:661333377 mslabel:A5UL339RyGxT7zwgyF12BFqesxkmbUsaycp5\r\n"
  2281     "a=ssrc:661333377 label:A5UL339RyGxT7zwgyF12BFqesxkmbUsaycp5a0\r\n"
  2283     "m=video 1 RTP/SAVPF 100 101 102\r\n"
  2284     "a=fingerprint:sha-1 4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:"
  2285       "6B:19:E5:7C:AB\r\n"
  2286     "c=IN IP4 0.0.0.0\r\n"
  2287     "a=rtcp:1 IN IP4 0.0.0.0\r\n"
  2288     "a=ice-ufrag:lBrbdDfrVBH1cldN\r\n"
  2289     "a=ice-pwd:rzh23jet4QpCaEoj9Sl75pL3\r\n"
  2290     "a=ice-options:google-ice\r\n"
  2291     "a=sendrecv\r\n"
  2292     "a=mid:video\r\n"
  2293     "a=rtcp-mux\r\n"
  2294     "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:"
  2295       "RzrYlzpkTsvgYFD1hQqNCzQ7y4emNLKI1tODsjim\r\n"
  2296     "a=rtpmap:100 VP8/90000\r\n"
  2297     "a=rtpmap:101 red/90000\r\n"
  2298     "a=rtpmap:102 ulpfec/90000\r\n"
  2299     "a=rtcp-fb:100 nack\r\n"
  2300     "a=rtcp-fb:100 ccm fir\r\n"
  2301     "a=ssrc:3012607008 cname:KIXaNxUlU5DP3fVS\r\n"
  2302     "a=ssrc:3012607008 msid:A5UL339RyGxT7zwgyF12BFqesxkmbUsaycp5 v0\r\n"
  2303     "a=ssrc:3012607008 mslabel:A5UL339RyGxT7zwgyF12BFqesxkmbUsaycp5\r\n"
  2304     "a=ssrc:3012607008 label:A5UL339RyGxT7zwgyF12BFqesxkmbUsaycp5v0\r\n";
  2307   std::cout << "Setting offer to:" << std::endl << indent(offer) << std::endl;
  2308   a2_->SetRemote(TestObserver::OFFER, offer);
  2310   std::cout << "Creating answer:" << std::endl;
  2311   a2_->CreateAnswer(constraints, offer, OFFER_AUDIO | ANSWER_AUDIO);
  2313   std::string answer = a2_->answer();
  2317 TEST_F(SignalingTest, FullChromeHandshake)
  2319   EnsureInit();
  2321   sipcc::MediaConstraints constraints;
  2322   constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
  2323   constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
  2325   std::string offer = "v=0\r\n"
  2326       "o=- 3835809413 2 IN IP4 127.0.0.1\r\n"
  2327       "s=-\r\n"
  2328       "t=0 0\r\n"
  2329       "a=group:BUNDLE audio video\r\n"
  2330       "a=msid-semantic: WMS ahheYQXHFU52slYMrWNtKUyHCtWZsOJgjlOH\r\n"
  2331       "m=audio 1 RTP/SAVPF 103 104 111 0 8 107 106 105 13 126\r\n"
  2332       "c=IN IP4 1.1.1.1\r\n"
  2333       "a=rtcp:1 IN IP4 1.1.1.1\r\n"
  2334       "a=ice-ufrag:jz9UBk9RT8eCQXiL\r\n"
  2335       "a=ice-pwd:iscXxsdU+0gracg0g5D45orx\r\n"
  2336       "a=ice-options:google-ice\r\n"
  2337       "a=fingerprint:sha-256 A8:76:8C:4C:FA:2E:67:D7:F8:1D:28:4E:90:24:04:"
  2338         "12:EB:B4:A6:69:3D:05:92:E4:91:C3:EA:F9:B7:54:D3:09\r\n"
  2339       "a=sendrecv\r\n"
  2340       "a=mid:audio\r\n"
  2341       "a=rtcp-mux\r\n"
  2342       "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:/he/v44FKu/QvEhex86zV0pdn2V"
  2343         "4Y7wB2xaZ8eUy\r\n"
  2344       "a=rtpmap:103 ISAC/16000\r\n"
  2345       "a=rtpmap:104 ISAC/32000\r\n"
  2346       "a=rtpmap:111 opus/48000/2\r\n"
  2347       "a=rtpmap:0 PCMU/8000\r\n"
  2348       "a=rtpmap:8 PCMA/8000\r\n"
  2349       "a=rtpmap:107 CN/48000\r\n"
  2350       "a=rtpmap:106 CN/32000\r\n"
  2351       "a=rtpmap:105 CN/16000\r\n"
  2352       "a=rtpmap:13 CN/8000\r\n"
  2353       "a=rtpmap:126 telephone-event/8000\r\n"
  2354       "a=ssrc:3389377748 cname:G5I+Jxz4rcaq8IIK\r\n"
  2355       "a=ssrc:3389377748 msid:ahheYQXHFU52slYMrWNtKUyHCtWZsOJgjlOH a0\r\n"
  2356       "a=ssrc:3389377748 mslabel:ahheYQXHFU52slYMrWNtKUyHCtWZsOJgjlOH\r\n"
  2357       "a=ssrc:3389377748 label:ahheYQXHFU52slYMrWNtKUyHCtWZsOJgjlOHa0\r\n"
  2358       "m=video 1 RTP/SAVPF 100 116 117\r\n"
  2359       "c=IN IP4 1.1.1.1\r\n"
  2360       "a=rtcp:1 IN IP4 1.1.1.1\r\n"
  2361       "a=ice-ufrag:jz9UBk9RT8eCQXiL\r\n"
  2362       "a=ice-pwd:iscXxsdU+0gracg0g5D45orx\r\n"
  2363       "a=ice-options:google-ice\r\n"
  2364       "a=fingerprint:sha-256 A8:76:8C:4C:FA:2E:67:D7:F8:1D:28:4E:90:24:04:"
  2365         "12:EB:B4:A6:69:3D:05:92:E4:91:C3:EA:F9:B7:54:D3:09\r\n"
  2366       "a=sendrecv\r\n"
  2367       "a=mid:video\r\n"
  2368       "a=rtcp-mux\r\n"
  2369       "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:/he/v44FKu/QvEhex86zV0pdn2V"
  2370         "4Y7wB2xaZ8eUy\r\n"
  2371       "a=rtpmap:100 VP8/90000\r\n"
  2372       "a=rtpmap:116 red/90000\r\n"
  2373       "a=rtpmap:117 ulpfec/90000\r\n"
  2374       "a=ssrc:3613537198 cname:G5I+Jxz4rcaq8IIK\r\n"
  2375       "a=ssrc:3613537198 msid:ahheYQXHFU52slYMrWNtKUyHCtWZsOJgjlOH v0\r\n"
  2376       "a=ssrc:3613537198 mslabel:ahheYQXHFU52slYMrWNtKUyHCtWZsOJgjlOH\r\n"
  2377       "a=ssrc:3613537198 label:ahheYQXHFU52slYMrWNtKUyHCtWZsOJgjlOHv0\r\n";
  2379   std::cout << "Setting offer to:" << std::endl << indent(offer) << std::endl;
  2380   a2_->SetRemote(TestObserver::OFFER, offer);
  2382   std::cout << "Creating answer:" << std::endl;
  2383   a2_->CreateAnswer(constraints, offer, OFFER_AUDIO | ANSWER_AUDIO);
  2385   std::cout << "Setting answer" << std::endl;
  2386   a2_->SetLocal(TestObserver::ANSWER, a2_->answer());
  2388   std::string answer = a2_->answer();
  2389   ASSERT_NE(answer.find("111 opus/"), std::string::npos);
  2392 // Disabled pending resolution of bug 818640.
  2393 TEST_F(SignalingTest, DISABLED_OfferAllDynamicTypes)
  2395   EnsureInit();
  2397   sipcc::MediaConstraints constraints;
  2398   std::string offer;
  2399   for (int i = 96; i < 128; i++)
  2401     std::stringstream ss;
  2402     ss << i;
  2403     std::cout << "Trying dynamic pt = " << i << std::endl;
  2404     offer =
  2405       "v=0\r\n"
  2406       "o=- 1 1 IN IP4 148.147.200.251\r\n"
  2407       "s=-\r\n"
  2408       "b=AS:64\r\n"
  2409       "t=0 0\r\n"
  2410       "a=fingerprint:sha-256 F3:FA:20:C0:CD:48:C4:5F:02:5F:A5:D3:21:D0:2D:48:"
  2411         "7B:31:60:5C:5A:D8:0D:CD:78:78:6C:6D:CE:CC:0C:67\r\n"
  2412       "m=audio 9000 RTP/AVP " + ss.str() + "\r\n"
  2413       "c=IN IP4 148.147.200.251\r\n"
  2414       "b=TIAS:64000\r\n"
  2415       "a=rtpmap:" + ss.str() +" opus/48000/2\r\n"
  2416       "a=candidate:0 1 udp 2130706432 148.147.200.251 9000 typ host\r\n"
  2417       "a=candidate:0 2 udp 2130706432 148.147.200.251 9005 typ host\r\n"
  2418       "a=ice-ufrag:cYuakxkEKH+RApYE\r\n"
  2419       "a=ice-pwd:bwtpzLZD+3jbu8vQHvEa6Xuq\r\n"
  2420       "a=sendrecv\r\n";
  2422       /*
  2423       std::cout << "Setting offer to:" << std::endl
  2424                 << indent(offer) << std::endl;
  2425       */
  2426       a2_->SetRemote(TestObserver::OFFER, offer);
  2428       //std::cout << "Creating answer:" << std::endl;
  2429       a2_->CreateAnswer(constraints, offer, OFFER_AUDIO | ANSWER_AUDIO);
  2431       std::string answer = a2_->answer();
  2433       ASSERT_NE(answer.find(ss.str() + " opus/"), std::string::npos);
  2438 TEST_F(SignalingTest, OfferAnswerCheckDescriptions)
  2440   sipcc::MediaConstraints constraints;
  2441   OfferAnswer(constraints, constraints, OFFER_AV | ANSWER_AV, true,
  2442               SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
  2444   std::cout << "Caller's Local Description: " << std::endl
  2445             << indent(a1_->getLocalDescription()) << std::endl << std::endl;
  2447   std::cout << "Caller's Remote Description: " << std::endl
  2448             << indent(a1_->getRemoteDescription()) << std::endl << std::endl;
  2450   std::cout << "Callee's Local Description: " << std::endl
  2451             << indent(a2_->getLocalDescription()) << std::endl << std::endl;
  2453   std::cout << "Callee's Remote Description: " << std::endl
  2454             << indent(a2_->getRemoteDescription()) << std::endl << std::endl;
  2456   ASSERT_EQ(a1_->getLocalDescription(),a2_->getRemoteDescription());
  2457   ASSERT_EQ(a2_->getLocalDescription(),a1_->getRemoteDescription());
  2460 TEST_F(SignalingTest, CheckTrickleSdpChange)
  2462   sipcc::MediaConstraints constraints;
  2463   OfferAnswerTrickle(constraints, constraints,
  2464                      SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
  2465   std::cerr << "ICE handshake completed" << std::endl;
  2467   a1_->CloseSendStreams();
  2468   a2_->CloseReceiveStreams();
  2470   std::cout << "Caller's Local Description: " << std::endl
  2471             << indent(a1_->getLocalDescription()) << std::endl << std::endl;
  2473   std::cout << "Caller's Remote Description: " << std::endl
  2474             << indent(a1_->getRemoteDescription()) << std::endl << std::endl;
  2476   std::cout << "Callee's Local Description: " << std::endl
  2477             << indent(a2_->getLocalDescription()) << std::endl << std::endl;
  2479   std::cout << "Callee's Remote Description: " << std::endl
  2480             << indent(a2_->getRemoteDescription()) << std::endl << std::endl;
  2482   ASSERT_NE(a1_->getLocalDescription().find("\r\na=candidate"),
  2483             std::string::npos);
  2484   ASSERT_NE(a1_->getRemoteDescription().find("\r\na=candidate"),
  2485             std::string::npos);
  2486   ASSERT_NE(a2_->getLocalDescription().find("\r\na=candidate"),
  2487             std::string::npos);
  2488   ASSERT_NE(a2_->getRemoteDescription().find("\r\na=candidate"),
  2489             std::string::npos);
  2490   /* TODO (abr): These checks aren't quite right, since trickle ICE
  2491    * can easily result in SDP that is semantically identical but
  2492    * varies syntactically (in particularly, the ordering of attributes
  2493    * withing an m-line section can be different). This needs to be updated
  2494    * to be a semantic comparision between the SDP. Currently, these checks
  2495    * will fail whenever we add any other attributes to the SDP, such as
  2496    * RTCP MUX or RTCP feedback.
  2497   ASSERT_EQ(a1_->getLocalDescription(),a2_->getRemoteDescription());
  2498   ASSERT_EQ(a2_->getLocalDescription(),a1_->getRemoteDescription());
  2499   */
  2502 TEST_F(SignalingTest, ipAddrAnyOffer)
  2504   EnsureInit();
  2506   sipcc::MediaConstraints constraints;
  2507   std::string offer =
  2508     "v=0\r\n"
  2509     "o=- 1 1 IN IP4 127.0.0.1\r\n"
  2510     "s=-\r\n"
  2511     "b=AS:64\r\n"
  2512     "t=0 0\r\n"
  2513     "a=fingerprint:sha-256 F3:FA:20:C0:CD:48:C4:5F:02:5F:A5:D3:21:D0:2D:48:"
  2514       "7B:31:60:5C:5A:D8:0D:CD:78:78:6C:6D:CE:CC:0C:67\r\n"
  2515     "m=audio 9000 RTP/AVP 99\r\n"
  2516     "c=IN IP4 0.0.0.0\r\n"
  2517     "a=rtpmap:99 opus/48000/2\r\n"
  2518     "a=ice-ufrag:cYuakxkEKH+RApYE\r\n"
  2519     "a=ice-pwd:bwtpzLZD+3jbu8vQHvEa6Xuq\r\n"
  2520     "a=sendrecv\r\n";
  2522     a2_->SetRemote(TestObserver::OFFER, offer);
  2523     ASSERT_TRUE(a2_->pObserver->state == TestObserver::stateSuccess);
  2524     a2_->CreateAnswer(constraints, offer, OFFER_AUDIO | ANSWER_AUDIO);
  2525     ASSERT_TRUE(a2_->pObserver->state == TestObserver::stateSuccess);
  2526     std::string answer = a2_->answer();
  2527     ASSERT_NE(answer.find("a=sendrecv"), std::string::npos);
  2530 static void CreateSDPForBigOTests(std::string& offer, const char *number) {
  2531   offer =
  2532     "v=0\r\n"
  2533     "o=- ";
  2534   offer += number;
  2535   offer += " ";
  2536   offer += number;
  2537   offer += " IN IP4 127.0.0.1\r\n"
  2538     "s=-\r\n"
  2539     "b=AS:64\r\n"
  2540     "t=0 0\r\n"
  2541     "a=fingerprint:sha-256 F3:FA:20:C0:CD:48:C4:5F:02:5F:A5:D3:21:D0:2D:48:"
  2542       "7B:31:60:5C:5A:D8:0D:CD:78:78:6C:6D:CE:CC:0C:67\r\n"
  2543     "m=audio 9000 RTP/AVP 99\r\n"
  2544     "c=IN IP4 0.0.0.0\r\n"
  2545     "a=rtpmap:99 opus/48000/2\r\n"
  2546     "a=ice-ufrag:cYuakxkEKH+RApYE\r\n"
  2547     "a=ice-pwd:bwtpzLZD+3jbu8vQHvEa6Xuq\r\n"
  2548     "a=sendrecv\r\n";
  2551 TEST_F(SignalingTest, BigOValues)
  2553   EnsureInit();
  2555   std::string offer;
  2557   CreateSDPForBigOTests(offer, "12345678901234567");
  2559   a2_->SetRemote(TestObserver::OFFER, offer);
  2560   ASSERT_EQ(a2_->pObserver->state, TestObserver::stateSuccess);
  2563 TEST_F(SignalingTest, BigOValuesExtraChars)
  2565   EnsureInit();
  2567   std::string offer;
  2569   CreateSDPForBigOTests(offer, "12345678901234567FOOBAR");
  2571   // The signaling state will remain "stable" because the unparsable
  2572   // SDP leads to a failure in SetRemoteDescription.
  2573   a2_->SetRemote(TestObserver::OFFER, offer, true,
  2574                  PCImplSignalingState::SignalingStable);
  2575   ASSERT_TRUE(a2_->pObserver->state == TestObserver::stateError);
  2578 TEST_F(SignalingTest, BigOValuesTooBig)
  2580   EnsureInit();
  2582   std::string offer;
  2584   CreateSDPForBigOTests(offer, "18446744073709551615");
  2586   // The signaling state will remain "stable" because the unparsable
  2587   // SDP leads to a failure in SetRemoteDescription.
  2588   a2_->SetRemote(TestObserver::OFFER, offer, true,
  2589                  PCImplSignalingState::SignalingStable);
  2590   ASSERT_TRUE(a2_->pObserver->state == TestObserver::stateError);
  2593 TEST_F(SignalingTest, SetLocalAnswerInStable)
  2595   EnsureInit();
  2597   sipcc::MediaConstraints constraints;
  2598   CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  2600   // The signaling state will remain "stable" because the
  2601   // SetLocalDescription call fails.
  2602   a1_->SetLocal(TestObserver::ANSWER, a1_->offer(), true,
  2603                 PCImplSignalingState::SignalingStable);
  2604   ASSERT_EQ(a1_->pObserver->lastStatusCode,
  2605             sipcc::PeerConnectionImpl::kInvalidState);
  2608 TEST_F(SignalingTest, SetRemoteAnswerInStable) {
  2609   EnsureInit();
  2611   // The signaling state will remain "stable" because the
  2612   // SetRemoteDescription call fails.
  2613   a1_->SetRemote(TestObserver::ANSWER, strSampleSdpAudioVideoNoIce, true,
  2614                 PCImplSignalingState::SignalingStable);
  2615   ASSERT_EQ(a1_->pObserver->lastStatusCode,
  2616             sipcc::PeerConnectionImpl::kInvalidState);
  2619 TEST_F(SignalingTest, SetLocalAnswerInHaveLocalOffer) {
  2620   sipcc::MediaConstraints constraints;
  2621   CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  2622   a1_->SetLocal(TestObserver::OFFER, a1_->offer());
  2623   ASSERT_EQ(a1_->pObserver->lastStatusCode,
  2624             sipcc::PeerConnectionImpl::kNoError);
  2626   // The signaling state will remain "have-local-offer" because the
  2627   // SetLocalDescription call fails.
  2628   a1_->SetLocal(TestObserver::ANSWER, a1_->offer(), true,
  2629                 PCImplSignalingState::SignalingHaveLocalOffer);
  2630   ASSERT_EQ(a1_->pObserver->lastStatusCode,
  2631             sipcc::PeerConnectionImpl::kInvalidState);
  2634 TEST_F(SignalingTest, SetRemoteOfferInHaveLocalOffer) {
  2635   sipcc::MediaConstraints constraints;
  2636   CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  2637   a1_->SetLocal(TestObserver::OFFER, a1_->offer());
  2638   ASSERT_EQ(a1_->pObserver->lastStatusCode,
  2639             sipcc::PeerConnectionImpl::kNoError);
  2641   // The signaling state will remain "have-local-offer" because the
  2642   // SetRemoteDescription call fails.
  2643   a1_->SetRemote(TestObserver::OFFER, a1_->offer(), true,
  2644                  PCImplSignalingState::SignalingHaveLocalOffer);
  2645   ASSERT_EQ(a1_->pObserver->lastStatusCode,
  2646             sipcc::PeerConnectionImpl::kInvalidState);
  2649 TEST_F(SignalingTest, SetLocalOfferInHaveRemoteOffer) {
  2650   sipcc::MediaConstraints constraints;
  2651   CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  2652   a2_->SetRemote(TestObserver::OFFER, a1_->offer());
  2653   ASSERT_EQ(a2_->pObserver->lastStatusCode,
  2654             sipcc::PeerConnectionImpl::kNoError);
  2656   // The signaling state will remain "have-remote-offer" because the
  2657   // SetLocalDescription call fails.
  2658   a2_->SetLocal(TestObserver::OFFER, a1_->offer(), true,
  2659                 PCImplSignalingState::SignalingHaveRemoteOffer);
  2660   ASSERT_EQ(a2_->pObserver->lastStatusCode,
  2661             sipcc::PeerConnectionImpl::kInvalidState);
  2664 TEST_F(SignalingTest, SetRemoteAnswerInHaveRemoteOffer) {
  2665   sipcc::MediaConstraints constraints;
  2666   CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  2667   a2_->SetRemote(TestObserver::OFFER, a1_->offer());
  2668   ASSERT_EQ(a2_->pObserver->lastStatusCode,
  2669             sipcc::PeerConnectionImpl::kNoError);
  2671   // The signaling state will remain "have-remote-offer" because the
  2672   // SetRemoteDescription call fails.
  2673   a2_->SetRemote(TestObserver::ANSWER, a1_->offer(), true,
  2674                PCImplSignalingState::SignalingHaveRemoteOffer);
  2675   ASSERT_EQ(a2_->pObserver->lastStatusCode,
  2676             sipcc::PeerConnectionImpl::kInvalidState);
  2679 // Disabled until the spec adds a failure callback to addStream
  2680 TEST_F(SignalingTest, DISABLED_AddStreamInHaveLocalOffer) {
  2681   sipcc::MediaConstraints constraints;
  2682   CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  2683   a1_->SetLocal(TestObserver::OFFER, a1_->offer());
  2684   ASSERT_EQ(a1_->pObserver->lastStatusCode,
  2685             sipcc::PeerConnectionImpl::kNoError);
  2686   a1_->AddStream();
  2687   ASSERT_EQ(a1_->pObserver->lastStatusCode,
  2688             sipcc::PeerConnectionImpl::kInvalidState);
  2691 // Disabled until the spec adds a failure callback to removeStream
  2692 TEST_F(SignalingTest, DISABLED_RemoveStreamInHaveLocalOffer) {
  2693   sipcc::MediaConstraints constraints;
  2694   CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  2695   a1_->SetLocal(TestObserver::OFFER, a1_->offer());
  2696   ASSERT_EQ(a1_->pObserver->lastStatusCode,
  2697             sipcc::PeerConnectionImpl::kNoError);
  2698   a1_->RemoveLastStreamAdded();
  2699   ASSERT_EQ(a1_->pObserver->lastStatusCode,
  2700             sipcc::PeerConnectionImpl::kInvalidState);
  2703 TEST_F(SignalingTest, AddCandidateInHaveLocalOffer) {
  2704   sipcc::MediaConstraints constraints;
  2705   CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  2706   a1_->SetLocal(TestObserver::OFFER, a1_->offer());
  2707   ASSERT_EQ(a1_->pObserver->lastStatusCode,
  2708             sipcc::PeerConnectionImpl::kNoError);
  2709   a1_->AddIceCandidate(strSampleCandidate.c_str(),
  2710                       strSampleMid.c_str(), nSamplelevel, false);
  2711   ASSERT_EQ(a1_->pObserver->lastStatusCode,
  2712             sipcc::PeerConnectionImpl::kInvalidState);
  2715 TEST_F(SignalingAgentTest, CreateOffer) {
  2716   CreateAgent();
  2717   sipcc::MediaConstraints constraints;
  2718   agent(0)->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  2719   PR_Sleep(20000);
  2722 TEST_F(SignalingAgentTest, CreateOfferTrickleTestServer) {
  2723   TestStunServer::GetInstance()->SetActive(false);
  2724   TestStunServer::GetInstance()->SetResponseAddr(
  2725       kBogusSrflxAddress, kBogusSrflxPort);
  2727   CreateAgent(
  2728       TestStunServer::GetInstance()->addr(),
  2729       TestStunServer::GetInstance()->port(),
  2730       false);
  2732   sipcc::MediaConstraints constraints;
  2733   agent(0)->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  2735   // Verify that the bogus addr is not there.
  2736   ASSERT_FALSE(agent(0)->OfferContains(kBogusSrflxAddress));
  2738   // Now enable the STUN server.
  2739   TestStunServer::GetInstance()->SetActive(true);
  2740   agent(0)->WaitForGather();
  2742   // There shouldn't be any candidates until SetLocal.
  2743   ASSERT_EQ(0U, agent(0)->MatchingCandidates(kBogusSrflxAddress));
  2745   // Verify that the candidates appear in the offer.
  2746   size_t match;
  2747   match = agent(0)->getLocalDescription().find(kBogusSrflxAddress);
  2748   ASSERT_LT(0U, match);
  2751 TEST_F(SignalingAgentTest, CreateOfferSetLocalTrickleTestServer) {
  2752   TestStunServer::GetInstance()->SetActive(false);
  2753   TestStunServer::GetInstance()->SetResponseAddr(
  2754       kBogusSrflxAddress, kBogusSrflxPort);
  2756   CreateAgent(
  2757       TestStunServer::GetInstance()->addr(),
  2758       TestStunServer::GetInstance()->port(),
  2759       false);
  2761   sipcc::MediaConstraints constraints;
  2762   agent(0)->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  2764   // Verify that the bogus addr is not there.
  2765   ASSERT_FALSE(agent(0)->OfferContains(kBogusSrflxAddress));
  2767   // Now enable the STUN server.
  2768   TestStunServer::GetInstance()->SetActive(true);
  2769   agent(0)->WaitForGather();
  2771   // There shouldn't be any candidates until SetLocal.
  2772   ASSERT_EQ(0U, agent(0)->MatchingCandidates(kBogusSrflxAddress));
  2774   agent(0)->SetLocal(TestObserver::OFFER, agent(0)->offer());
  2775   PR_Sleep(1000); // Give time for the message queues.
  2777   // Verify that we got our candidates.
  2778   ASSERT_LE(2U, agent(0)->MatchingCandidates(kBogusSrflxAddress));
  2780   // Verify that the candidates appear in the offer.
  2781   size_t match;
  2782   match = agent(0)->getLocalDescription().find(kBogusSrflxAddress);
  2783   ASSERT_LT(0U, match);
  2787 TEST_F(SignalingAgentTest, CreateAnswerSetLocalTrickleTestServer) {
  2788   TestStunServer::GetInstance()->SetActive(false);
  2789   TestStunServer::GetInstance()->SetResponseAddr(
  2790       kBogusSrflxAddress, kBogusSrflxPort);
  2792   CreateAgent(
  2793       TestStunServer::GetInstance()->addr(),
  2794       TestStunServer::GetInstance()->port(),
  2795       false);
  2797   std::string offer(strG711SdpOffer);
  2798   agent(0)->SetRemote(TestObserver::OFFER, offer, true,
  2799                  PCImplSignalingState::SignalingHaveRemoteOffer);
  2800   ASSERT_EQ(agent(0)->pObserver->lastStatusCode,
  2801             sipcc::PeerConnectionImpl::kNoError);
  2803   sipcc::MediaConstraints constraints;
  2804   agent(0)->CreateAnswer(constraints, offer, ANSWER_AUDIO, DONT_CHECK_AUDIO);
  2806   // Verify that the bogus addr is not there.
  2807   ASSERT_FALSE(agent(0)->AnswerContains(kBogusSrflxAddress));
  2809   // Now enable the STUN server.
  2810   TestStunServer::GetInstance()->SetActive(true);
  2811   agent(0)->WaitForGather();
  2813   // There shouldn't be any candidates until SetLocal.
  2814   ASSERT_EQ(0U, agent(0)->MatchingCandidates(kBogusSrflxAddress));
  2816   agent(0)->SetLocal(TestObserver::ANSWER, agent(0)->answer());
  2817   PR_Sleep(1000); // Give time for the message queues.
  2819   // Verify that we got our candidates.
  2820   ASSERT_LE(2U, agent(0)->MatchingCandidates(kBogusSrflxAddress));
  2822   // Verify that the candidates appear in the answer.
  2823   size_t match;
  2824   match = agent(0)->getLocalDescription().find(kBogusSrflxAddress);
  2825   ASSERT_LT(0U, match);
  2830 TEST_F(SignalingAgentTest, CreateUntilFailThenWait) {
  2831   int i;
  2833   for (i=0; ; i++) {
  2834     if (!CreateAgent())
  2835       break;
  2836     std::cerr << "Created agent " << i << std::endl;
  2838   std::cerr << "Failed after creating " << i << " PCs " << std::endl;
  2839   PR_Sleep(10000);  // Wait to see if we crash
  2842 // Test for bug 856433.
  2843 TEST_F(SignalingAgentTest, CreateNoInit) {
  2844   CreateAgentNoInit();
  2848 /*
  2849  * Test for Bug 843595
  2850  */
  2851 TEST_F(SignalingTest, missingUfrag)
  2853   EnsureInit();
  2855   sipcc::MediaConstraints constraints;
  2856   std::string offer =
  2857     "v=0\r\n"
  2858     "o=Mozilla-SIPUA 2208 0 IN IP4 0.0.0.0\r\n"
  2859     "s=SIP Call\r\n"
  2860     "t=0 0\r\n"
  2861     "a=ice-pwd:4450d5a4a5f097855c16fa079893be18\r\n"
  2862     "a=fingerprint:sha-256 23:9A:2E:43:94:42:CF:46:68:FC:62:F9:F4:48:61:DB:"
  2863       "2F:8C:C9:FF:6B:25:54:9D:41:09:EF:83:A8:19:FC:B6\r\n"
  2864     "m=audio 56187 RTP/SAVPF 109 0 8 101\r\n"
  2865     "c=IN IP4 77.9.79.167\r\n"
  2866     "a=rtpmap:109 opus/48000/2\r\n"
  2867     "a=ptime:20\r\n"
  2868     "a=rtpmap:0 PCMU/8000\r\n"
  2869     "a=rtpmap:8 PCMA/8000\r\n"
  2870     "a=rtpmap:101 telephone-event/8000\r\n"
  2871     "a=fmtp:101 0-15\r\n"
  2872     "a=sendrecv\r\n"
  2873     "a=candidate:0 1 UDP 2113601791 192.168.178.20 56187 typ host\r\n"
  2874     "a=candidate:1 1 UDP 1694236671 77.9.79.167 56187 typ srflx raddr "
  2875       "192.168.178.20 rport 56187\r\n"
  2876     "a=candidate:0 2 UDP 2113601790 192.168.178.20 52955 typ host\r\n"
  2877     "a=candidate:1 2 UDP 1694236670 77.9.79.167 52955 typ srflx raddr "
  2878       "192.168.178.20 rport 52955\r\n"
  2879     "m=video 49929 RTP/SAVPF 120\r\n"
  2880     "c=IN IP4 77.9.79.167\r\n"
  2881     "a=rtpmap:120 VP8/90000\r\n"
  2882     "a=recvonly\r\n"
  2883     "a=candidate:0 1 UDP 2113601791 192.168.178.20 49929 typ host\r\n"
  2884     "a=candidate:1 1 UDP 1694236671 77.9.79.167 49929 typ srflx raddr "
  2885       "192.168.178.20 rport 49929\r\n"
  2886     "a=candidate:0 2 UDP 2113601790 192.168.178.20 50769 typ host\r\n"
  2887     "a=candidate:1 2 UDP 1694236670 77.9.79.167 50769 typ srflx raddr "
  2888       "192.168.178.20 rport 50769\r\n"
  2889     "m=application 54054 DTLS/SCTP 5000\r\n"
  2890     "c=IN IP4 77.9.79.167\r\n"
  2891     "a=fmtp:HuRUu]Dtcl\\zM,7(OmEU%O$gU]x/z\tD protocol=webrtc-datachannel;"
  2892       "streams=16\r\n"
  2893     "a=sendrecv\r\n";
  2895   // Need to create an offer, since that's currently required by our
  2896   // FSM. This may change in the future.
  2897   a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
  2898   a1_->SetLocal(TestObserver::OFFER, offer, true);
  2899   // We now detect the missing ICE parameters at SetRemoteDescription
  2900   a2_->SetRemote(TestObserver::OFFER, offer, true,
  2901                  PCImplSignalingState::SignalingStable);
  2902   ASSERT_TRUE(a2_->pObserver->state == TestObserver::stateError);
  2905 TEST_F(SignalingTest, AudioOnlyCalleeNoRtcpMux)
  2907   EnsureInit();
  2909   sipcc::MediaConstraints constraints;
  2911   a1_->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  2912   a1_->SetLocal(TestObserver::OFFER, a1_->offer(), false);
  2913   ParsedSDP sdpWrapper(a1_->offer());
  2914   sdpWrapper.DeleteLine("a=rtcp-mux");
  2915   std::cout << "Modified SDP " << std::endl
  2916             << indent(sdpWrapper.getSdp()) << std::endl;
  2917   a2_->SetRemote(TestObserver::OFFER, sdpWrapper.getSdp(), false);
  2918   a2_->CreateAnswer(constraints, sdpWrapper.getSdp(),
  2919     OFFER_AUDIO | ANSWER_AUDIO);
  2920   a2_->SetLocal(TestObserver::ANSWER, a2_->answer(), false);
  2921   a1_->SetRemote(TestObserver::ANSWER, a2_->answer(), false);
  2923   // Answer should not have a=rtcp-mux
  2924   ASSERT_EQ(a2_->getLocalDescription().find("\r\na=rtcp-mux"),
  2925             std::string::npos);
  2927   ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
  2928   ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
  2930   // Wait for some data to get written
  2931   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
  2932                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
  2934   a1_->CloseSendStreams();
  2935   a2_->CloseReceiveStreams();
  2937   ASSERT_GE(a1_->GetPacketsSent(0), 40);
  2938   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
  2940   // Check the low-level media pipeline
  2941   // for RTP and RTCP flows
  2942   // The first Local pipeline gets stored at 0
  2943   a1_->CheckMediaPipeline(0, 0, PIPELINE_LOCAL | PIPELINE_SEND);
  2945   // The first Remote pipeline gets stored at 1
  2946   a2_->CheckMediaPipeline(0, 1, 0);
  2949 TEST_F(SignalingTest, FullCallAudioNoMuxVideoMux)
  2951   EnsureInit();
  2953   sipcc::MediaConstraints constraints;
  2955   a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
  2956   a1_->SetLocal(TestObserver::OFFER, a1_->offer(), false);
  2957   ParsedSDP sdpWrapper(a1_->offer());
  2958   sdpWrapper.DeleteLine("a=rtcp-mux");
  2959   std::cout << "Modified SDP " << std::endl
  2960             << indent(sdpWrapper.getSdp()) << std::endl;
  2961   a2_->SetRemote(TestObserver::OFFER, sdpWrapper.getSdp(), false);
  2962   a2_->CreateAnswer(constraints, sdpWrapper.getSdp(), OFFER_AV | ANSWER_AV);
  2963   a2_->SetLocal(TestObserver::ANSWER, a2_->answer(), false);
  2964   a1_->SetRemote(TestObserver::ANSWER, a2_->answer(), false);
  2966   // Answer should have only one a=rtcp-mux line
  2967   size_t match = a2_->getLocalDescription().find("\r\na=rtcp-mux");
  2968   if (fRtcpMux) {
  2969     ASSERT_NE(match, std::string::npos);
  2970     match = a2_->getLocalDescription().find("\r\na=rtcp-mux", match + 1);
  2972   ASSERT_EQ(match, std::string::npos);
  2974   ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
  2975   ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
  2977   // Wait for some data to get written
  2978   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
  2979                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
  2981   a1_->CloseSendStreams();
  2982   a2_->CloseReceiveStreams();
  2984   ASSERT_GE(a1_->GetPacketsSent(0), 40);
  2985   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
  2987   // Check the low-level media pipeline
  2988   // for RTP and RTCP flows
  2989   // The first Local pipeline gets stored at 0
  2990   a1_->CheckMediaPipeline(0, 0, PIPELINE_LOCAL | PIPELINE_SEND);
  2992   // Now check video mux.
  2993   a1_->CheckMediaPipeline(0, 1,
  2994     PIPELINE_LOCAL | (fRtcpMux ? PIPELINE_RTCP_MUX : 0) | PIPELINE_SEND |
  2995     PIPELINE_VIDEO);
  2997   // The first Remote pipeline gets stored at 1
  2998   a2_->CheckMediaPipeline(0, 1, 0);
  3000   // Now check video mux.
  3001   a2_->CheckMediaPipeline(0, 2, (fRtcpMux ?  PIPELINE_RTCP_MUX : 0) |
  3002     PIPELINE_VIDEO | PIPELINE_RTCP_NACK, VideoSessionConduit::FrameRequestPli);
  3005 TEST_F(SignalingTest, RtcpFbInOffer)
  3007   EnsureInit();
  3008   sipcc::MediaConstraints constraints;
  3009   a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
  3010   const char *expected[] = { "nack", "nack pli", "ccm fir" };
  3011   CheckRtcpFbSdp(a1_->offer(), ARRAY_TO_SET(std::string, expected));
  3014 TEST_F(SignalingTest, RtcpFbInAnswer)
  3016   const char *feedbackTypes[] = { "nack", "nack pli", "ccm fir" };
  3017   TestRtcpFb(ARRAY_TO_SET(std::string, feedbackTypes),
  3018              PIPELINE_RTCP_NACK,
  3019              VideoSessionConduit::FrameRequestPli);
  3022 TEST_F(SignalingTest, RtcpFbNoNackBasic)
  3024   const char *feedbackTypes[] = { "nack pli", "ccm fir" };
  3025   TestRtcpFb(ARRAY_TO_SET(std::string, feedbackTypes),
  3026              0,
  3027              VideoSessionConduit::FrameRequestPli);
  3030 TEST_F(SignalingTest, RtcpFbNoNackPli)
  3032   const char *feedbackTypes[] = { "nack", "ccm fir" };
  3033   TestRtcpFb(ARRAY_TO_SET(std::string, feedbackTypes),
  3034              PIPELINE_RTCP_NACK,
  3035              VideoSessionConduit::FrameRequestFir);
  3038 TEST_F(SignalingTest, RtcpFbNoCcmFir)
  3040   const char *feedbackTypes[] = { "nack", "nack pli" };
  3041   TestRtcpFb(ARRAY_TO_SET(std::string, feedbackTypes),
  3042              PIPELINE_RTCP_NACK,
  3043              VideoSessionConduit::FrameRequestPli);
  3046 TEST_F(SignalingTest, RtcpFbNoNack)
  3048   const char *feedbackTypes[] = { "ccm fir" };
  3049   TestRtcpFb(ARRAY_TO_SET(std::string, feedbackTypes),
  3050              0,
  3051              VideoSessionConduit::FrameRequestFir);
  3054 TEST_F(SignalingTest, RtcpFbNoFrameRequest)
  3056   const char *feedbackTypes[] = { "nack" };
  3057   TestRtcpFb(ARRAY_TO_SET(std::string, feedbackTypes),
  3058              PIPELINE_RTCP_NACK,
  3059              VideoSessionConduit::FrameRequestNone);
  3062 TEST_F(SignalingTest, RtcpFbPliOnly)
  3064   const char *feedbackTypes[] = { "nack pli" };
  3065   TestRtcpFb(ARRAY_TO_SET(std::string, feedbackTypes),
  3066              0,
  3067              VideoSessionConduit::FrameRequestPli);
  3070 TEST_F(SignalingTest, RtcpFbNoFeedback)
  3072   const char *feedbackTypes[] = { };
  3073   TestRtcpFb(ARRAY_TO_SET(std::string, feedbackTypes),
  3074              0,
  3075              VideoSessionConduit::FrameRequestNone);
  3078 // In this test we will change the offer SDP's a=setup value
  3079 // from actpass to passive.  This will make the answer do active.
  3080 TEST_F(SignalingTest, AudioCallForceDtlsRoles)
  3082   EnsureInit();
  3084   sipcc::MediaConstraints constraints;
  3085   size_t match;
  3087   a1_->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  3089   // By default the offer should give actpass
  3090   std::string offer(a1_->offer());
  3091   match = offer.find("\r\na=setup:actpass");
  3092   ASSERT_NE(match, std::string::npos);
  3093   // Now replace the actpass with passive so that the answer will
  3094   // return active
  3095   offer.replace(match, strlen("\r\na=setup:actpass"),
  3096     "\r\na=setup:passive");
  3097   std::cout << "Modified SDP " << std::endl
  3098             << indent(offer) << std::endl;
  3100   a1_->SetLocal(TestObserver::OFFER, offer.c_str(), false);
  3101   a2_->SetRemote(TestObserver::OFFER, offer.c_str(), false);
  3102   a2_->CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
  3104   // Now the answer should contain a=setup:active
  3105   std::string answer(a2_->answer());
  3106   match = answer.find("\r\na=setup:active");
  3107   ASSERT_NE(match, std::string::npos);
  3109   // This should setup the DTLS with the same roles
  3110   // as the regular tests above.
  3111   a2_->SetLocal(TestObserver::ANSWER, a2_->answer(), false);
  3112   a1_->SetRemote(TestObserver::ANSWER, a2_->answer(), false);
  3114   ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
  3115   ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
  3117   // Wait for some data to get written
  3118   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
  3119                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
  3121   a1_->CloseSendStreams();
  3122   a2_->CloseReceiveStreams();
  3124   ASSERT_GE(a1_->GetPacketsSent(0), 40);
  3125   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
  3128 // In this test we will change the offer SDP's a=setup value
  3129 // from actpass to active.  This will make the answer do passive
  3130 TEST_F(SignalingTest, AudioCallReverseDtlsRoles)
  3132   EnsureInit();
  3134   sipcc::MediaConstraints constraints;
  3135   size_t match;
  3137   a1_->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  3139   // By default the offer should give actpass
  3140   std::string offer(a1_->offer());
  3141   match = offer.find("\r\na=setup:actpass");
  3142   ASSERT_NE(match, std::string::npos);
  3143   // Now replace the actpass with active so that the answer will
  3144   // return passive
  3145   offer.replace(match, strlen("\r\na=setup:actpass"),
  3146     "\r\na=setup:active");
  3147   std::cout << "Modified SDP " << std::endl
  3148             << indent(offer) << std::endl;
  3150   a1_->SetLocal(TestObserver::OFFER, offer.c_str(), false);
  3151   a2_->SetRemote(TestObserver::OFFER, offer.c_str(), false);
  3152   a2_->CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
  3154   // Now the answer should contain a=setup:passive
  3155   std::string answer(a2_->answer());
  3156   match = answer.find("\r\na=setup:passive");
  3157   ASSERT_NE(match, std::string::npos);
  3159   // This should setup the DTLS with the opposite roles
  3160   // than the regular tests above.
  3161   a2_->SetLocal(TestObserver::ANSWER, a2_->answer(), false);
  3162   a1_->SetRemote(TestObserver::ANSWER, a2_->answer(), false);
  3164   ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
  3165   ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
  3167   // Wait for some data to get written
  3168   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
  3169                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
  3171   a1_->CloseSendStreams();
  3172   a2_->CloseReceiveStreams();
  3174   ASSERT_GE(a1_->GetPacketsSent(0), 40);
  3175   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
  3178 // In this test we will change the answer SDP's a=setup value
  3179 // from active to passive.  This will make both sides do
  3180 // active and should not connect.
  3181 TEST_F(SignalingTest, AudioCallMismatchDtlsRoles)
  3183   EnsureInit();
  3185   sipcc::MediaConstraints constraints;
  3186   size_t match;
  3188   a1_->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  3190   // By default the offer should give actpass
  3191   std::string offer(a1_->offer());
  3192   match = offer.find("\r\na=setup:actpass");
  3193   ASSERT_NE(match, std::string::npos);
  3194   a1_->SetLocal(TestObserver::OFFER, offer.c_str(), false);
  3195   a2_->SetRemote(TestObserver::OFFER, offer.c_str(), false);
  3196   a2_->CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
  3198   // Now the answer should contain a=setup:active
  3199   std::string answer(a2_->answer());
  3200   match = answer.find("\r\na=setup:active");
  3201   ASSERT_NE(match, std::string::npos);
  3203   // Now replace the active with passive so that the offerer will
  3204   // also do active.
  3205   answer.replace(match, strlen("\r\na=setup:active"),
  3206     "\r\na=setup:passive");
  3207   std::cout << "Modified SDP " << std::endl
  3208             << indent(answer) << std::endl;
  3210   // This should setup the DTLS with both sides playing active
  3211   a2_->SetLocal(TestObserver::ANSWER, answer.c_str(), false);
  3212   a1_->SetRemote(TestObserver::ANSWER, answer.c_str(), false);
  3214   ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
  3215   ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
  3217   // Not using ASSERT_TRUE_WAIT here because we expect failure
  3218   PR_Sleep(kDefaultTimeout * 2); // Wait for some data to get written
  3220   a1_->CloseSendStreams();
  3221   a2_->CloseReceiveStreams();
  3223   ASSERT_GE(a1_->GetPacketsSent(0), 40);
  3224   // In this case we should receive nothing.
  3225   ASSERT_EQ(a2_->GetPacketsReceived(0), 0);
  3228 // In this test we will change the offer SDP's a=setup value
  3229 // from actpass to garbage.  It should ignore the garbage value
  3230 // and respond with setup:active
  3231 TEST_F(SignalingTest, AudioCallGarbageSetup)
  3233   EnsureInit();
  3235   sipcc::MediaConstraints constraints;
  3236   size_t match;
  3238   a1_->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  3240   // By default the offer should give actpass
  3241   std::string offer(a1_->offer());
  3242   match = offer.find("\r\na=setup:actpass");
  3243   ASSERT_NE(match, std::string::npos);
  3244   // Now replace the actpass with a garbage value
  3245   offer.replace(match, strlen("\r\na=setup:actpass"),
  3246     "\r\na=setup:G4rb4g3V4lu3");
  3247   std::cout << "Modified SDP " << std::endl
  3248             << indent(offer) << std::endl;
  3250   a1_->SetLocal(TestObserver::OFFER, offer.c_str(), false);
  3251   a2_->SetRemote(TestObserver::OFFER, offer.c_str(), false);
  3252   a2_->CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
  3254   // Now the answer should contain a=setup:active
  3255   std::string answer(a2_->answer());
  3256   match = answer.find("\r\na=setup:active");
  3257   ASSERT_NE(match, std::string::npos);
  3259   // This should setup the DTLS with the same roles
  3260   // as the regular tests above.
  3261   a2_->SetLocal(TestObserver::ANSWER, a2_->answer(), false);
  3262   a1_->SetRemote(TestObserver::ANSWER, a2_->answer(), false);
  3264   ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
  3265   ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
  3267   // Wait for some data to get written
  3268   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
  3269                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
  3271   a1_->CloseSendStreams();
  3272   a2_->CloseReceiveStreams();
  3274   ASSERT_GE(a1_->GetPacketsSent(0), 40);
  3275   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
  3278 // In this test we will change the offer SDP to remove the
  3279 // a=setup line.  Answer should respond with a=setup:active.
  3280 TEST_F(SignalingTest, AudioCallOfferNoSetupOrConnection)
  3282   EnsureInit();
  3284   sipcc::MediaConstraints constraints;
  3285   size_t match;
  3287   a1_->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  3289   // By default the offer should give setup:actpass
  3290   std::string offer(a1_->offer());
  3291   match = offer.find("\r\na=setup:actpass");
  3292   ASSERT_NE(match, std::string::npos);
  3293   // Remove the a=setup line
  3294   offer.replace(match, strlen("\r\na=setup:actpass"), "");
  3295   std::cout << "Modified SDP " << std::endl
  3296             << indent(offer) << std::endl;
  3298   a1_->SetLocal(TestObserver::OFFER, offer.c_str(), false);
  3299   a2_->SetRemote(TestObserver::OFFER, offer.c_str(), false);
  3300   a2_->CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
  3302   // Now the answer should contain a=setup:active
  3303   std::string answer(a2_->answer());
  3304   match = answer.find("\r\na=setup:active");
  3305   ASSERT_NE(match, std::string::npos);
  3307   // This should setup the DTLS with the same roles
  3308   // as the regular tests above.
  3309   a2_->SetLocal(TestObserver::ANSWER, a2_->answer(), false);
  3310   a1_->SetRemote(TestObserver::ANSWER, a2_->answer(), false);
  3312   ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
  3313   ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
  3315   // Wait for some data to get written
  3316   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
  3317                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
  3319   a1_->CloseSendStreams();
  3320   a2_->CloseReceiveStreams();
  3322   ASSERT_GE(a1_->GetPacketsSent(0), 40);
  3323   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
  3326 // In this test we will change the answer SDP to remove the
  3327 // a=setup line.  ICE should still connect since active will
  3328 // be assumed.
  3329 TEST_F(SignalingTest, AudioCallAnswerNoSetupOrConnection)
  3331   EnsureInit();
  3333   sipcc::MediaConstraints constraints;
  3334   size_t match;
  3336   a1_->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
  3338   // By default the offer should give setup:actpass
  3339   std::string offer(a1_->offer());
  3340   match = offer.find("\r\na=setup:actpass");
  3341   ASSERT_NE(match, std::string::npos);
  3343   a1_->SetLocal(TestObserver::OFFER, offer.c_str(), false);
  3344   a2_->SetRemote(TestObserver::OFFER, offer.c_str(), false);
  3345   a2_->CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
  3347   // Now the answer should contain a=setup:active
  3348   std::string answer(a2_->answer());
  3349   match = answer.find("\r\na=setup:active");
  3350   ASSERT_NE(match, std::string::npos);
  3351   // Remove the a=setup line
  3352   answer.replace(match, strlen("\r\na=setup:active"), "");
  3353   std::cout << "Modified SDP " << std::endl
  3354             << indent(answer) << std::endl;
  3356   // This should setup the DTLS with the same roles
  3357   // as the regular tests above.
  3358   a2_->SetLocal(TestObserver::ANSWER, answer, false);
  3359   a1_->SetRemote(TestObserver::ANSWER, answer, false);
  3361   ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
  3362   ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
  3364   // Wait for some data to get written
  3365   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
  3366                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
  3368   a1_->CloseSendStreams();
  3369   a2_->CloseReceiveStreams();
  3371   ASSERT_GE(a1_->GetPacketsSent(0), 40);
  3372   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
  3376 TEST_F(SignalingTest, FullCallRealTrickle)
  3378   wait_for_gather_ = false;
  3380   sipcc::MediaConstraints constraints;
  3381   OfferAnswer(constraints, constraints, OFFER_AV | ANSWER_AV,
  3382               true, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
  3384   // Wait for some data to get written
  3385   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
  3386                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
  3388   a1_->CloseSendStreams();
  3389   a2_->CloseReceiveStreams();
  3390   ASSERT_GE(a1_->GetPacketsSent(0), 40);
  3391   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
  3394 TEST_F(SignalingTest, FullCallRealTrickleTestServer)
  3396   wait_for_gather_ = false;
  3397   SetTestStunServer();
  3399   sipcc::MediaConstraints constraints;
  3400   OfferAnswer(constraints, constraints, OFFER_AV | ANSWER_AV,
  3401               true, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
  3403   TestStunServer::GetInstance()->SetActive(true);
  3405   // Wait for some data to get written
  3406   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
  3407                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
  3409   a1_->CloseSendStreams();
  3410   a2_->CloseReceiveStreams();
  3411   ASSERT_GE(a1_->GetPacketsSent(0), 40);
  3412   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
  3415 TEST_F(SignalingTest, hugeSdp)
  3417   EnsureInit();
  3419   sipcc::MediaConstraints constraints;
  3420   std::string offer =
  3421     "v=0\r\n"
  3422     "o=- 1109973417102828257 2 IN IP4 127.0.0.1\r\n"
  3423     "s=-\r\n"
  3424     "t=0 0\r\n"
  3425     "a=group:BUNDLE audio video\r\n"
  3426     "a=msid-semantic: WMS 1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIP\r\n"
  3427     "m=audio 32952 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126\r\n"
  3428     "c=IN IP4 128.64.32.16\r\n"
  3429     "a=rtcp:32952 IN IP4 128.64.32.16\r\n"
  3430     "a=candidate:77142221 1 udp 2113937151 192.168.137.1 54081 typ host generation 0\r\n"
  3431     "a=candidate:77142221 2 udp 2113937151 192.168.137.1 54081 typ host generation 0\r\n"
  3432     "a=candidate:983072742 1 udp 2113937151 172.22.0.56 54082 typ host generation 0\r\n"
  3433     "a=candidate:983072742 2 udp 2113937151 172.22.0.56 54082 typ host generation 0\r\n"
  3434     "a=candidate:2245074553 1 udp 1845501695 32.64.128.1 62397 typ srflx raddr 192.168.137.1 rport 54081 generation 0\r\n"
  3435     "a=candidate:2245074553 2 udp 1845501695 32.64.128.1 62397 typ srflx raddr 192.168.137.1 rport 54081 generation 0\r\n"
  3436     "a=candidate:2479353907 1 udp 1845501695 32.64.128.1 54082 typ srflx raddr 172.22.0.56 rport 54082 generation 0\r\n"
  3437     "a=candidate:2479353907 2 udp 1845501695 32.64.128.1 54082 typ srflx raddr 172.22.0.56 rport 54082 generation 0\r\n"
  3438     "a=candidate:1243276349 1 tcp 1509957375 192.168.137.1 0 typ host generation 0\r\n"
  3439     "a=candidate:1243276349 2 tcp 1509957375 192.168.137.1 0 typ host generation 0\r\n"
  3440     "a=candidate:1947960086 1 tcp 1509957375 172.22.0.56 0 typ host generation 0\r\n"
  3441     "a=candidate:1947960086 2 tcp 1509957375 172.22.0.56 0 typ host generation 0\r\n"
  3442     "a=candidate:1808221584 1 udp 33562367 128.64.32.16 32952 typ relay raddr 32.64.128.1 rport 62398 generation 0\r\n"
  3443     "a=candidate:1808221584 2 udp 33562367 128.64.32.16 32952 typ relay raddr 32.64.128.1 rport 62398 generation 0\r\n"
  3444     "a=candidate:507872740 1 udp 33562367 128.64.32.16 40975 typ relay raddr 32.64.128.1 rport 54085 generation 0\r\n"
  3445     "a=candidate:507872740 2 udp 33562367 128.64.32.16 40975 typ relay raddr 32.64.128.1 rport 54085 generation 0\r\n"
  3446     "a=ice-ufrag:xQuJwjX3V3eMA81k\r\n"
  3447     "a=ice-pwd:ZUiRmjS2GDhG140p73dAsSVP\r\n"
  3448     "a=ice-options:google-ice\r\n"
  3449     "a=fingerprint:sha-256 59:4A:8B:73:A7:73:53:71:88:D7:4D:58:28:0C:79:72:31:29:9B:05:37:DD:58:43:C2:D4:85:A2:B3:66:38:7A\r\n"
  3450     "a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n"
  3451     "a=sendrecv\r\n"
  3452     "a=mid:audio\r\n"
  3453     "a=rtcp-mux\r\n"
  3454     "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:/U44g3ULdtapeiSg+T3n6dDLBKIjpOhb/NXAL/2b\r\n"
  3455     "a=rtpmap:111 opus/48000/2\r\n"
  3456     "a=fmtp:111 minptime=10\r\n"
  3457     "a=rtpmap:103 ISAC/16000\r\n"
  3458     "a=rtpmap:104 ISAC/32000\r\n"
  3459     "a=rtpmap:0 PCMU/8000\r\n"
  3460     "a=rtpmap:8 PCMA/8000\r\n"
  3461     "a=rtpmap:107 CN/48000\r\n"
  3462     "a=rtpmap:106 CN/32000\r\n"
  3463     "a=rtpmap:105 CN/16000\r\n"
  3464     "a=rtpmap:13 CN/8000\r\n"
  3465     "a=rtpmap:126 telephone-event/8000\r\n"
  3466     "a=maxptime:60\r\n"
  3467     "a=ssrc:2271517329 cname:mKDNt7SQf6pwDlIn\r\n"
  3468     "a=ssrc:2271517329 msid:1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIP 1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIPa0\r\n"
  3469     "a=ssrc:2271517329 mslabel:1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIP\r\n"
  3470     "a=ssrc:2271517329 label:1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIPa0\r\n"
  3471     "m=video 32952 RTP/SAVPF 100 116 117\r\n"
  3472     "c=IN IP4 128.64.32.16\r\n"
  3473     "a=rtcp:32952 IN IP4 128.64.32.16\r\n"
  3474     "a=candidate:77142221 1 udp 2113937151 192.168.137.1 54081 typ host generation 0\r\n"
  3475     "a=candidate:77142221 2 udp 2113937151 192.168.137.1 54081 typ host generation 0\r\n"
  3476     "a=candidate:983072742 1 udp 2113937151 172.22.0.56 54082 typ host generation 0\r\n"
  3477     "a=candidate:983072742 2 udp 2113937151 172.22.0.56 54082 typ host generation 0\r\n"
  3478     "a=candidate:2245074553 1 udp 1845501695 32.64.128.1 62397 typ srflx raddr 192.168.137.1 rport 54081 generation 0\r\n"
  3479     "a=candidate:2245074553 2 udp 1845501695 32.64.128.1 62397 typ srflx raddr 192.168.137.1 rport 54081 generation 0\r\n"
  3480     "a=candidate:2479353907 1 udp 1845501695 32.64.128.1 54082 typ srflx raddr 172.22.0.56 rport 54082 generation 0\r\n"
  3481     "a=candidate:2479353907 2 udp 1845501695 32.64.128.1 54082 typ srflx raddr 172.22.0.56 rport 54082 generation 0\r\n"
  3482     "a=candidate:1243276349 1 tcp 1509957375 192.168.137.1 0 typ host generation 0\r\n"
  3483     "a=candidate:1243276349 2 tcp 1509957375 192.168.137.1 0 typ host generation 0\r\n"
  3484     "a=candidate:1947960086 1 tcp 1509957375 172.22.0.56 0 typ host generation 0\r\n"
  3485     "a=candidate:1947960086 2 tcp 1509957375 172.22.0.56 0 typ host generation 0\r\n"
  3486     "a=candidate:1808221584 1 udp 33562367 128.64.32.16 32952 typ relay raddr 32.64.128.1 rport 62398 generation 0\r\n"
  3487     "a=candidate:1808221584 2 udp 33562367 128.64.32.16 32952 typ relay raddr 32.64.128.1 rport 62398 generation 0\r\n"
  3488     "a=candidate:507872740 1 udp 33562367 128.64.32.16 40975 typ relay raddr 32.64.128.1 rport 54085 generation 0\r\n"
  3489     "a=candidate:507872740 2 udp 33562367 128.64.32.16 40975 typ relay raddr 32.64.128.1 rport 54085 generation 0\r\n"
  3490     "a=ice-ufrag:xQuJwjX3V3eMA81k\r\n"
  3491     "a=ice-pwd:ZUiRmjS2GDhG140p73dAsSVP\r\n"
  3492     "a=ice-options:google-ice\r\n"
  3493     "a=fingerprint:sha-256 59:4A:8B:73:A7:73:53:71:88:D7:4D:58:28:0C:79:72:31:29:9B:05:37:DD:58:43:C2:D4:85:A2:B3:66:38:7A\r\n"
  3494     "a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\n"
  3495     "a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n"
  3496     "a=sendrecv\r\n"
  3497     "a=mid:video\r\n"
  3498     "a=rtcp-mux\r\n"
  3499     "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:/U44g3ULdtapeiSg+T3n6dDLBKIjpOhb/NXAL/2b\r\n"
  3500     "a=rtpmap:100 VP8/90000\r\n"
  3501     "a=rtcp-fb:100 ccm fir\r\n"
  3502     "a=rtcp-fb:100 nack\r\n"
  3503     "a=rtcp-fb:100 goog-remb\r\n"
  3504     "a=rtpmap:116 red/90000\r\n"
  3505     "a=rtpmap:117 ulpfec/90000\r\n"
  3506     "a=ssrc:54724160 cname:mKDNt7SQf6pwDlIn\r\n"
  3507     "a=ssrc:54724160 msid:1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIP 1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIPv0\r\n"
  3508     "a=ssrc:54724160 mslabel:1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIP\r\n"
  3509     "a=ssrc:54724160 label:1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIPv0\r\n";
  3511   a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
  3512   a1_->SetLocal(TestObserver::OFFER, offer, true);
  3514   a2_->SetRemote(TestObserver::OFFER, offer, true);
  3515   ASSERT_GE(a2_->getRemoteDescription().length(), 4096U);
  3516   a2_->CreateAnswer(constraints, offer, OFFER_AV);
  3519 // Test max_fs and max_fr prefs have proper impact on SDP offer
  3520 TEST_F(SignalingTest, MaxFsFrInOffer)
  3522   EnsureInit();
  3524   sipcc::MediaConstraints constraints;
  3526   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
  3527   ASSERT_TRUE(prefs);
  3528   FsFrPrefClearer prefClearer(prefs);
  3530   SetMaxFsFr(prefs, 300, 30);
  3532   a1_->CreateOffer(constraints, OFFER_AV, SHOULD_CHECK_AV);
  3534   // Verify that SDP contains correct max-fs and max-fr
  3535   CheckMaxFsFrSdp(a1_->offer(), 120, 300, 30);
  3538 // Test max_fs and max_fr prefs have proper impact on SDP answer
  3539 TEST_F(SignalingTest, MaxFsFrInAnswer)
  3541   EnsureInit();
  3543   sipcc::MediaConstraints constraints;
  3545   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
  3546   ASSERT_TRUE(prefs);
  3547   FsFrPrefClearer prefClearer(prefs);
  3549   // We don't want max_fs and max_fr prefs impact SDP at this moment
  3550   SetMaxFsFr(prefs, 0, 0);
  3552   a1_->CreateOffer(constraints, OFFER_AV, SHOULD_CHECK_AV);
  3554   // SDP should not contain max-fs and max-fr here
  3555   CheckMaxFsFrSdp(a1_->offer(), 120, 0, 0);
  3557   a2_->SetRemote(TestObserver::OFFER, a1_->offer());
  3559   SetMaxFsFr(prefs, 600, 60);
  3561   a2_->CreateAnswer(constraints, a1_->offer(), OFFER_AV | ANSWER_AV);
  3563   // Verify that SDP contains correct max-fs and max-fr
  3564   CheckMaxFsFrSdp(a2_->answer(), 120, 600, 60);
  3567 // Test SDP offer has proper impact on callee's codec configuration
  3568 TEST_F(SignalingTest, MaxFsFrCalleeCodec)
  3570   EnsureInit();
  3572   sipcc::MediaConstraints constraints;
  3574   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
  3575   ASSERT_TRUE(prefs);
  3576   FsFrPrefClearer prefClearer(prefs);
  3578   // We don't want max_fs and max_fr prefs impact SDP at this moment
  3579   SetMaxFsFr(prefs, 0, 0);
  3581   a1_->CreateOffer(constraints, OFFER_AV, SHOULD_CHECK_AV);
  3583   ParsedSDP sdpWrapper(a1_->offer());
  3585   sdpWrapper.ReplaceLine("a=rtpmap:120",
  3586     "a=rtpmap:120 VP8/90000\r\na=fmtp:120 max-fs=300;max-fr=30\r\n");
  3588   std::cout << "Modified SDP " << std::endl
  3589             << indent(sdpWrapper.getSdp()) << std::endl;
  3591   // Double confirm that SDP offer contains correct max-fs and max-fr
  3592   CheckMaxFsFrSdp(sdpWrapper.getSdp(), 120, 300, 30);
  3594   a1_->SetLocal(TestObserver::OFFER, sdpWrapper.getSdp());
  3595   a2_->SetRemote(TestObserver::OFFER, sdpWrapper.getSdp());
  3597   a2_->CreateAnswer(constraints, sdpWrapper.getSdp(), OFFER_AV | ANSWER_AV);
  3599   // SDP should not contain max-fs and max-fr here
  3600   CheckMaxFsFrSdp(a2_->answer(), 120, 0, 0);
  3602   a2_->SetLocal(TestObserver::ANSWER, a2_->answer());
  3603   a1_->SetRemote(TestObserver::ANSWER, a2_->answer());
  3605   ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
  3606   ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
  3608   // Checking callee's video sending configuration does respect max-fs and
  3609   // max-fr in SDP offer.
  3610   mozilla::RefPtr<mozilla::MediaPipeline> pipeline =
  3611     a2_->GetMediaPipeline(1, 0, 1);
  3612   ASSERT_TRUE(pipeline);
  3613   mozilla::MediaSessionConduit *conduit = pipeline->Conduit();
  3614   ASSERT_TRUE(conduit);
  3615   ASSERT_EQ(conduit->type(), mozilla::MediaSessionConduit::VIDEO);
  3616   mozilla::VideoSessionConduit *video_conduit =
  3617     static_cast<mozilla::VideoSessionConduit*>(conduit);
  3619   ASSERT_EQ(video_conduit->SendingMaxFs(), (unsigned short) 300);
  3620   ASSERT_EQ(video_conduit->SendingMaxFr(), (unsigned short) 30);
  3623 // Test SDP answer has proper impact on caller's codec configuration
  3624 TEST_F(SignalingTest, MaxFsFrCallerCodec)
  3626   EnsureInit();
  3628   sipcc::MediaConstraints constraints;
  3630   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
  3631   ASSERT_TRUE(prefs);
  3632   FsFrPrefClearer prefClearer(prefs);
  3634   // We don't want max_fs and max_fr prefs impact SDP at this moment
  3635   SetMaxFsFr(prefs, 0, 0);
  3637   a1_->CreateOffer(constraints, OFFER_AV, SHOULD_CHECK_AV);
  3638   a1_->SetLocal(TestObserver::OFFER, a1_->offer());
  3639   a2_->SetRemote(TestObserver::OFFER, a1_->offer());
  3641   a2_->CreateAnswer(constraints, a1_->offer(), OFFER_AV | ANSWER_AV);
  3643   ParsedSDP sdpWrapper(a2_->answer());
  3645   sdpWrapper.ReplaceLine("a=rtpmap:120",
  3646     "a=rtpmap:120 VP8/90000\r\na=fmtp:120 max-fs=600;max-fr=60\r\n");
  3648   std::cout << "Modified SDP " << std::endl
  3649             << indent(sdpWrapper.getSdp()) << std::endl;
  3651   // Double confirm that SDP answer contains correct max-fs and max-fr
  3652   CheckMaxFsFrSdp(sdpWrapper.getSdp(), 120, 600, 60);
  3654   a2_->SetLocal(TestObserver::ANSWER, sdpWrapper.getSdp());
  3655   a1_->SetRemote(TestObserver::ANSWER, sdpWrapper.getSdp());
  3657   ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
  3658   ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
  3660   // Checking caller's video sending configuration does respect max-fs and
  3661   // max-fr in SDP answer.
  3662   mozilla::RefPtr<mozilla::MediaPipeline> pipeline =
  3663     a1_->GetMediaPipeline(1, 0, 1);
  3664   ASSERT_TRUE(pipeline);
  3665   mozilla::MediaSessionConduit *conduit = pipeline->Conduit();
  3666   ASSERT_TRUE(conduit);
  3667   ASSERT_EQ(conduit->type(), mozilla::MediaSessionConduit::VIDEO);
  3668   mozilla::VideoSessionConduit *video_conduit =
  3669     static_cast<mozilla::VideoSessionConduit*>(conduit);
  3671   ASSERT_EQ(video_conduit->SendingMaxFs(), (unsigned short) 600);
  3672   ASSERT_EQ(video_conduit->SendingMaxFr(), (unsigned short) 60);
  3675 } // End namespace test.
  3677 bool is_color_terminal(const char *terminal) {
  3678   if (!terminal) {
  3679     return false;
  3681   const char *color_terms[] = {
  3682     "xterm",
  3683     "xterm-color",
  3684     "xterm-256color",
  3685     "screen",
  3686     "linux",
  3687     "cygwin",
  3689   };
  3690   const char **p = color_terms;
  3691   while (*p) {
  3692     if (!strcmp(terminal, *p)) {
  3693       return true;
  3695     p++;
  3697   return false;
  3700 static std::string get_environment(const char *name) {
  3701   char *value = getenv(name);
  3703   if (!value)
  3704     return "";
  3706   return value;
  3709 // This exists to send as an event to trigger shutdown.
  3710 static void tests_complete() {
  3711   gTestsComplete = true;
  3714 // The GTest thread runs this instead of the main thread so it can
  3715 // do things like ASSERT_TRUE_WAIT which you could not do on the main thread.
  3716 static int gtest_main(int argc, char **argv) {
  3717   MOZ_ASSERT(!NS_IsMainThread());
  3719   ::testing::InitGoogleTest(&argc, argv);
  3721   for(int i=0; i<argc; i++) {
  3722     if (!strcmp(argv[i],"-t")) {
  3723       kDefaultTimeout = 20000;
  3727   ::testing::AddGlobalTestEnvironment(new test::SignalingEnvironment);
  3728   int result = RUN_ALL_TESTS();
  3730   test_utils->sts_target()->Dispatch(
  3731     WrapRunnableNM(&TestStunServer::ShutdownInstance), NS_DISPATCH_SYNC);
  3733   // Set the global shutdown flag and tickle the main thread
  3734   // The main thread did not go through Init() so calling Shutdown()
  3735   // on it will not work.
  3736   gMainThread->Dispatch(WrapRunnableNM(tests_complete), NS_DISPATCH_SYNC);
  3738   return result;
  3742 int main(int argc, char **argv) {
  3744   // This test can cause intermittent oranges on the builders
  3745   CHECK_ENVIRONMENT_FLAG("MOZ_WEBRTC_TESTS")
  3747   if (isatty(STDOUT_FILENO) && is_color_terminal(getenv("TERM"))) {
  3748     std::string ansiMagenta = "\x1b[35m";
  3749     std::string ansiCyan = "\x1b[36m";
  3750     std::string ansiColorOff = "\x1b[0m";
  3751     callerName = ansiCyan + callerName + ansiColorOff;
  3752     calleeName = ansiMagenta + calleeName + ansiColorOff;
  3755   std::string tmp = get_environment("STUN_SERVER_ADDRESS");
  3756   if (tmp != "")
  3757     g_stun_server_address = tmp;
  3759   tmp = get_environment("STUN_SERVER_PORT");
  3760   if (tmp != "")
  3761       g_stun_server_port = atoi(tmp.c_str());
  3763   test_utils = new MtransportTestUtils();
  3764   NSS_NoDB_Init(nullptr);
  3765   NSS_SetDomesticPolicy();
  3767   ::testing::TestEventListeners& listeners =
  3768         ::testing::UnitTest::GetInstance()->listeners();
  3769   // Adds a listener to the end.  Google Test takes the ownership.
  3770   listeners.Append(new test::RingbufferDumper(test_utils));
  3771   test_utils->sts_target()->Dispatch(
  3772     WrapRunnableNM(&TestStunServer::GetInstance), NS_DISPATCH_SYNC);
  3774   // Set the main thread global which is this thread.
  3775   nsIThread *thread;
  3776   NS_GetMainThread(&thread);
  3777   gMainThread = thread;
  3778   MOZ_ASSERT(NS_IsMainThread());
  3780   // Now create the GTest thread and run all of the tests on it
  3781   // When it is complete it will set gTestsComplete
  3782   NS_NewNamedThread("gtest_thread", &thread);
  3783   gGtestThread = thread;
  3785   int result;
  3786   gGtestThread->Dispatch(
  3787     WrapRunnableNMRet(gtest_main, argc, argv, &result), NS_DISPATCH_NORMAL);
  3789   // Here we handle the event queue for dispatches to the main thread
  3790   // When the GTest thread is complete it will send one more dispatch
  3791   // with gTestsComplete == true.
  3792   while (!gTestsComplete && NS_ProcessNextEvent());
  3794   gGtestThread->Shutdown();
  3796   sipcc::PeerConnectionCtx::Destroy();
  3797   delete test_utils;
  3799   return result;

mercurial