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

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

mercurial