| Index: webrtc/api/peerconnectioninterface_unittest.cc
|
| diff --git a/webrtc/api/peerconnectioninterface_unittest.cc b/webrtc/api/peerconnectioninterface_unittest.cc
|
| index d673b4174a93a7a46aa2771477073b4c0b22ffe1..eb094b863f0e17ebcb82afe827f73d01d743c2b3 100644
|
| --- a/webrtc/api/peerconnectioninterface_unittest.cc
|
| +++ b/webrtc/api/peerconnectioninterface_unittest.cc
|
| @@ -72,11 +72,11 @@ static const char kSdpStringWithStream1[] =
|
| "o=- 0 0 IN IP4 127.0.0.1\r\n"
|
| "s=-\r\n"
|
| "t=0 0\r\n"
|
| + "m=audio 1 RTP/AVPF 103\r\n"
|
| "a=ice-ufrag:e5785931\r\n"
|
| "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
| "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
|
| "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
|
| - "m=audio 1 RTP/AVPF 103\r\n"
|
| "a=mid:audio\r\n"
|
| "a=sendrecv\r\n"
|
| "a=rtcp-mux\r\n"
|
| @@ -85,6 +85,10 @@ static const char kSdpStringWithStream1[] =
|
| "a=ssrc:1 mslabel:stream1\r\n"
|
| "a=ssrc:1 label:audiotrack0\r\n"
|
| "m=video 1 RTP/AVPF 120\r\n"
|
| + "a=ice-ufrag:e5785931\r\n"
|
| + "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
| + "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
|
| + "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
|
| "a=mid:video\r\n"
|
| "a=sendrecv\r\n"
|
| "a=rtcp-mux\r\n"
|
| @@ -100,11 +104,11 @@ static const char kSdpStringWithStream1AudioTrackOnly[] =
|
| "o=- 0 0 IN IP4 127.0.0.1\r\n"
|
| "s=-\r\n"
|
| "t=0 0\r\n"
|
| + "m=audio 1 RTP/AVPF 103\r\n"
|
| "a=ice-ufrag:e5785931\r\n"
|
| "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
| "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
|
| "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
|
| - "m=audio 1 RTP/AVPF 103\r\n"
|
| "a=mid:audio\r\n"
|
| "a=sendrecv\r\n"
|
| "a=rtpmap:103 ISAC/16000\r\n"
|
| @@ -121,12 +125,12 @@ static const char kSdpStringWithStream1And2[] =
|
| "o=- 0 0 IN IP4 127.0.0.1\r\n"
|
| "s=-\r\n"
|
| "t=0 0\r\n"
|
| + "a=msid-semantic: WMS stream1 stream2\r\n"
|
| + "m=audio 1 RTP/AVPF 103\r\n"
|
| "a=ice-ufrag:e5785931\r\n"
|
| "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
| "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
|
| "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
|
| - "a=msid-semantic: WMS stream1 stream2\r\n"
|
| - "m=audio 1 RTP/AVPF 103\r\n"
|
| "a=mid:audio\r\n"
|
| "a=sendrecv\r\n"
|
| "a=rtcp-mux\r\n"
|
| @@ -136,6 +140,10 @@ static const char kSdpStringWithStream1And2[] =
|
| "a=ssrc:3 cname:stream2\r\n"
|
| "a=ssrc:3 msid:stream2 audiotrack1\r\n"
|
| "m=video 1 RTP/AVPF 120\r\n"
|
| + "a=ice-ufrag:e5785931\r\n"
|
| + "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
| + "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
|
| + "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
|
| "a=mid:video\r\n"
|
| "a=sendrecv\r\n"
|
| "a=rtcp-mux\r\n"
|
| @@ -151,16 +159,20 @@ static const char kSdpStringWithoutStreams[] =
|
| "o=- 0 0 IN IP4 127.0.0.1\r\n"
|
| "s=-\r\n"
|
| "t=0 0\r\n"
|
| + "m=audio 1 RTP/AVPF 103\r\n"
|
| "a=ice-ufrag:e5785931\r\n"
|
| "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
| "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
|
| "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
|
| - "m=audio 1 RTP/AVPF 103\r\n"
|
| "a=mid:audio\r\n"
|
| "a=sendrecv\r\n"
|
| "a=rtcp-mux\r\n"
|
| "a=rtpmap:103 ISAC/16000\r\n"
|
| "m=video 1 RTP/AVPF 120\r\n"
|
| + "a=ice-ufrag:e5785931\r\n"
|
| + "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
| + "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
|
| + "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
|
| "a=mid:video\r\n"
|
| "a=sendrecv\r\n"
|
| "a=rtcp-mux\r\n"
|
| @@ -172,17 +184,21 @@ static const char kSdpStringWithMsidWithoutStreams[] =
|
| "o=- 0 0 IN IP4 127.0.0.1\r\n"
|
| "s=-\r\n"
|
| "t=0 0\r\n"
|
| + "a=msid-semantic: WMS\r\n"
|
| + "m=audio 1 RTP/AVPF 103\r\n"
|
| "a=ice-ufrag:e5785931\r\n"
|
| "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
| "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
|
| "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
|
| - "a=msid-semantic: WMS\r\n"
|
| - "m=audio 1 RTP/AVPF 103\r\n"
|
| "a=mid:audio\r\n"
|
| "a=sendrecv\r\n"
|
| "a=rtcp-mux\r\n"
|
| "a=rtpmap:103 ISAC/16000\r\n"
|
| "m=video 1 RTP/AVPF 120\r\n"
|
| + "a=ice-ufrag:e5785931\r\n"
|
| + "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
| + "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
|
| + "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
|
| "a=mid:video\r\n"
|
| "a=sendrecv\r\n"
|
| "a=rtcp-mux\r\n"
|
| @@ -194,11 +210,11 @@ static const char kSdpStringWithoutStreamsAudioOnly[] =
|
| "o=- 0 0 IN IP4 127.0.0.1\r\n"
|
| "s=-\r\n"
|
| "t=0 0\r\n"
|
| + "m=audio 1 RTP/AVPF 103\r\n"
|
| "a=ice-ufrag:e5785931\r\n"
|
| "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
| "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
|
| "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
|
| - "m=audio 1 RTP/AVPF 103\r\n"
|
| "a=mid:audio\r\n"
|
| "a=sendrecv\r\n"
|
| "a=rtcp-mux\r\n"
|
| @@ -210,17 +226,21 @@ static const char kSdpStringSendOnlyWithoutStreams[] =
|
| "o=- 0 0 IN IP4 127.0.0.1\r\n"
|
| "s=-\r\n"
|
| "t=0 0\r\n"
|
| + "m=audio 1 RTP/AVPF 103\r\n"
|
| "a=ice-ufrag:e5785931\r\n"
|
| "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
| "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
|
| "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
|
| - "m=audio 1 RTP/AVPF 103\r\n"
|
| "a=mid:audio\r\n"
|
| "a=sendrecv\r\n"
|
| "a=sendonly\r\n"
|
| "a=rtcp-mux\r\n"
|
| "a=rtpmap:103 ISAC/16000\r\n"
|
| "m=video 1 RTP/AVPF 120\r\n"
|
| + "a=ice-ufrag:e5785931\r\n"
|
| + "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
| + "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
|
| + "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
|
| "a=mid:video\r\n"
|
| "a=sendrecv\r\n"
|
| "a=sendonly\r\n"
|
| @@ -232,14 +252,14 @@ static const char kSdpStringInit[] =
|
| "o=- 0 0 IN IP4 127.0.0.1\r\n"
|
| "s=-\r\n"
|
| "t=0 0\r\n"
|
| - "a=ice-ufrag:e5785931\r\n"
|
| - "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
| - "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
|
| - "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
|
| "a=msid-semantic: WMS\r\n";
|
|
|
| static const char kSdpStringAudio[] =
|
| "m=audio 1 RTP/AVPF 103\r\n"
|
| + "a=ice-ufrag:e5785931\r\n"
|
| + "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
| + "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
|
| + "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
|
| "a=mid:audio\r\n"
|
| "a=sendrecv\r\n"
|
| "a=rtcp-mux\r\n"
|
| @@ -247,6 +267,10 @@ static const char kSdpStringAudio[] =
|
|
|
| static const char kSdpStringVideo[] =
|
| "m=video 1 RTP/AVPF 120\r\n"
|
| + "a=ice-ufrag:e5785931\r\n"
|
| + "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
| + "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
|
| + "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
|
| "a=mid:video\r\n"
|
| "a=sendrecv\r\n"
|
| "a=rtcp-mux\r\n"
|
| @@ -325,6 +349,18 @@ bool GetFirstSsrc(const cricket::ContentInfo* content_info, int* ssrc) {
|
| return true;
|
| }
|
|
|
| +// Get the ufrags out of an SDP blob. Useful for testing ICE restart
|
| +// behavior.
|
| +std::vector<std::string> GetUfrags(
|
| + const webrtc::SessionDescriptionInterface* desc) {
|
| + std::vector<std::string> ufrags;
|
| + for (const cricket::TransportInfo& info :
|
| + desc->description()->transport_infos()) {
|
| + ufrags.push_back(info.description.ice_ufrag);
|
| + }
|
| + return ufrags;
|
| +}
|
| +
|
| void SetSsrcToZero(std::string* sdp) {
|
| const char kSdpSsrcAtribute[] = "a=ssrc:";
|
| const char kSdpSsrcAtributeZero[] = "a=ssrc:0";
|
| @@ -2726,6 +2762,116 @@ TEST_F(PeerConnectionInterfaceTest, OnAddTrackCallback) {
|
| EXPECT_EQ(observer_.last_added_track_label_, kVideoTracks[0]);
|
| }
|
|
|
| +// Test that when SetConfiguration is called and the configuration is
|
| +// changing, the next offer causes an ICE restart.
|
| +TEST_F(PeerConnectionInterfaceTest, SetConfigurationCausingIceRetart) {
|
| + PeerConnectionInterface::RTCConfiguration config;
|
| + config.type = PeerConnectionInterface::kRelay;
|
| + // Need to pass default constraints to prevent disabling of DTLS...
|
| + FakeConstraints default_constraints;
|
| + CreatePeerConnection(config, &default_constraints);
|
| + AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
|
| +
|
| + // Do initial offer/answer so there's something to restart.
|
| + CreateOfferAsLocalDescription();
|
| + CreateAnswerAsRemoteDescription(kSdpStringWithStream1);
|
| +
|
| + // Grab the ufrags.
|
| + std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
|
| +
|
| + // Change ICE policy, which should trigger an ICE restart on the next offer.
|
| + config.type = PeerConnectionInterface::kAll;
|
| + EXPECT_TRUE(pc_->SetConfiguration(config));
|
| + CreateOfferAsLocalDescription();
|
| +
|
| + // Grab the new ufrags.
|
| + std::vector<std::string> subsequent_ufrags =
|
| + GetUfrags(pc_->local_description());
|
| +
|
| + // Sanity check.
|
| + EXPECT_EQ(initial_ufrags.size(), subsequent_ufrags.size());
|
| + // Check that each ufrag is different.
|
| + for (int i = 0; i < static_cast<int>(initial_ufrags.size()); ++i) {
|
| + EXPECT_NE(initial_ufrags[i], subsequent_ufrags[i]);
|
| + }
|
| +}
|
| +
|
| +// Test that when SetConfiguration is called and the configuration *isn't*
|
| +// changing, the next offer does *not* cause an ICE restart.
|
| +TEST_F(PeerConnectionInterfaceTest, SetConfigurationNotCausingIceRetart) {
|
| + PeerConnectionInterface::RTCConfiguration config;
|
| + config.type = PeerConnectionInterface::kRelay;
|
| + // Need to pass default constraints to prevent disabling of DTLS...
|
| + FakeConstraints default_constraints;
|
| + CreatePeerConnection(config, &default_constraints);
|
| + AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
|
| +
|
| + // Do initial offer/answer so there's something to restart.
|
| + CreateOfferAsLocalDescription();
|
| + CreateAnswerAsRemoteDescription(kSdpStringWithStream1);
|
| +
|
| + // Grab the ufrags.
|
| + std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
|
| +
|
| + // Call SetConfiguration with a config identical to what the PC was
|
| + // constructed with.
|
| + EXPECT_TRUE(pc_->SetConfiguration(config));
|
| + CreateOfferAsLocalDescription();
|
| +
|
| + // Grab the new ufrags.
|
| + std::vector<std::string> subsequent_ufrags =
|
| + GetUfrags(pc_->local_description());
|
| +
|
| + EXPECT_EQ(initial_ufrags, subsequent_ufrags);
|
| +}
|
| +
|
| +// Test for a weird corner case scenario:
|
| +// 1. Audio/video session established.
|
| +// 2. SetConfiguration changes ICE config; ICE restart needed.
|
| +// 3. ICE restart initiated by remote peer, but only for one m= section.
|
| +// 4. Next createOffer should initiate an ICE restart, but only for the other
|
| +// m= section; it would be pointless to do an ICE restart for the m= section
|
| +// that was already restarted.
|
| +TEST_F(PeerConnectionInterfaceTest, SetConfigurationCausingPartialIceRestart) {
|
| + PeerConnectionInterface::RTCConfiguration config;
|
| + config.type = PeerConnectionInterface::kRelay;
|
| + // Need to pass default constraints to prevent disabling of DTLS...
|
| + FakeConstraints default_constraints;
|
| + CreatePeerConnection(config, &default_constraints);
|
| + AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
|
| +
|
| + // Do initial offer/answer so there's something to restart.
|
| + CreateOfferAsLocalDescription();
|
| + CreateAnswerAsRemoteDescription(kSdpStringWithStream1);
|
| +
|
| + // Change ICE policy, which should set the "needs-ice-restart" flag.
|
| + config.type = PeerConnectionInterface::kAll;
|
| + EXPECT_TRUE(pc_->SetConfiguration(config));
|
| +
|
| + // Do ICE restart for the first m= section, initiated by remote peer.
|
| + webrtc::JsepSessionDescription* remote_offer =
|
| + new webrtc::JsepSessionDescription(SessionDescriptionInterface::kOffer);
|
| + EXPECT_TRUE(remote_offer->Initialize(kSdpStringWithStream1, nullptr));
|
| + remote_offer->description()->transport_infos()[0].description.ice_ufrag =
|
| + "modified";
|
| + EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
|
| + CreateAnswerAsLocalDescription();
|
| +
|
| + // Grab the ufrags.
|
| + std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
|
| + ASSERT_EQ(2, initial_ufrags.size());
|
| +
|
| + // Create offer and grab the new ufrags.
|
| + CreateOfferAsLocalDescription();
|
| + std::vector<std::string> subsequent_ufrags =
|
| + GetUfrags(pc_->local_description());
|
| + ASSERT_EQ(2, subsequent_ufrags.size());
|
| +
|
| + // Ensure that only the ufrag for the second m= section changed.
|
| + EXPECT_EQ(initial_ufrags[0], subsequent_ufrags[0]);
|
| + EXPECT_NE(initial_ufrags[1], subsequent_ufrags[1]);
|
| +}
|
| +
|
| class PeerConnectionMediaConfigTest : public testing::Test {
|
| protected:
|
| void SetUp() override {
|
|
|