Bug 844071 - Patch 3 - DTLS role negotiation unit test r=ekr
authorEthan Hugg <ethanhugg@gmail.com>
Mon, 26 Aug 2013 21:55:43 -0700
changeset 158939 842a3da6e311a8fca3734a8ecbfd37cf571da63f
parent 158938 55d6779a2cc640854299f5d18fa5968c72f31b9c
child 158940 8cad45f03f6aefd3cf27fe2c955fd6826bd867f8
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersekr
bugs844071
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 844071 - Patch 3 - DTLS role negotiation unit test r=ekr
media/webrtc/signaling/test/signaling_unittests.cpp
--- a/media/webrtc/signaling/test/signaling_unittests.cpp
+++ b/media/webrtc/signaling/test/signaling_unittests.cpp
@@ -2467,16 +2467,362 @@ TEST_F(SignalingTest, FullCallAudioNoMux
   a2_.CheckMediaPipeline(0, 1, 0);
 
   // Now check video mux.
   a2_.CheckMediaPipeline(0, 2, fRtcpMux ?
     PIPELINE_RTCP_MUX | PIPELINE_VIDEO :
     PIPELINE_VIDEO);
 }
 
+// In this test we will change the offer SDP's a=setup value
+// from actpass to passive.  This will make the answer do active.
+TEST_F(SignalingTest, AudioCallForceDtlsRoles)
+{
+  sipcc::MediaConstraints constraints;
+  size_t match;
+
+  a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+
+  // By default the offer should give actpass
+  std::string offer(a1_.offer());
+  match = offer.find("\r\na=setup:actpass");
+  ASSERT_NE(match, std::string::npos);
+  // Now replace the actpass with passive so that the answer will
+  // return active
+  offer.replace(match, strlen("\r\na=setup:actpass"),
+    "\r\na=setup:passive");
+  std::cout << "Modified SDP " << std::endl
+            << indent(offer) << std::endl;
+
+  a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false);
+  a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false);
+  a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
+
+  // Now the answer should contain a=setup:active
+  std::string answer(a2_.answer());
+  match = answer.find("\r\na=setup:active");
+  ASSERT_NE(match, std::string::npos);
+
+  // This should setup the DTLS with the same roles
+  // as the regular tests above.
+  a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false);
+  a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false);
+
+  ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
+  ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
+
+  // Wait for some data to get written
+  ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
+                   a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
+
+  a1_.CloseSendStreams();
+  a2_.CloseReceiveStreams();
+
+  ASSERT_GE(a1_.GetPacketsSent(0), 40);
+  ASSERT_GE(a2_.GetPacketsReceived(0), 40);
+}
+
+// In this test we will change the offer SDP's a=setup value
+// from actpass to active.  This will make the answer do passive
+TEST_F(SignalingTest, AudioCallReverseDtlsRoles)
+{
+  sipcc::MediaConstraints constraints;
+  size_t match;
+
+  a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+
+  // By default the offer should give actpass
+  std::string offer(a1_.offer());
+  match = offer.find("\r\na=setup:actpass");
+  ASSERT_NE(match, std::string::npos);
+  // Now replace the actpass with active so that the answer will
+  // return passive
+  offer.replace(match, strlen("\r\na=setup:actpass"),
+    "\r\na=setup:active");
+  std::cout << "Modified SDP " << std::endl
+            << indent(offer) << std::endl;
+
+  a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false);
+  a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false);
+  a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
+
+  // Now the answer should contain a=setup:passive
+  std::string answer(a2_.answer());
+  match = answer.find("\r\na=setup:passive");
+  ASSERT_NE(match, std::string::npos);
+
+  // This should setup the DTLS with the opposite roles
+  // than the regular tests above.
+  a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false);
+  a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false);
+
+  ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
+  ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
+
+  // Wait for some data to get written
+  ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
+                   a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
+
+  a1_.CloseSendStreams();
+  a2_.CloseReceiveStreams();
+
+  ASSERT_GE(a1_.GetPacketsSent(0), 40);
+  ASSERT_GE(a2_.GetPacketsReceived(0), 40);
+}
+
+// In this test we will change the answer SDP's a=setup value
+// from active to passive.  This will make both sides do
+// active and should not connect.
+TEST_F(SignalingTest, AudioCallMismatchDtlsRoles)
+{
+  sipcc::MediaConstraints constraints;
+  size_t match;
+
+  a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+
+  // By default the offer should give actpass
+  std::string offer(a1_.offer());
+  match = offer.find("\r\na=setup:actpass");
+  ASSERT_NE(match, std::string::npos);
+  a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false);
+  a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false);
+  a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
+
+  // Now the answer should contain a=setup:active
+  std::string answer(a2_.answer());
+  match = answer.find("\r\na=setup:active");
+  ASSERT_NE(match, std::string::npos);
+
+  // Now replace the active with passive so that the offerer will
+  // also do active.
+  answer.replace(match, strlen("\r\na=setup:active"),
+    "\r\na=setup:passive");
+  std::cout << "Modified SDP " << std::endl
+            << indent(answer) << std::endl;
+
+  // This should setup the DTLS with both sides playing active
+  a2_.SetLocal(TestObserver::ANSWER, answer.c_str(), false);
+  a1_.SetRemote(TestObserver::ANSWER, answer.c_str(), false);
+
+  ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
+  ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
+
+  // Not using ASSERT_TRUE_WAIT here because we expect failure
+  PR_Sleep(kDefaultTimeout * 2); // Wait for some data to get written
+
+  a1_.CloseSendStreams();
+  a2_.CloseReceiveStreams();
+
+  ASSERT_GE(a1_.GetPacketsSent(0), 40);
+  // In this case we should receive nothing.
+  ASSERT_EQ(a2_.GetPacketsReceived(0), 0);
+}
+
+// In this test we will change the offer SDP's a=setup value
+// from actpass to garbage.  It should ignore the garbage value
+// and respond with setup:active
+TEST_F(SignalingTest, AudioCallGarbageSetup)
+{
+  sipcc::MediaConstraints constraints;
+  size_t match;
+
+  a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+
+  // By default the offer should give actpass
+  std::string offer(a1_.offer());
+  match = offer.find("\r\na=setup:actpass");
+  ASSERT_NE(match, std::string::npos);
+  // Now replace the actpass with a garbage value
+  offer.replace(match, strlen("\r\na=setup:actpass"),
+    "\r\na=setup:G4rb4g3V4lu3");
+  std::cout << "Modified SDP " << std::endl
+            << indent(offer) << std::endl;
+
+  a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false);
+  a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false);
+  a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
+
+  // Now the answer should contain a=setup:active
+  std::string answer(a2_.answer());
+  match = answer.find("\r\na=setup:active");
+  ASSERT_NE(match, std::string::npos);
+
+  // This should setup the DTLS with the same roles
+  // as the regular tests above.
+  a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false);
+  a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false);
+
+  ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
+  ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
+
+  // Wait for some data to get written
+  ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
+                   a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
+
+  a1_.CloseSendStreams();
+  a2_.CloseReceiveStreams();
+
+  ASSERT_GE(a1_.GetPacketsSent(0), 40);
+  ASSERT_GE(a2_.GetPacketsReceived(0), 40);
+}
+
+// In this test we will change the offer SDP's a=connection value
+// from new to garbage.  It should ignore the garbage value
+// and respond with connection:new
+TEST_F(SignalingTest, AudioCallGarbageConnection)
+{
+  sipcc::MediaConstraints constraints;
+  size_t match;
+
+  a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+
+  // By default the offer should give connection:new
+  std::string offer(a1_.offer());
+  match = offer.find("\r\na=connection:new");
+  ASSERT_NE(match, std::string::npos);
+  // Now replace the 'new' with a garbage value
+  offer.replace(match, strlen("\r\na=connection:new"),
+    "\r\na=connection:G4rb4g3V4lu3");
+  std::cout << "Modified SDP " << std::endl
+            << indent(offer) << std::endl;
+
+  a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false);
+  a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false);
+  a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
+
+  // Now the answer should contain a=connection:new
+  std::string answer(a2_.answer());
+  match = answer.find("\r\na=connection:new");
+  ASSERT_NE(match, std::string::npos);
+
+  // This should setup the DTLS with the same roles
+  // as the regular tests above.
+  a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false);
+  a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false);
+
+  ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
+  ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
+
+  // Wait for some data to get written
+  ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
+                   a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
+
+  a1_.CloseSendStreams();
+  a2_.CloseReceiveStreams();
+
+  ASSERT_GE(a1_.GetPacketsSent(0), 40);
+  ASSERT_GE(a2_.GetPacketsReceived(0), 40);
+}
+
+// In this test we will change the offer SDP to remove the
+// a=setup and a=connection lines.  Answer should respond with
+// a=setup:active and a=connection:new
+TEST_F(SignalingTest, AudioCallOfferNoSetupOrConnection)
+{
+  sipcc::MediaConstraints constraints;
+  size_t match;
+
+  a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+
+  // By default the offer should give setup:actpass and connection:new
+  std::string offer(a1_.offer());
+  match = offer.find("\r\na=setup:actpass");
+  ASSERT_NE(match, std::string::npos);
+  // Remove the a=setup line
+  offer.replace(match, strlen("\r\na=setup:actpass"), "");
+  match = offer.find("\r\na=connection:new");
+  ASSERT_NE(match, std::string::npos);
+  // Remove the a=connection line
+  offer.replace(match, strlen("\r\na=connection:new"), "");
+  std::cout << "Modified SDP " << std::endl
+            << indent(offer) << std::endl;
+
+  a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false);
+  a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false);
+  a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
+
+  // Now the answer should contain a=setup:active and a=connection:new
+  std::string answer(a2_.answer());
+  match = answer.find("\r\na=setup:active");
+  ASSERT_NE(match, std::string::npos);
+  match = answer.find("\r\na=connection:new");
+  ASSERT_NE(match, std::string::npos);
+
+  // This should setup the DTLS with the same roles
+  // as the regular tests above.
+  a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false);
+  a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false);
+
+  ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
+  ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
+
+  // Wait for some data to get written
+  ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
+                   a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
+
+  a1_.CloseSendStreams();
+  a2_.CloseReceiveStreams();
+
+  ASSERT_GE(a1_.GetPacketsSent(0), 40);
+  ASSERT_GE(a2_.GetPacketsReceived(0), 40);
+}
+
+// In this test we will change the answer SDP to remove the
+// a=setup and a=connection lines.  ICE should still connect
+// since active will be assumed.
+TEST_F(SignalingTest, AudioCallAnswerNoSetupOrConnection)
+{
+  sipcc::MediaConstraints constraints;
+  size_t match;
+
+  a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+
+  // By default the offer should give setup:actpass and connection:new
+  std::string offer(a1_.offer());
+  match = offer.find("\r\na=setup:actpass");
+  ASSERT_NE(match, std::string::npos);
+  match = offer.find("\r\na=connection:new");
+  ASSERT_NE(match, std::string::npos);
+
+  a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false);
+  a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false);
+  a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
+
+  // Now the answer should contain a=setup:active and a=connection:new
+  std::string answer(a2_.answer());
+  match = answer.find("\r\na=setup:active");
+  ASSERT_NE(match, std::string::npos);
+  // Remove the a=setup line
+  answer.replace(match, strlen("\r\na=setup:active"), "");
+  match = answer.find("\r\na=connection:new");
+  ASSERT_NE(match, std::string::npos);
+  // Remove the a=connection line
+  answer.replace(match, strlen("\r\na=connection:new"), "");
+  std::cout << "Modified SDP " << std::endl
+            << indent(answer) << std::endl;
+
+  // This should setup the DTLS with the same roles
+  // as the regular tests above.
+  a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false);
+  a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false);
+
+  ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
+  ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
+
+  // Wait for some data to get written
+  ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
+                   a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
+
+  a1_.CloseSendStreams();
+  a2_.CloseReceiveStreams();
+
+  ASSERT_GE(a1_.GetPacketsSent(0), 40);
+  ASSERT_GE(a2_.GetPacketsReceived(0), 40);
+}
+
 } // End namespace test.
 
 bool is_color_terminal(const char *terminal) {
   if (!terminal) {
     return false;
   }
   const char *color_terms[] = {
     "xterm",