blob: 1835f29094960a02b5c7a0e1c24bfb70df094cfa [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
kwibergd1fe2812016-04-27 06:47:29 -070011#include <memory>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000012#include <string>
13
Patrik Höglunde2d6a062017-10-05 14:53:33 +020014#include "api/candidate.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "api/jsepicecandidate.h"
16#include "api/jsepsessiondescription.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "p2p/base/p2pconstants.h"
Steve Antona3a92c22017-12-07 10:27:41 -080018#include "p2p/base/port.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "pc/mediasession.h"
Steve Anton4ab68ee2017-12-19 14:26:11 -080020#include "pc/sessiondescription.h"
Mirko Bonadei88bc9d52017-12-18 16:00:13 +010021#include "pc/webrtcsdp.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "rtc_base/gunit.h"
Steve Antona3a92c22017-12-07 10:27:41 -080023#include "rtc_base/ptr_util.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "rtc_base/stringencode.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000025
Steve Anton88f2cb92017-12-05 12:47:32 -080026using ::testing::Values;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000027using webrtc::IceCandidateCollection;
28using webrtc::IceCandidateInterface;
29using webrtc::JsepIceCandidate;
30using webrtc::JsepSessionDescription;
Steve Anton88f2cb92017-12-05 12:47:32 -080031using webrtc::SdpType;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032using webrtc::SessionDescriptionInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000033
34static const char kCandidateUfrag[] = "ufrag";
35static const char kCandidatePwd[] = "pwd";
36static const char kCandidateUfragVoice[] = "ufrag_voice";
37static const char kCandidatePwdVoice[] = "pwd_voice";
38static const char kCandidateUfragVideo[] = "ufrag_video";
39static const char kCandidatePwdVideo[] = "pwd_video";
zhihuang38989e52017-03-21 11:04:53 -070040static const char kCandidateFoundation[] = "a0+B/1";
41static const uint32_t kCandidatePriority = 2130706432U; // pref = 1.0
42static const uint32_t kCandidateGeneration = 2;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000043
44// This creates a session description with both audio and video media contents.
45// In SDP this is described by two m lines, one audio and one video.
46static cricket::SessionDescription* CreateCricketSessionDescription() {
47 cricket::SessionDescription* desc(new cricket::SessionDescription());
48 // AudioContentDescription
kwibergd1fe2812016-04-27 06:47:29 -070049 std::unique_ptr<cricket::AudioContentDescription> audio(
henrike@webrtc.org28e20752013-07-10 00:45:36 +000050 new cricket::AudioContentDescription());
51
52 // VideoContentDescription
kwibergd1fe2812016-04-27 06:47:29 -070053 std::unique_ptr<cricket::VideoContentDescription> video(
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054 new cricket::VideoContentDescription());
55
deadbeef67cf2c12016-04-13 10:07:16 -070056 audio->AddCodec(cricket::AudioCodec(103, "ISAC", 16000, 0, 0));
henrike@webrtc.org28e20752013-07-10 00:45:36 +000057 desc->AddContent(cricket::CN_AUDIO, cricket::NS_JINGLE_RTP,
58 audio.release());
59
perkj26752742016-10-24 01:21:16 -070060 video->AddCodec(cricket::VideoCodec(120, "VP8"));
henrike@webrtc.org28e20752013-07-10 00:45:36 +000061 desc->AddContent(cricket::CN_VIDEO, cricket::NS_JINGLE_RTP,
62 video.release());
63
deadbeef46eed762016-01-28 13:24:37 -080064 EXPECT_TRUE(desc->AddTransportInfo(cricket::TransportInfo(
65 cricket::CN_AUDIO,
66 cricket::TransportDescription(
67 std::vector<std::string>(), kCandidateUfragVoice, kCandidatePwdVoice,
68 cricket::ICEMODE_FULL, cricket::CONNECTIONROLE_NONE, NULL))));
69 EXPECT_TRUE(desc->AddTransportInfo(cricket::TransportInfo(
70 cricket::CN_VIDEO,
71 cricket::TransportDescription(
72 std::vector<std::string>(), kCandidateUfragVideo, kCandidatePwdVideo,
73 cricket::ICEMODE_FULL, cricket::CONNECTIONROLE_NONE, NULL))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +000074 return desc;
75}
76
77class JsepSessionDescriptionTest : public testing::Test {
78 protected:
henrike@webrtc.org28e20752013-07-10 00:45:36 +000079 virtual void SetUp() {
80 int port = 1234;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000081 rtc::SocketAddress address("127.0.0.1", port++);
guoweis@webrtc.org61c12472015-01-15 06:53:07 +000082 cricket::Candidate candidate(cricket::ICE_CANDIDATE_COMPONENT_RTP, "udp",
83 address, 1, "", "", "local", 0, "1");
henrike@webrtc.org28e20752013-07-10 00:45:36 +000084 candidate_ = candidate;
85 const std::string session_id =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000086 rtc::ToString(rtc::CreateRandomId64());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000087 const std::string session_version =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000088 rtc::ToString(rtc::CreateRandomId());
Steve Antona3a92c22017-12-07 10:27:41 -080089 jsep_desc_ = rtc::MakeUnique<JsepSessionDescription>(SdpType::kOffer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000090 ASSERT_TRUE(jsep_desc_->Initialize(CreateCricketSessionDescription(),
91 session_id, session_version));
92 }
93
94 std::string Serialize(const SessionDescriptionInterface* desc) {
95 std::string sdp;
96 EXPECT_TRUE(desc->ToString(&sdp));
97 EXPECT_FALSE(sdp.empty());
98 return sdp;
99 }
100
Steve Antona3a92c22017-12-07 10:27:41 -0800101 std::unique_ptr<SessionDescriptionInterface> DeSerialize(
102 const std::string& sdp) {
103 auto jsep_desc = rtc::MakeUnique<JsepSessionDescription>(SdpType::kOffer);
104 EXPECT_TRUE(webrtc::SdpDeserialize(sdp, jsep_desc.get(), nullptr));
105 return std::move(jsep_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000106 }
107
108 cricket::Candidate candidate_;
kwibergd1fe2812016-04-27 06:47:29 -0700109 std::unique_ptr<JsepSessionDescription> jsep_desc_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000110};
111
112// Test that number_of_mediasections() returns the number of media contents in
113// a session description.
114TEST_F(JsepSessionDescriptionTest, CheckSessionDescription) {
115 EXPECT_EQ(2u, jsep_desc_->number_of_mediasections());
116}
117
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700118// Test that we can add a candidate to a session description without MID.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000119TEST_F(JsepSessionDescriptionTest, AddCandidateWithoutMid) {
120 JsepIceCandidate jsep_candidate("", 0, candidate_);
121 EXPECT_TRUE(jsep_desc_->AddCandidate(&jsep_candidate));
122 const IceCandidateCollection* ice_candidates = jsep_desc_->candidates(0);
123 ASSERT_TRUE(ice_candidates != NULL);
124 EXPECT_EQ(1u, ice_candidates->count());
125 const IceCandidateInterface* ice_candidate = ice_candidates->at(0);
126 ASSERT_TRUE(ice_candidate != NULL);
127 candidate_.set_username(kCandidateUfragVoice);
128 candidate_.set_password(kCandidatePwdVoice);
129 EXPECT_TRUE(ice_candidate->candidate().IsEquivalent(candidate_));
130 EXPECT_EQ(0, ice_candidate->sdp_mline_index());
131 EXPECT_EQ(0u, jsep_desc_->candidates(1)->count());
132}
133
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700134// Test that we can add and remove candidates to a session description with
135// MID. Removing candidates requires MID (transport_name).
136TEST_F(JsepSessionDescriptionTest, AddAndRemoveCandidatesWithMid) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000137 // mid and m-line index don't match, in this case mid is preferred.
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700138 std::string mid = "video";
139 JsepIceCandidate jsep_candidate(mid, 0, candidate_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000140 EXPECT_TRUE(jsep_desc_->AddCandidate(&jsep_candidate));
141 EXPECT_EQ(0u, jsep_desc_->candidates(0)->count());
142 const IceCandidateCollection* ice_candidates = jsep_desc_->candidates(1);
143 ASSERT_TRUE(ice_candidates != NULL);
144 EXPECT_EQ(1u, ice_candidates->count());
145 const IceCandidateInterface* ice_candidate = ice_candidates->at(0);
146 ASSERT_TRUE(ice_candidate != NULL);
147 candidate_.set_username(kCandidateUfragVideo);
148 candidate_.set_password(kCandidatePwdVideo);
149 EXPECT_TRUE(ice_candidate->candidate().IsEquivalent(candidate_));
150 // The mline index should have been updated according to mid.
151 EXPECT_EQ(1, ice_candidate->sdp_mline_index());
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700152
153 std::vector<cricket::Candidate> candidates(1, candidate_);
154 candidates[0].set_transport_name(mid);
155 EXPECT_EQ(1u, jsep_desc_->RemoveCandidates(candidates));
156 EXPECT_EQ(0u, jsep_desc_->candidates(0)->count());
157 EXPECT_EQ(0u, jsep_desc_->candidates(1)->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000158}
159
160TEST_F(JsepSessionDescriptionTest, AddCandidateAlreadyHasUfrag) {
161 candidate_.set_username(kCandidateUfrag);
162 candidate_.set_password(kCandidatePwd);
163 JsepIceCandidate jsep_candidate("audio", 0, candidate_);
164 EXPECT_TRUE(jsep_desc_->AddCandidate(&jsep_candidate));
165 const IceCandidateCollection* ice_candidates = jsep_desc_->candidates(0);
166 ASSERT_TRUE(ice_candidates != NULL);
167 EXPECT_EQ(1u, ice_candidates->count());
168 const IceCandidateInterface* ice_candidate = ice_candidates->at(0);
169 ASSERT_TRUE(ice_candidate != NULL);
170 candidate_.set_username(kCandidateUfrag);
171 candidate_.set_password(kCandidatePwd);
172 EXPECT_TRUE(ice_candidate->candidate().IsEquivalent(candidate_));
173
174 EXPECT_EQ(0u, jsep_desc_->candidates(1)->count());
175}
176
177// Test that we can not add a candidate if there is no corresponding media
178// content in the session description.
179TEST_F(JsepSessionDescriptionTest, AddBadCandidate) {
180 JsepIceCandidate bad_candidate1("", 55, candidate_);
181 EXPECT_FALSE(jsep_desc_->AddCandidate(&bad_candidate1));
182
183 JsepIceCandidate bad_candidate2("some weird mid", 0, candidate_);
184 EXPECT_FALSE(jsep_desc_->AddCandidate(&bad_candidate2));
185}
186
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +0000187// Tests that repeatedly adding the same candidate, with or without credentials,
188// does not increase the number of candidates in the description.
189TEST_F(JsepSessionDescriptionTest, AddCandidateDuplicates) {
190 JsepIceCandidate jsep_candidate("", 0, candidate_);
191 EXPECT_TRUE(jsep_desc_->AddCandidate(&jsep_candidate));
192 EXPECT_EQ(1u, jsep_desc_->candidates(0)->count());
193
194 // Add the same candidate again. It should be ignored.
195 EXPECT_TRUE(jsep_desc_->AddCandidate(&jsep_candidate));
196 EXPECT_EQ(1u, jsep_desc_->candidates(0)->count());
197
198 // Create a new candidate, identical except that the ufrag and pwd are now
199 // populated.
200 candidate_.set_username(kCandidateUfragVoice);
201 candidate_.set_password(kCandidatePwdVoice);
202 JsepIceCandidate jsep_candidate_with_credentials("", 0, candidate_);
203
204 // This should also be identified as redundant and ignored.
205 EXPECT_TRUE(jsep_desc_->AddCandidate(&jsep_candidate_with_credentials));
206 EXPECT_EQ(1u, jsep_desc_->candidates(0)->count());
207}
208
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000209// Test that we can serialize a JsepSessionDescription and deserialize it again.
210TEST_F(JsepSessionDescriptionTest, SerializeDeserialize) {
211 std::string sdp = Serialize(jsep_desc_.get());
212
Steve Antona3a92c22017-12-07 10:27:41 -0800213 auto parsed_jsep_desc = DeSerialize(sdp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000214 EXPECT_EQ(2u, parsed_jsep_desc->number_of_mediasections());
215
216 std::string parsed_sdp = Serialize(parsed_jsep_desc.get());
217 EXPECT_EQ(sdp, parsed_sdp);
218}
219
220// Tests that we can serialize and deserialize a JsepSesssionDescription
221// with candidates.
222TEST_F(JsepSessionDescriptionTest, SerializeDeserializeWithCandidates) {
223 std::string sdp = Serialize(jsep_desc_.get());
224
225 // Add a candidate and check that the serialized result is different.
226 JsepIceCandidate jsep_candidate("audio", 0, candidate_);
227 EXPECT_TRUE(jsep_desc_->AddCandidate(&jsep_candidate));
228 std::string sdp_with_candidate = Serialize(jsep_desc_.get());
229 EXPECT_NE(sdp, sdp_with_candidate);
230
Steve Antona3a92c22017-12-07 10:27:41 -0800231 auto parsed_jsep_desc = DeSerialize(sdp_with_candidate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000232 std::string parsed_sdp_with_candidate = Serialize(parsed_jsep_desc.get());
233
234 EXPECT_EQ(sdp_with_candidate, parsed_sdp_with_candidate);
235}
zhihuang38989e52017-03-21 11:04:53 -0700236
237// TODO(zhihuang): Modify these tests. These are used to verify that after
238// adding the candidates, the connection_address field is set correctly. Modify
239// those so that the "connection address" is tested directly.
240// Tests serialization of SDP with only IPv6 candidates and verifies that IPv6
241// is used as default address in c line according to preference.
242TEST_F(JsepSessionDescriptionTest, SerializeSessionDescriptionWithIPv6Only) {
243 // Stun has a high preference than local host.
244 cricket::Candidate candidate1(
245 cricket::ICE_CANDIDATE_COMPONENT_RTP, "udp",
246 rtc::SocketAddress("::1", 1234), kCandidatePriority, "", "",
247 cricket::STUN_PORT_TYPE, kCandidateGeneration, kCandidateFoundation);
248 cricket::Candidate candidate2(
249 cricket::ICE_CANDIDATE_COMPONENT_RTP, "udp",
250 rtc::SocketAddress("::2", 1235), kCandidatePriority, "", "",
251 cricket::LOCAL_PORT_TYPE, kCandidateGeneration, kCandidateFoundation);
252
253 JsepIceCandidate jice1("audio", 0, candidate1);
254 JsepIceCandidate jice2("audio", 0, candidate2);
255 JsepIceCandidate jice3("video", 0, candidate1);
256 JsepIceCandidate jice4("video", 0, candidate2);
257 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice1));
258 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice2));
259 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice3));
260 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice4));
261 std::string message = Serialize(jsep_desc_.get());
262
263 // Should have a c line like this one.
264 EXPECT_NE(message.find("c=IN IP6 ::1"), std::string::npos);
265 // Shouldn't have a IP4 c line.
266 EXPECT_EQ(message.find("c=IN IP4"), std::string::npos);
267}
268
269// Tests serialization of SDP with both IPv4 and IPv6 candidates and
270// verifies that IPv4 is used as default address in c line even if the
271// preference of IPv4 is lower.
272TEST_F(JsepSessionDescriptionTest,
273 SerializeSessionDescriptionWithBothIPFamilies) {
274 cricket::Candidate candidate_v4(
275 cricket::ICE_CANDIDATE_COMPONENT_RTP, "udp",
276 rtc::SocketAddress("192.168.1.5", 1234), kCandidatePriority, "", "",
277 cricket::STUN_PORT_TYPE, kCandidateGeneration, kCandidateFoundation);
278 cricket::Candidate candidate_v6(
279 cricket::ICE_CANDIDATE_COMPONENT_RTP, "udp",
280 rtc::SocketAddress("::1", 1234), kCandidatePriority, "", "",
281 cricket::LOCAL_PORT_TYPE, kCandidateGeneration, kCandidateFoundation);
282
283 JsepIceCandidate jice_v4("audio", 0, candidate_v4);
284 JsepIceCandidate jice_v6("audio", 0, candidate_v6);
285 JsepIceCandidate jice_v4_video("video", 0, candidate_v4);
286 JsepIceCandidate jice_v6_video("video", 0, candidate_v6);
287 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice_v4));
288 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice_v6));
289 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice_v4_video));
290 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice_v6_video));
291 std::string message = Serialize(jsep_desc_.get());
292
293 // Should have a c line like this one.
294 EXPECT_NE(message.find("c=IN IP4 192.168.1.5"), std::string::npos);
295 // Shouldn't have a IP6 c line.
296 EXPECT_EQ(message.find("c=IN IP6"), std::string::npos);
297}
298
299// Tests serialization of SDP with both UDP and TCP candidates and
300// verifies that UDP is used as default address in c line even if the
301// preference of UDP is lower.
302TEST_F(JsepSessionDescriptionTest,
303 SerializeSessionDescriptionWithBothProtocols) {
304 // Stun has a high preference than local host.
305 cricket::Candidate candidate1(
306 cricket::ICE_CANDIDATE_COMPONENT_RTP, "tcp",
307 rtc::SocketAddress("::1", 1234), kCandidatePriority, "", "",
308 cricket::STUN_PORT_TYPE, kCandidateGeneration, kCandidateFoundation);
309 cricket::Candidate candidate2(
310 cricket::ICE_CANDIDATE_COMPONENT_RTP, "udp",
311 rtc::SocketAddress("fe80::1234:5678:abcd:ef12", 1235), kCandidatePriority,
312 "", "", cricket::LOCAL_PORT_TYPE, kCandidateGeneration,
313 kCandidateFoundation);
314
315 JsepIceCandidate jice1("audio", 0, candidate1);
316 JsepIceCandidate jice2("audio", 0, candidate2);
317 JsepIceCandidate jice3("video", 0, candidate1);
318 JsepIceCandidate jice4("video", 0, candidate2);
319 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice1));
320 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice2));
321 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice3));
322 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice4));
323 std::string message = Serialize(jsep_desc_.get());
324
325 // Should have a c line like this one.
326 EXPECT_NE(message.find("c=IN IP6 fe80::1234:5678:abcd:ef12"),
327 std::string::npos);
328 // Shouldn't have a IP4 c line.
329 EXPECT_EQ(message.find("c=IN IP4"), std::string::npos);
330}
331
332// Tests serialization of SDP with only TCP candidates and verifies that
333// null IPv4 is used as default address in c line.
334TEST_F(JsepSessionDescriptionTest, SerializeSessionDescriptionWithTCPOnly) {
335 // Stun has a high preference than local host.
336 cricket::Candidate candidate1(
337 cricket::ICE_CANDIDATE_COMPONENT_RTP, "tcp",
338 rtc::SocketAddress("::1", 1234), kCandidatePriority, "", "",
339 cricket::STUN_PORT_TYPE, kCandidateGeneration, kCandidateFoundation);
340 cricket::Candidate candidate2(
341 cricket::ICE_CANDIDATE_COMPONENT_RTP, "tcp",
342 rtc::SocketAddress("::2", 1235), kCandidatePriority, "", "",
343 cricket::LOCAL_PORT_TYPE, kCandidateGeneration, kCandidateFoundation);
344
345 JsepIceCandidate jice1("audio", 0, candidate1);
346 JsepIceCandidate jice2("audio", 0, candidate2);
347 JsepIceCandidate jice3("video", 0, candidate1);
348 JsepIceCandidate jice4("video", 0, candidate2);
349 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice1));
350 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice2));
351 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice3));
352 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice4));
353
354 std::string message = Serialize(jsep_desc_.get());
355 EXPECT_EQ(message.find("c=IN IP6 ::3"), std::string::npos);
356 // Should have a c line like this one when no any default exists.
357 EXPECT_NE(message.find("c=IN IP4 0.0.0.0"), std::string::npos);
358}
359
360// Tests that the connection address will be correctly set when the Candidate is
361// removed.
362TEST_F(JsepSessionDescriptionTest, RemoveCandidateAndSetConnectionAddress) {
363 cricket::Candidate candidate1(
364 cricket::ICE_CANDIDATE_COMPONENT_RTP, "udp",
365 rtc::SocketAddress("::1", 1234), kCandidatePriority, "", "",
366 cricket::LOCAL_PORT_TYPE, kCandidateGeneration, kCandidateFoundation);
367 candidate1.set_transport_name("audio");
368
369 cricket::Candidate candidate2(
370 cricket::ICE_CANDIDATE_COMPONENT_RTP, "tcp",
371 rtc::SocketAddress("::2", 1235), kCandidatePriority, "", "",
372 cricket::LOCAL_PORT_TYPE, kCandidateGeneration, kCandidateFoundation);
373 candidate2.set_transport_name("audio");
374
375 cricket::Candidate candidate3(
376 cricket::ICE_CANDIDATE_COMPONENT_RTP, "udp",
377 rtc::SocketAddress("192.168.1.1", 1236), kCandidatePriority, "", "",
378 cricket::LOCAL_PORT_TYPE, kCandidateGeneration, kCandidateFoundation);
379 candidate3.set_transport_name("audio");
380
381 JsepIceCandidate jice1("audio", 0, candidate1);
382 JsepIceCandidate jice2("audio", 0, candidate2);
383 JsepIceCandidate jice3("audio", 0, candidate3);
384
385 size_t audio_index = 0;
386 auto media_desc = static_cast<cricket::MediaContentDescription*>(
387 jsep_desc_->description()->contents()[audio_index].description);
388
389 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice1));
390 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice2));
391 ASSERT_TRUE(jsep_desc_->AddCandidate(&jice3));
392
393 std::vector<cricket::Candidate> candidates;
394 EXPECT_EQ("192.168.1.1:1236", media_desc->connection_address().ToString());
395
396 candidates.push_back(candidate3);
397 ASSERT_TRUE(jsep_desc_->RemoveCandidates(candidates));
398 EXPECT_EQ("[::1]:1234", media_desc->connection_address().ToString());
399
400 candidates.clear();
401 candidates.push_back(candidate2);
402 ASSERT_TRUE(jsep_desc_->RemoveCandidates(candidates));
403 EXPECT_EQ("[::1]:1234", media_desc->connection_address().ToString());
404
405 candidates.clear();
406 candidates.push_back(candidate1);
407 ASSERT_TRUE(jsep_desc_->RemoveCandidates(candidates));
408 EXPECT_EQ("0.0.0.0:9", media_desc->connection_address().ToString());
409}
Steve Anton88f2cb92017-12-05 12:47:32 -0800410
411class EnumerateAllSdpTypesTest : public ::testing::Test,
412 public ::testing::WithParamInterface<SdpType> {
413};
414
415TEST_P(EnumerateAllSdpTypesTest, TestIdentity) {
416 SdpType type = GetParam();
417
418 const char* str = webrtc::SdpTypeToString(type);
419 EXPECT_EQ(type, webrtc::SdpTypeFromString(str));
420}
421
422INSTANTIATE_TEST_CASE_P(JsepSessionDescriptionTest,
423 EnumerateAllSdpTypesTest,
424 Values(SdpType::kOffer,
425 SdpType::kPrAnswer,
426 SdpType::kAnswer));