 Chromium Code Reviews
 Chromium Code Reviews Issue 2742903002:
  Parse the connection data in SDP (c= line).  (Closed)
    
  
    Issue 2742903002:
  Parse the connection data in SDP (c= line).  (Closed) 
  | Index: webrtc/pc/webrtcsdp_unittest.cc | 
| diff --git a/webrtc/pc/webrtcsdp_unittest.cc b/webrtc/pc/webrtcsdp_unittest.cc | 
| index f5cac8921f3a3fddadf0672f372ce9f2c4713d1d..67226666052fc26b96fe7093bb369c407a8617c6 100644 | 
| --- a/webrtc/pc/webrtcsdp_unittest.cc | 
| +++ b/webrtc/pc/webrtcsdp_unittest.cc | 
| @@ -875,6 +875,8 @@ class WebRtcSdpTest : public testing::Test { | 
| audio_stream.sync_label = kStreamLabel1; | 
| audio_stream.ssrcs.push_back(kAudioTrack1Ssrc); | 
| audio_desc_->AddStream(audio_stream); | 
| + rtc::SocketAddress audio_addr("74.125.127.126", 2345); | 
| + audio_desc_->set_connection_address(audio_addr); | 
| 
Taylor Brandstetter
2017/03/20 18:29:58
nit (slash question): I still don't see that this
 
Zhi Huang
2017/03/21 03:43:12
The jdesc_ is initialized based on a copy of desc_
 | 
| desc_.AddContent(kAudioContentName, NS_JINGLE_RTP, audio_desc_); | 
| // VideoContentDescription | 
| @@ -888,6 +890,8 @@ class WebRtcSdpTest : public testing::Test { | 
| cricket::SsrcGroup ssrc_group(kFecSsrcGroupSemantics, video_stream.ssrcs); | 
| video_stream.ssrc_groups.push_back(ssrc_group); | 
| video_desc_->AddStream(video_stream); | 
| + rtc::SocketAddress video_addr("74.125.224.39", 3457); | 
| + video_desc_->set_connection_address(video_addr); | 
| desc_.AddContent(kVideoContentName, NS_JINGLE_RTP, video_desc_); | 
| // TransportInfo | 
| @@ -1090,7 +1094,6 @@ class WebRtcSdpTest : public testing::Test { | 
| desc_.AddContent(kAudioContentName2, NS_JINGLE_RTP, audio_desc_2); | 
| EXPECT_TRUE(desc_.AddTransportInfo(TransportInfo( | 
| kAudioContentName2, TransportDescription(kUfragVoice2, kPwdVoice2)))); | 
| - | 
| // Video track 2, in stream 2. | 
| VideoContentDescription* video_desc_2 = CreateVideoContentDescription(); | 
| StreamParams video_track_2; | 
| @@ -1470,6 +1473,7 @@ class WebRtcSdpTest : public testing::Test { | 
| audio_desc_->Copy()); | 
| video_desc_ = static_cast<VideoContentDescription*>( | 
| video_desc_->Copy()); | 
| + | 
| desc_.RemoveContentByName(kAudioContentName); | 
| desc_.RemoveContentByName(kVideoContentName); | 
| desc_.AddContent(kAudioContentName, NS_JINGLE_RTP, audio_rejected, | 
| @@ -1485,10 +1489,7 @@ class WebRtcSdpTest : public testing::Test { | 
| ReplaceRejected(audio_rejected, video_rejected, &new_sdp); | 
| JsepSessionDescription jdesc_no_candidates(kDummyString); | 
| - if (!jdesc_no_candidates.Initialize(desc_.Copy(), kSessionId, | 
| - kSessionVersion)) { | 
| - return false; | 
| - } | 
| + MakeDescriptionWithoutCandidates(&jdesc_no_candidates); | 
| std::string message = webrtc::SdpSerialize(jdesc_no_candidates, false); | 
| EXPECT_EQ(new_sdp, message); | 
| return true; | 
| @@ -1766,6 +1767,14 @@ class WebRtcSdpTest : public testing::Test { | 
| EXPECT_TRUE(CompareSessionDescription(jdesc, jdesc_output_des)); | 
| } | 
| + void MakeDescriptionWithoutCandidates(JsepSessionDescription* jdesc) { | 
| + rtc::SocketAddress audio_addr("0.0.0.0", 9); | 
| 
Taylor Brandstetter
2017/03/20 18:29:58
nit: Could add a comment explaining this. "Calling
 
Zhi Huang
2017/03/21 03:43:12
Done.
 | 
| + rtc::SocketAddress video_addr("0.0.0.0", 9); | 
| + audio_desc_->set_connection_address(audio_addr); | 
| + video_desc_->set_connection_address(video_addr); | 
| + ASSERT_TRUE(jdesc->Initialize(desc_.Copy(), kSessionId, kSessionVersion)); | 
| + } | 
| + | 
| protected: | 
| SessionDescription desc_; | 
| AudioContentDescription* audio_desc_; | 
| @@ -1801,134 +1810,12 @@ TEST_F(WebRtcSdpTest, SerializeSessionDescriptionEmpty) { | 
| EXPECT_EQ("", webrtc::SdpSerialize(jdesc_empty, false)); | 
| } | 
| -// This tests serialization of SDP with only IPv6 candidates and verifies that | 
| -// IPv6 is used as default address in c line according to preference. | 
| -TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithIPv6Only) { | 
| - // Only test 1 m line. | 
| - desc_.RemoveContentByName("video_content_name"); | 
| - // Stun has a high preference than local host. | 
| - cricket::Candidate candidate1( | 
| - cricket::ICE_CANDIDATE_COMPONENT_RTP, "udp", | 
| - rtc::SocketAddress("::1", 1234), kCandidatePriority, "", "", | 
| - cricket::STUN_PORT_TYPE, kCandidateGeneration, kCandidateFoundation1); | 
| - cricket::Candidate candidate2( | 
| - cricket::ICE_CANDIDATE_COMPONENT_RTP, "udp", | 
| - rtc::SocketAddress("::2", 1235), kCandidatePriority, "", "", | 
| - cricket::LOCAL_PORT_TYPE, kCandidateGeneration, kCandidateFoundation1); | 
| - JsepSessionDescription jdesc(kDummyString); | 
| - ASSERT_TRUE(jdesc.Initialize(desc_.Copy(), kSessionId, kSessionVersion)); | 
| - | 
| - // Only add the candidates to audio m line. | 
| - JsepIceCandidate jice1("audio_content_name", 0, candidate1); | 
| - JsepIceCandidate jice2("audio_content_name", 0, candidate2); | 
| - ASSERT_TRUE(jdesc.AddCandidate(&jice1)); | 
| - ASSERT_TRUE(jdesc.AddCandidate(&jice2)); | 
| - std::string message = webrtc::SdpSerialize(jdesc, false); | 
| - | 
| - // Audio line should have a c line like this one. | 
| - EXPECT_NE(message.find("c=IN IP6 ::1"), std::string::npos); | 
| - // Shouldn't have a IP4 c line. | 
| - EXPECT_EQ(message.find("c=IN IP4"), std::string::npos); | 
| -} | 
| - | 
| -// This tests serialization of SDP with both IPv4 and IPv6 candidates and | 
| -// verifies that IPv4 is used as default address in c line even if the | 
| -// preference of IPv4 is lower. | 
| -TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithBothIPFamilies) { | 
| - // Only test 1 m line. | 
| - desc_.RemoveContentByName("video_content_name"); | 
| - cricket::Candidate candidate_v4( | 
| - cricket::ICE_CANDIDATE_COMPONENT_RTP, "udp", | 
| - rtc::SocketAddress("192.168.1.5", 1234), kCandidatePriority, "", "", | 
| - cricket::STUN_PORT_TYPE, kCandidateGeneration, kCandidateFoundation1); | 
| - cricket::Candidate candidate_v6( | 
| - cricket::ICE_CANDIDATE_COMPONENT_RTP, "udp", | 
| - rtc::SocketAddress("::1", 1234), kCandidatePriority, "", "", | 
| - cricket::LOCAL_PORT_TYPE, kCandidateGeneration, kCandidateFoundation1); | 
| - JsepSessionDescription jdesc(kDummyString); | 
| - ASSERT_TRUE(jdesc.Initialize(desc_.Copy(), kSessionId, kSessionVersion)); | 
| - | 
| - // Only add the candidates to audio m line. | 
| - JsepIceCandidate jice_v4("audio_content_name", 0, candidate_v4); | 
| - JsepIceCandidate jice_v6("audio_content_name", 0, candidate_v6); | 
| - ASSERT_TRUE(jdesc.AddCandidate(&jice_v4)); | 
| - ASSERT_TRUE(jdesc.AddCandidate(&jice_v6)); | 
| - std::string message = webrtc::SdpSerialize(jdesc, false); | 
| - | 
| - // Audio line should have a c line like this one. | 
| - EXPECT_NE(message.find("c=IN IP4 192.168.1.5"), std::string::npos); | 
| - // Shouldn't have a IP6 c line. | 
| - EXPECT_EQ(message.find("c=IN IP6"), std::string::npos); | 
| -} | 
| - | 
| -// This tests serialization of SDP with both UDP and TCP candidates and | 
| -// verifies that UDP is used as default address in c line even if the | 
| -// preference of UDP is lower. | 
| -TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithBothProtocols) { | 
| - // Only test 1 m line. | 
| - desc_.RemoveContentByName("video_content_name"); | 
| - // Stun has a high preference than local host. | 
| - cricket::Candidate candidate1( | 
| - cricket::ICE_CANDIDATE_COMPONENT_RTP, "tcp", | 
| - rtc::SocketAddress("::1", 1234), kCandidatePriority, "", "", | 
| - cricket::STUN_PORT_TYPE, kCandidateGeneration, kCandidateFoundation1); | 
| - cricket::Candidate candidate2( | 
| - cricket::ICE_CANDIDATE_COMPONENT_RTP, "udp", | 
| - rtc::SocketAddress("fe80::1234:5678:abcd:ef12", 1235), kCandidatePriority, | 
| - "", "", cricket::LOCAL_PORT_TYPE, kCandidateGeneration, | 
| - kCandidateFoundation1); | 
| - JsepSessionDescription jdesc(kDummyString); | 
| - ASSERT_TRUE(jdesc.Initialize(desc_.Copy(), kSessionId, kSessionVersion)); | 
| - | 
| - // Only add the candidates to audio m line. | 
| - JsepIceCandidate jice1("audio_content_name", 0, candidate1); | 
| - JsepIceCandidate jice2("audio_content_name", 0, candidate2); | 
| - ASSERT_TRUE(jdesc.AddCandidate(&jice1)); | 
| - ASSERT_TRUE(jdesc.AddCandidate(&jice2)); | 
| - std::string message = webrtc::SdpSerialize(jdesc, false); | 
| - | 
| - // Audio line should have a c line like this one. | 
| - EXPECT_NE(message.find("c=IN IP6 fe80::1234:5678:abcd:ef12"), | 
| - std::string::npos); | 
| - // Shouldn't have a IP4 c line. | 
| - EXPECT_EQ(message.find("c=IN IP4"), std::string::npos); | 
| -} | 
| - | 
| -// This tests serialization of SDP with only TCP candidates and verifies that | 
| -// null IPv4 is used as default address in c line. | 
| -TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithTCPOnly) { | 
| - // Only test 1 m line. | 
| - desc_.RemoveContentByName("video_content_name"); | 
| - // Stun has a high preference than local host. | 
| - cricket::Candidate candidate1( | 
| - cricket::ICE_CANDIDATE_COMPONENT_RTP, "tcp", | 
| - rtc::SocketAddress("::1", 1234), kCandidatePriority, "", "", | 
| - cricket::STUN_PORT_TYPE, kCandidateGeneration, kCandidateFoundation1); | 
| - cricket::Candidate candidate2( | 
| - cricket::ICE_CANDIDATE_COMPONENT_RTP, "tcp", | 
| - rtc::SocketAddress("::2", 1235), kCandidatePriority, "", "", | 
| - cricket::LOCAL_PORT_TYPE, kCandidateGeneration, kCandidateFoundation1); | 
| - JsepSessionDescription jdesc(kDummyString); | 
| - ASSERT_TRUE(jdesc.Initialize(desc_.Copy(), kSessionId, kSessionVersion)); | 
| - | 
| - // Only add the candidates to audio m line. | 
| - JsepIceCandidate jice1("audio_content_name", 0, candidate1); | 
| - JsepIceCandidate jice2("audio_content_name", 0, candidate2); | 
| - ASSERT_TRUE(jdesc.AddCandidate(&jice1)); | 
| - ASSERT_TRUE(jdesc.AddCandidate(&jice2)); | 
| - std::string message = webrtc::SdpSerialize(jdesc, false); | 
| - | 
| - // Audio line should have a c line like this one when no any default exists. | 
| - EXPECT_NE(message.find("c=IN IP4 0.0.0.0"), std::string::npos); | 
| -} | 
| - | 
| // This tests serialization of SDP with a=crypto and a=fingerprint, as would be | 
| // the case in a DTLS offer. | 
| TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithFingerprint) { | 
| AddFingerprint(); | 
| JsepSessionDescription jdesc_with_fingerprint(kDummyString); | 
| - ASSERT_TRUE(jdesc_with_fingerprint.Initialize(desc_.Copy(), | 
| - kSessionId, kSessionVersion)); | 
| + MakeDescriptionWithoutCandidates(&jdesc_with_fingerprint); | 
| std::string message = webrtc::SdpSerialize(jdesc_with_fingerprint, false); | 
| std::string sdp_with_fingerprint = kSdpString; | 
| @@ -1946,8 +1833,7 @@ TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithFingerprintNoCryptos) { | 
| AddFingerprint(); | 
| RemoveCryptos(); | 
| JsepSessionDescription jdesc_with_fingerprint(kDummyString); | 
| - ASSERT_TRUE(jdesc_with_fingerprint.Initialize(desc_.Copy(), | 
| - kSessionId, kSessionVersion)); | 
| + MakeDescriptionWithoutCandidates(&jdesc_with_fingerprint); | 
| std::string message = webrtc::SdpSerialize(jdesc_with_fingerprint, false); | 
| std::string sdp_with_fingerprint = kSdpString; | 
| @@ -1964,8 +1850,7 @@ TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithFingerprintNoCryptos) { | 
| TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithoutCandidates) { | 
| // JsepSessionDescription with desc but without candidates. | 
| JsepSessionDescription jdesc_no_candidates(kDummyString); | 
| - ASSERT_TRUE(jdesc_no_candidates.Initialize(desc_.Copy(), kSessionId, | 
| - kSessionVersion)); | 
| + MakeDescriptionWithoutCandidates(&jdesc_no_candidates); | 
| std::string message = webrtc::SdpSerialize(jdesc_no_candidates, false); | 
| EXPECT_EQ(std::string(kSdpString), message); | 
| } | 
| @@ -2058,7 +1943,7 @@ TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithRtpDataChannel) { | 
| AddRtpDataChannel(); | 
| JsepSessionDescription jsep_desc(kDummyString); | 
| - ASSERT_TRUE(jsep_desc.Initialize(desc_.Copy(), kSessionId, kSessionVersion)); | 
| + MakeDescriptionWithoutCandidates(&jsep_desc); | 
| std::string message = webrtc::SdpSerialize(jsep_desc, false); | 
| std::string expected_sdp = kSdpString; | 
| @@ -2071,7 +1956,7 @@ TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithSctpDataChannel) { | 
| AddSctpDataChannel(use_sctpmap); | 
| JsepSessionDescription jsep_desc(kDummyString); | 
| - ASSERT_TRUE(jsep_desc.Initialize(desc_.Copy(), kSessionId, kSessionVersion)); | 
| + MakeDescriptionWithoutCandidates(&jsep_desc); | 
| std::string message = webrtc::SdpSerialize(jsep_desc, false); | 
| std::string expected_sdp = kSdpString; | 
| @@ -2083,8 +1968,7 @@ TEST_F(WebRtcSdpTest, SerializeWithSctpDataChannelAndNewPort) { | 
| bool use_sctpmap = true; | 
| AddSctpDataChannel(use_sctpmap); | 
| JsepSessionDescription jsep_desc(kDummyString); | 
| - | 
| - ASSERT_TRUE(jsep_desc.Initialize(desc_.Copy(), kSessionId, kSessionVersion)); | 
| + MakeDescriptionWithoutCandidates(&jsep_desc); | 
| DataContentDescription* dcdesc = static_cast<DataContentDescription*>( | 
| jsep_desc.description()->GetContentDescriptionByName(kDataContentName)); | 
| @@ -2112,11 +1996,10 @@ TEST_F(WebRtcSdpTest, SerializeWithSctpDataChannelAndNewPort) { | 
| } | 
| TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithDataChannelAndBandwidth) { | 
| + JsepSessionDescription jsep_desc(kDummyString); | 
| AddRtpDataChannel(); | 
| data_desc_->set_bandwidth(100*1000); | 
| - JsepSessionDescription jsep_desc(kDummyString); | 
| - | 
| - ASSERT_TRUE(jsep_desc.Initialize(desc_.Copy(), kSessionId, kSessionVersion)); | 
| + MakeDescriptionWithoutCandidates(&jsep_desc); | 
| std::string message = webrtc::SdpSerialize(jsep_desc, false); | 
| std::string expected_sdp = kSdpString; | 
| @@ -2131,8 +2014,7 @@ TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithDataChannelAndBandwidth) { | 
| TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithExtmap) { | 
| AddExtmap(); | 
| JsepSessionDescription desc_with_extmap("dummy"); | 
| - ASSERT_TRUE(desc_with_extmap.Initialize(desc_.Copy(), | 
| - kSessionId, kSessionVersion)); | 
| + MakeDescriptionWithoutCandidates(&desc_with_extmap); | 
| std::string message = webrtc::SdpSerialize(desc_with_extmap, false); | 
| std::string sdp_with_extmap = kSdpString; | 
| @@ -3504,3 +3386,121 @@ TEST_F(WebRtcSdpTest, DeserializeMsidAttributeWithMissingStreamId) { | 
| JsepSessionDescription jdesc_output(kDummyString); | 
| EXPECT_FALSE(SdpDeserialize(kSdpWithMissingStreamId, &jdesc_output)); | 
| } | 
| + | 
| +// Tests that if both session-level address and media-level address exist, use | 
| +// the media-level address. | 
| +TEST_F(WebRtcSdpTest, ParseConnectionData) { | 
| + JsepSessionDescription jsep_desc(kDummyString); | 
| + | 
| + // Sesssion-level address. | 
| + std::string sdp = kSdpFullString; | 
| + InjectAfter("s=-\r\n", "c=IN IP4 192.168.0.3\r\n", &sdp); | 
| + EXPECT_TRUE(SdpDeserialize(sdp, &jsep_desc)); | 
| + | 
| + const auto& content1 = jsep_desc.description()->contents()[0]; | 
| + EXPECT_EQ("74.125.127.126:2345", | 
| + static_cast<cricket::MediaContentDescription*>(content1.description) | 
| + ->connection_address() | 
| + .ToString()); | 
| + const auto& content2 = jsep_desc.description()->contents()[1]; | 
| + EXPECT_EQ("74.125.224.39:3457", | 
| + static_cast<cricket::MediaContentDescription*>(content2.description) | 
| + ->connection_address() | 
| + .ToString()); | 
| +} | 
| + | 
| +// Tests that the session-level connection address will be used if the media | 
| +// level-addresses are not specified. | 
| +TEST_F(WebRtcSdpTest, ParseConnectionDataSessionLevelOnly) { | 
| + JsepSessionDescription jsep_desc(kDummyString); | 
| + | 
| + // Sesssion-level address. | 
| + std::string sdp = kSdpString; | 
| + InjectAfter("s=-\r\n", "c=IN IP4 192.168.0.3\r\n", &sdp); | 
| + // Remove the media level addresses. | 
| + Replace("c=IN IP4 0.0.0.0\r\n", "", &sdp); | 
| + Replace("c=IN IP4 0.0.0.0\r\n", "", &sdp); | 
| + EXPECT_TRUE(SdpDeserialize(sdp, &jsep_desc)); | 
| + | 
| + const auto& content1 = jsep_desc.description()->contents()[0]; | 
| + EXPECT_EQ("192.168.0.3:9", | 
| + static_cast<cricket::MediaContentDescription*>(content1.description) | 
| + ->connection_address() | 
| + .ToString()); | 
| + const auto& content2 = jsep_desc.description()->contents()[1]; | 
| + EXPECT_EQ("192.168.0.3:9", | 
| + static_cast<cricket::MediaContentDescription*>(content2.description) | 
| + ->connection_address() | 
| + .ToString()); | 
| +} | 
| + | 
| +TEST_F(WebRtcSdpTest, ParseConnectionDataIPv6) { | 
| + JsepSessionDescription jsep_desc(kDummyString); | 
| + | 
| + std::string sdp = kSdpString; | 
| + EXPECT_TRUE(SdpDeserialize(sdp, &jsep_desc)); | 
| + Replace("m=audio 9 RTP/SAVPF 111 103 104\r\nc=IN IP4 0.0.0.0\r\n", | 
| + "m=audio 9 RTP/SAVPF 111 103 104\r\nc=IN IP6 " | 
| + "2001:0db8:85a3:0000:0000:8a2e:0370:7335\r\n", | 
| + &sdp); | 
| + Replace("m=video 9 RTP/SAVPF 120\r\nc=IN IP4 0.0.0.0\r\n", | 
| + "m=video 9 RTP/SAVPF 120\r\nc=IN IP6 " | 
| + "2001:0db8:85a3:0000:0000:8a2e:0370:7336\r\n", | 
| + &sdp); | 
| + EXPECT_TRUE(SdpDeserialize(sdp, &jsep_desc)); | 
| + const auto& content1 = jsep_desc.description()->contents()[0]; | 
| + EXPECT_EQ("[2001:db8:85a3::8a2e:370:7335]:9", | 
| + static_cast<cricket::MediaContentDescription*>(content1.description) | 
| + ->connection_address() | 
| + .ToString()); | 
| + const auto& content2 = jsep_desc.description()->contents()[1]; | 
| + EXPECT_EQ("[2001:db8:85a3::8a2e:370:7336]:9", | 
| + static_cast<cricket::MediaContentDescription*>(content2.description) | 
| + ->connection_address() | 
| + .ToString()); | 
| +} | 
| + | 
| +// Test that the invalid or unsupprted connection data cannot be parsed. | 
| +TEST_F(WebRtcSdpTest, ParseConnectionDataFailure) { | 
| + JsepSessionDescription jsep_desc(kDummyString); | 
| + std::string sdp = kSdpString; | 
| + EXPECT_TRUE(SdpDeserialize(sdp, &jsep_desc)); | 
| + | 
| + // Unsupported multicast IPv4 address. | 
| + sdp = kSdpFullString; | 
| + Replace("c=IN IP4 74.125.224.39\r\n", "c=IN IP4 74.125.224.39/127\r\n", &sdp); | 
| + EXPECT_FALSE(SdpDeserialize(sdp, &jsep_desc)); | 
| + | 
| + // Unsupported multicast IPv6 address. | 
| + sdp = kSdpFullString; | 
| + Replace("c=IN IP4 74.125.224.39\r\n", "c=IN IP6 ::1/3\r\n", &sdp); | 
| + EXPECT_FALSE(SdpDeserialize(sdp, &jsep_desc)); | 
| + | 
| + // Mismatched address type. | 
| + sdp = kSdpFullString; | 
| + Replace("c=IN IP4 74.125.224.39\r\n", "c=IN IP6 74.125.224.39\r\n", &sdp); | 
| + EXPECT_FALSE(SdpDeserialize(sdp, &jsep_desc)); | 
| + | 
| + sdp = kSdpFullString; | 
| + Replace("c=IN IP4 74.125.224.39\r\n", | 
| + "c=IN IP4 2001:0db8:85a3:0000:0000:8a2e:0370:7334\r\n", &sdp); | 
| + EXPECT_FALSE(SdpDeserialize(sdp, &jsep_desc)); | 
| +} | 
| + | 
| +TEST_F(WebRtcSdpTest, SerializeAndDeserializeWithConnectionAddress) { | 
| + JsepSessionDescription expected_jsep(kDummyString); | 
| + MakeDescriptionWithoutCandidates(&expected_jsep); | 
| + // Serialization. | 
| + std::string message = webrtc::SdpSerialize(expected_jsep, false); | 
| + // Deserialization. | 
| + JsepSessionDescription jdesc(kDummyString); | 
| + EXPECT_TRUE(SdpDeserialize(message, &jdesc)); | 
| + auto audio_desc = static_cast<cricket::MediaContentDescription*>( | 
| + jdesc.description()->GetContentByName(kAudioContentName)->description); | 
| + auto video_desc = static_cast<cricket::MediaContentDescription*>( | 
| + jdesc.description()->GetContentByName(kVideoContentName)->description); | 
| + EXPECT_EQ(audio_desc_->connection_address().ToString(), | 
| + audio_desc->connection_address().ToString()); | 
| + EXPECT_EQ(video_desc_->connection_address().ToString(), | 
| + video_desc->connection_address().ToString()); | 
| +} |