2 * Copyright 2018 The WebRTC project authors. All Rights Reserved.
4 * 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.
11 #include "pc/sdp_serializer.h"
20 #include "test/gtest.h"
22 using cricket::RidDescription
;
23 using cricket::RidDirection
;
24 using cricket::SimulcastDescription
;
25 using cricket::SimulcastLayer
;
26 using cricket::SimulcastLayerList
;
27 using ::testing::TestWithParam
;
28 using ::testing::ValuesIn
;
33 // Checks that two vectors have the same objects in the same order.
34 template <typename TElement
>
35 void ExpectEqual(const std::vector
<TElement
>& expected
,
36 const std::vector
<TElement
>& actual
) {
37 ASSERT_EQ(expected
.size(), actual
.size());
38 for (size_t i
= 0; i
< expected
.size(); i
++) {
39 EXPECT_EQ(expected
[i
], actual
[i
]) << "Vectors differ at element " << i
;
43 // Template specialization for vectors of SimulcastLayer objects.
45 void ExpectEqual(const std::vector
<SimulcastLayer
>& expected
,
46 const std::vector
<SimulcastLayer
>& actual
) {
47 EXPECT_EQ(expected
.size(), actual
.size());
48 for (size_t i
= 0; i
< expected
.size(); i
++) {
49 EXPECT_EQ(expected
[i
].rid
, actual
[i
].rid
);
50 EXPECT_EQ(expected
[i
].is_paused
, actual
[i
].is_paused
);
54 // Checks that two maps have the same key-value pairs.
55 // Even though a map is technically ordered, the order semantics are not
56 // tested because having the same key-set in both maps implies that they
57 // are ordered the same because the template enforces that they have the
58 // same Key-Comparer type.
59 template <typename TKey
, typename TValue
>
60 void ExpectEqual(const std::map
<TKey
, TValue
>& expected
,
61 const std::map
<TKey
, TValue
>& actual
) {
62 typedef typename
std::map
<TKey
, TValue
>::const_iterator const_iterator
;
63 ASSERT_EQ(expected
.size(), actual
.size());
64 // Maps have unique keys, so if size is equal, it is enough to check
65 // that all the keys (and values) from one map exist in the other.
66 for (const auto& pair
: expected
) {
67 const_iterator iter
= actual
.find(pair
.first
);
68 EXPECT_NE(iter
, actual
.end()) << "Key: " << pair
.first
<< " not found";
69 EXPECT_EQ(pair
.second
, iter
->second
);
73 // Checks that the two SimulcastLayerLists are equal.
74 void ExpectEqual(const SimulcastLayerList
& expected
,
75 const SimulcastLayerList
& actual
) {
76 EXPECT_EQ(expected
.size(), actual
.size());
77 for (size_t i
= 0; i
< expected
.size(); i
++) {
78 ExpectEqual(expected
[i
], actual
[i
]);
82 // Checks that the two SimulcastDescriptions are equal.
83 void ExpectEqual(const SimulcastDescription
& expected
,
84 const SimulcastDescription
& actual
) {
85 ExpectEqual(expected
.send_layers(), actual
.send_layers());
86 ExpectEqual(expected
.receive_layers(), actual
.receive_layers());
89 // Checks that the two RidDescriptions are equal.
90 void ExpectEqual(const RidDescription
& expected
, const RidDescription
& actual
) {
91 EXPECT_EQ(expected
.rid
, actual
.rid
);
92 EXPECT_EQ(expected
.direction
, actual
.direction
);
93 ExpectEqual(expected
.payload_types
, actual
.payload_types
);
94 ExpectEqual(expected
.restrictions
, actual
.restrictions
);
98 class SimulcastSdpSerializerTest
: public TestWithParam
<const char*> {
100 // Runs a test for deserializing Simulcast.
101 // `str` - The serialized Simulcast to parse.
102 // `expected` - The expected output Simulcast to compare to.
103 void TestDeserialization(const std::string
& str
,
104 const SimulcastDescription
& expected
) const {
105 SdpSerializer deserializer
;
106 auto result
= deserializer
.DeserializeSimulcastDescription(str
);
107 EXPECT_TRUE(result
.ok());
108 ExpectEqual(expected
, result
.value());
111 // Runs a test for serializing Simulcast.
112 // `simulcast` - The Simulcast to serialize.
113 // `expected` - The expected output string to compare to.
114 void TestSerialization(const SimulcastDescription
& simulcast
,
115 const std::string
& expected
) const {
116 SdpSerializer serializer
;
117 auto result
= serializer
.SerializeSimulcastDescription(simulcast
);
118 EXPECT_EQ(expected
, result
);
124 // Test simple deserialization with no alternative streams.
125 TEST_F(SimulcastSdpSerializerTest
, Deserialize_SimpleCaseNoAlternatives
) {
126 std::string simulcast_str
= "send 1;2 recv 3;4";
127 SimulcastDescription expected
;
128 expected
.send_layers().AddLayer(SimulcastLayer("1", false));
129 expected
.send_layers().AddLayer(SimulcastLayer("2", false));
130 expected
.receive_layers().AddLayer(SimulcastLayer("3", false));
131 expected
.receive_layers().AddLayer(SimulcastLayer("4", false));
132 TestDeserialization(simulcast_str
, expected
);
135 // Test simulcast deserialization with alternative streams.
136 TEST_F(SimulcastSdpSerializerTest
, Deserialize_SimpleCaseWithAlternatives
) {
137 std::string simulcast_str
= "send 1,5;2,6 recv 3,7;4,8";
138 SimulcastDescription expected
;
139 expected
.send_layers().AddLayerWithAlternatives(
140 {SimulcastLayer("1", false), SimulcastLayer("5", false)});
141 expected
.send_layers().AddLayerWithAlternatives(
142 {SimulcastLayer("2", false), SimulcastLayer("6", false)});
143 expected
.receive_layers().AddLayerWithAlternatives(
144 {SimulcastLayer("3", false), SimulcastLayer("7", false)});
145 expected
.receive_layers().AddLayerWithAlternatives(
146 {SimulcastLayer("4", false), SimulcastLayer("8", false)});
147 TestDeserialization(simulcast_str
, expected
);
150 // Test simulcast deserialization when only some streams have alternatives.
151 TEST_F(SimulcastSdpSerializerTest
, Deserialize_WithSomeAlternatives
) {
152 std::string simulcast_str
= "send 1;2,6 recv 3,7;4";
153 SimulcastDescription expected
;
154 expected
.send_layers().AddLayer(SimulcastLayer("1", false));
155 expected
.send_layers().AddLayerWithAlternatives(
156 {SimulcastLayer("2", false), SimulcastLayer("6", false)});
157 expected
.receive_layers().AddLayerWithAlternatives(
158 {SimulcastLayer("3", false), SimulcastLayer("7", false)});
159 expected
.receive_layers().AddLayer(SimulcastLayer("4", false));
160 TestDeserialization(simulcast_str
, expected
);
163 // Test simulcast deserialization when only send streams are specified.
164 TEST_F(SimulcastSdpSerializerTest
, Deserialize_OnlySendStreams
) {
165 std::string simulcast_str
= "send 1;2,6;3,7;4";
166 SimulcastDescription expected
;
167 expected
.send_layers().AddLayer(SimulcastLayer("1", false));
168 expected
.send_layers().AddLayerWithAlternatives(
169 {SimulcastLayer("2", false), SimulcastLayer("6", false)});
170 expected
.send_layers().AddLayerWithAlternatives(
171 {SimulcastLayer("3", false), SimulcastLayer("7", false)});
172 expected
.send_layers().AddLayer(SimulcastLayer("4", false));
173 TestDeserialization(simulcast_str
, expected
);
176 // Test simulcast deserialization when only receive streams are specified.
177 TEST_F(SimulcastSdpSerializerTest
, Deserialize_OnlyReceiveStreams
) {
178 std::string simulcast_str
= "recv 1;2,6;3,7;4";
179 SimulcastDescription expected
;
180 expected
.receive_layers().AddLayer(SimulcastLayer("1", false));
181 expected
.receive_layers().AddLayerWithAlternatives(
182 {SimulcastLayer("2", false), SimulcastLayer("6", false)});
183 expected
.receive_layers().AddLayerWithAlternatives(
184 {SimulcastLayer("3", false), SimulcastLayer("7", false)});
185 expected
.receive_layers().AddLayer(SimulcastLayer("4", false));
186 TestDeserialization(simulcast_str
, expected
);
189 // Test simulcast deserialization with receive streams before send streams.
190 TEST_F(SimulcastSdpSerializerTest
, Deserialize_SendReceiveReversed
) {
191 std::string simulcast_str
= "recv 1;2,6 send 3,7;4";
192 SimulcastDescription expected
;
193 expected
.receive_layers().AddLayer(SimulcastLayer("1", false));
194 expected
.receive_layers().AddLayerWithAlternatives(
195 {SimulcastLayer("2", false), SimulcastLayer("6", false)});
196 expected
.send_layers().AddLayerWithAlternatives(
197 {SimulcastLayer("3", false), SimulcastLayer("7", false)});
198 expected
.send_layers().AddLayer(SimulcastLayer("4", false));
199 TestDeserialization(simulcast_str
, expected
);
202 // Test simulcast deserialization with some streams set to paused state.
203 TEST_F(SimulcastSdpSerializerTest
, Deserialize_PausedStreams
) {
204 std::string simulcast_str
= "recv 1;~2,6 send 3,7;~4";
205 SimulcastDescription expected
;
206 expected
.receive_layers().AddLayer(SimulcastLayer("1", false));
207 expected
.receive_layers().AddLayerWithAlternatives(
208 {SimulcastLayer("2", true), SimulcastLayer("6", false)});
209 expected
.send_layers().AddLayerWithAlternatives(
210 {SimulcastLayer("3", false), SimulcastLayer("7", false)});
211 expected
.send_layers().AddLayer(SimulcastLayer("4", true));
212 TestDeserialization(simulcast_str
, expected
);
215 // Parameterized negative test case for deserialization with invalid inputs.
216 TEST_P(SimulcastSdpSerializerTest
, SimulcastDeserializationFailed
) {
217 SdpSerializer deserializer
;
218 auto result
= deserializer
.DeserializeSimulcastDescription(GetParam());
219 EXPECT_FALSE(result
.ok());
222 // The malformed Simulcast inputs to use in the negative test case.
223 const char* kSimulcastMalformedStrings
[] = {
228 "recv 1;~2,6 recv 3,7;~4",
229 "send 1;~2,6 send 3,7;~4",
237 INSTANTIATE_TEST_SUITE_P(SimulcastDeserializationErrors
,
238 SimulcastSdpSerializerTest
,
239 ValuesIn(kSimulcastMalformedStrings
));
241 // Test a simple serialization scenario.
242 TEST_F(SimulcastSdpSerializerTest
, Serialize_SimpleCase
) {
243 SimulcastDescription simulcast
;
244 simulcast
.send_layers().AddLayer(SimulcastLayer("1", false));
245 simulcast
.receive_layers().AddLayer(SimulcastLayer("2", false));
246 TestSerialization(simulcast
, "send 1 recv 2");
249 // Test serialization with only send streams.
250 TEST_F(SimulcastSdpSerializerTest
, Serialize_OnlySend
) {
251 SimulcastDescription simulcast
;
252 simulcast
.send_layers().AddLayer(SimulcastLayer("1", false));
253 simulcast
.send_layers().AddLayer(SimulcastLayer("2", false));
254 TestSerialization(simulcast
, "send 1;2");
257 // Test serialization with only receive streams
258 TEST_F(SimulcastSdpSerializerTest
, Serialize_OnlyReceive
) {
259 SimulcastDescription simulcast
;
260 simulcast
.receive_layers().AddLayer(SimulcastLayer("1", false));
261 simulcast
.receive_layers().AddLayer(SimulcastLayer("2", false));
262 TestSerialization(simulcast
, "recv 1;2");
265 // Test a complex serialization with multiple streams, alternatives and states.
266 TEST_F(SimulcastSdpSerializerTest
, Serialize_ComplexSerialization
) {
267 SimulcastDescription simulcast
;
268 simulcast
.send_layers().AddLayerWithAlternatives(
269 {SimulcastLayer("2", false), SimulcastLayer("1", true)});
270 simulcast
.send_layers().AddLayerWithAlternatives(
271 {SimulcastLayer("4", false), SimulcastLayer("3", false)});
273 simulcast
.receive_layers().AddLayerWithAlternatives(
274 {SimulcastLayer("6", false), SimulcastLayer("7", false)});
275 simulcast
.receive_layers().AddLayer(SimulcastLayer("8", true));
276 simulcast
.receive_layers().AddLayerWithAlternatives(
277 {SimulcastLayer("9", false), SimulcastLayer("10", true),
278 SimulcastLayer("11", false)});
279 TestSerialization(simulcast
, "send 2,~1;4,3 recv 6,7;~8;9,~10,11");
282 class RidDescriptionSdpSerializerTest
: public TestWithParam
<const char*> {
284 // Runs a test for deserializing Rid Descriptions.
285 // `str` - The serialized Rid Description to parse.
286 // `expected` - The expected output RidDescription to compare to.
287 void TestDeserialization(const std::string
& str
,
288 const RidDescription
& expected
) const {
289 SdpSerializer deserializer
;
290 auto result
= deserializer
.DeserializeRidDescription(str
);
291 EXPECT_TRUE(result
.ok());
292 ExpectEqual(expected
, result
.value());
295 // Runs a test for serializing RidDescriptions.
296 // `rid_description` - The RidDescription to serialize.
297 // `expected` - The expected output string to compare to.
298 void TestSerialization(const RidDescription
& rid_description
,
299 const std::string
& expected
) const {
300 SdpSerializer serializer
;
301 auto result
= serializer
.SerializeRidDescription(rid_description
);
302 EXPECT_EQ(expected
, result
);
306 // Test serialization for RidDescription that only specifies send.
307 TEST_F(RidDescriptionSdpSerializerTest
, Serialize_OnlyDirectionSend
) {
308 RidDescription
rid_description("1", RidDirection::kSend
);
309 TestSerialization(rid_description
, "1 send");
312 // Test serialization for RidDescription that only specifies receive.
313 TEST_F(RidDescriptionSdpSerializerTest
, Serialize_OnlyDirectionReceive
) {
314 RidDescription
rid_description("2", RidDirection::kReceive
);
315 TestSerialization(rid_description
, "2 recv");
318 // Test serialization for RidDescription with format list.
319 TEST_F(RidDescriptionSdpSerializerTest
, Serialize_FormatList
) {
320 RidDescription
rid_description("3", RidDirection::kSend
);
321 rid_description
.payload_types
= {102, 101};
322 TestSerialization(rid_description
, "3 send pt=102,101");
325 // Test serialization for RidDescription with format list.
326 TEST_F(RidDescriptionSdpSerializerTest
, Serialize_FormatListSingleFormat
) {
327 RidDescription
rid_description("4", RidDirection::kReceive
);
328 rid_description
.payload_types
= {100};
329 TestSerialization(rid_description
, "4 recv pt=100");
332 // Test serialization for RidDescription with restriction list.
333 // Note: restriction list will be sorted because it is stored in a map.
334 TEST_F(RidDescriptionSdpSerializerTest
, Serialize_AttributeList
) {
335 RidDescription
rid_description("5", RidDirection::kSend
);
336 rid_description
.restrictions
["max-width"] = "1280";
337 rid_description
.restrictions
["max-height"] = "720";
338 TestSerialization(rid_description
, "5 send max-height=720;max-width=1280");
341 // Test serialization for RidDescription with format list and attribute list.
342 // Note: restriction list will be sorted because it is stored in a map.
343 TEST_F(RidDescriptionSdpSerializerTest
, Serialize_FormatAndAttributeList
) {
344 RidDescription
rid_description("6", RidDirection::kSend
);
345 rid_description
.payload_types
= {103, 104};
346 rid_description
.restrictions
["max-mbps"] = "108000";
347 rid_description
.restrictions
["max-br"] = "64000";
348 TestSerialization(rid_description
,
349 "6 send pt=103,104;max-br=64000;max-mbps=108000");
352 // Test serialization for attribute list that has key with no value.
353 // Note: restriction list will be sorted because it is stored in a map.
354 TEST_F(RidDescriptionSdpSerializerTest
, Serialize_RestrictionWithoutValue
) {
355 RidDescription
rid_description("7", RidDirection::kReceive
);
356 rid_description
.payload_types
= {103};
357 rid_description
.restrictions
["max-width"] = "1280";
358 rid_description
.restrictions
["max-height"] = "720";
359 rid_description
.restrictions
["max-myval"] = "";
360 TestSerialization(rid_description
,
361 "7 recv pt=103;max-height=720;max-myval;max-width=1280");
364 // Test simulcast deserialization with simple send stream.
365 TEST_F(RidDescriptionSdpSerializerTest
, Deserialize_SimpleSendCase
) {
366 RidDescription
rid_description("1", RidDirection::kSend
);
367 TestDeserialization("1 send", rid_description
);
370 // Test simulcast deserialization with simple receive stream.
371 TEST_F(RidDescriptionSdpSerializerTest
, Deserialize_SimpleReceiveCase
) {
372 RidDescription
rid_description("2", RidDirection::kReceive
);
373 TestDeserialization("2 recv", rid_description
);
376 // Test simulcast deserialization with single format.
377 TEST_F(RidDescriptionSdpSerializerTest
, Deserialize_WithFormat
) {
378 RidDescription
rid_description("3", RidDirection::kSend
);
379 rid_description
.payload_types
= {101};
380 TestDeserialization("3 send pt=101", rid_description
);
383 // Test simulcast deserialization with multiple formats.
384 TEST_F(RidDescriptionSdpSerializerTest
, Deserialize_WithMultipleFormats
) {
385 RidDescription
rid_description("4", RidDirection::kSend
);
386 rid_description
.payload_types
= {103, 104, 101, 102};
387 TestDeserialization("4 send pt=103,104,101,102", rid_description
);
390 // Test simulcast deserialization with restriction.
391 TEST_F(RidDescriptionSdpSerializerTest
, Deserialize_WithRestriction
) {
392 RidDescription
rid_description("5", RidDirection::kReceive
);
393 rid_description
.restrictions
["max-height"] = "720";
394 TestDeserialization("5 recv max-height=720", rid_description
);
397 // Test simulcast deserialization with multiple restrictions.
398 TEST_F(RidDescriptionSdpSerializerTest
, Deserialize_WithMultipleRestrictions
) {
399 RidDescription
rid_description("6", RidDirection::kReceive
);
400 rid_description
.restrictions
["max-height"] = "720";
401 rid_description
.restrictions
["max-width"] = "1920";
402 rid_description
.restrictions
["max-fr"] = "60";
403 rid_description
.restrictions
["max-bps"] = "14000";
405 "6 recv max-height=720;max-width=1920;max-bps=14000;max-fr=60",
409 // Test simulcast deserialization with custom (non-standard) restriction.
410 TEST_F(RidDescriptionSdpSerializerTest
, Deserialize_WithCustomRestrictions
) {
411 RidDescription
rid_description("7", RidDirection::kSend
);
412 rid_description
.restrictions
["foo"] = "bar";
413 rid_description
.restrictions
["max-height"] = "720";
414 TestDeserialization("7 send max-height=720;foo=bar", rid_description
);
417 // Test simulcast deserialization with multiple formats and restrictions.
418 TEST_F(RidDescriptionSdpSerializerTest
, Deserialize_WithFormatAndRestrictions
) {
419 RidDescription
rid_description("8", RidDirection::kSend
);
420 rid_description
.payload_types
= {104, 103};
421 rid_description
.restrictions
["max-height"] = "720";
422 rid_description
.restrictions
["max-width"] = "1920";
423 TestDeserialization("8 send pt=104,103;max-height=720;max-width=1920",
427 // Test simulcast deserialization with restriction that has no value.
428 TEST_F(RidDescriptionSdpSerializerTest
, Deserialize_RestrictionHasNoValue
) {
429 RidDescription
rid_description("9", RidDirection::kReceive
);
430 rid_description
.payload_types
= {104};
431 rid_description
.restrictions
["max-height"];
432 rid_description
.restrictions
["max-width"] = "1920";
433 TestDeserialization("9 recv pt=104;max-height;max-width=1920",
437 // Add this test to explicitly indicate that this is not an error.
438 // The following string "1 send recv" looks malformed because it specifies
439 // two directions, but in fact, the recv can be interpreted as a parameter
440 // without a value. While such a use case is dubious, the input string is
442 TEST_F(RidDescriptionSdpSerializerTest
, Deserialize_AmbiguousCase
) {
443 RidDescription
rid_description("1", RidDirection::kSend
);
444 rid_description
.restrictions
["recv"]; // No value.
445 TestDeserialization("1 send recv", rid_description
);
448 // Parameterized negative test case for deserialization with invalid inputs.
449 TEST_P(RidDescriptionSdpSerializerTest
, RidDescriptionDeserializationFailed
) {
450 SdpSerializer deserializer
;
451 auto result
= deserializer
.DeserializeRidDescription(GetParam());
452 EXPECT_FALSE(result
.ok());
455 // The malformed Rid Description inputs to use in the negative test case.
456 const char* kRidDescriptionMalformedStrings
[] = {
464 "1 send pt=1 max-width=720", // The ' ' should be ';' in restriction list.
468 "1 send max-width=720;pt=101", // pt= should appear first.
469 "1 send pt=101;pt=102",
471 "1 recv max-width=720;max-width=720",
481 INSTANTIATE_TEST_SUITE_P(RidDescriptionDeserializationErrors
,
482 RidDescriptionSdpSerializerTest
,
483 ValuesIn(kRidDescriptionMalformedStrings
));
485 } // namespace webrtc