• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
3  *
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.
9  */
10 
11 #include "pc/sdp_serializer.h"
12 
13 #include <map>
14 #include <string>
15 #include <utility>
16 #include <vector>
17 
18 #include "rtc_base/gunit.h"
19 
20 using cricket::RidDescription;
21 using cricket::RidDirection;
22 using cricket::SimulcastDescription;
23 using cricket::SimulcastLayer;
24 using cricket::SimulcastLayerList;
25 using ::testing::TestWithParam;
26 using ::testing::ValuesIn;
27 
28 namespace webrtc {
29 
30 namespace {
31 // Checks that two vectors have the same objects in the same order.
32 template <typename TElement>
ExpectEqual(const std::vector<TElement> & expected,const std::vector<TElement> & actual)33 void ExpectEqual(const std::vector<TElement>& expected,
34                  const std::vector<TElement>& actual) {
35   ASSERT_EQ(expected.size(), actual.size());
36   for (size_t i = 0; i < expected.size(); i++) {
37     EXPECT_EQ(expected[i], actual[i]) << "Vectors differ at element " << i;
38   }
39 }
40 
41 // Template specialization for vectors of SimulcastLayer objects.
42 template <>
ExpectEqual(const std::vector<SimulcastLayer> & expected,const std::vector<SimulcastLayer> & actual)43 void ExpectEqual(const std::vector<SimulcastLayer>& expected,
44                  const std::vector<SimulcastLayer>& actual) {
45   EXPECT_EQ(expected.size(), actual.size());
46   for (size_t i = 0; i < expected.size(); i++) {
47     EXPECT_EQ(expected[i].rid, actual[i].rid);
48     EXPECT_EQ(expected[i].is_paused, actual[i].is_paused);
49   }
50 }
51 
52 // Checks that two maps have the same key-value pairs.
53 // Even though a map is technically ordered, the order semantics are not
54 // tested because having the same key-set in both maps implies that they
55 // are ordered the same because the template enforces that they have the
56 // same Key-Comparer type.
57 template <typename TKey, typename TValue>
ExpectEqual(const std::map<TKey,TValue> & expected,const std::map<TKey,TValue> & actual)58 void ExpectEqual(const std::map<TKey, TValue>& expected,
59                  const std::map<TKey, TValue>& actual) {
60   typedef typename std::map<TKey, TValue>::const_iterator const_iterator;
61   ASSERT_EQ(expected.size(), actual.size());
62   // Maps have unique keys, so if size is equal, it is enough to check
63   // that all the keys (and values) from one map exist in the other.
64   for (const std::pair<TKey, TValue>& pair : expected) {
65     const_iterator iter = actual.find(pair.first);
66     EXPECT_NE(iter, actual.end()) << "Key: " << pair.first << " not found";
67     EXPECT_EQ(pair.second, iter->second);
68   }
69 }
70 
71 // Checks that the two SimulcastLayerLists are equal.
ExpectEqual(const SimulcastLayerList & expected,const SimulcastLayerList & actual)72 void ExpectEqual(const SimulcastLayerList& expected,
73                  const SimulcastLayerList& actual) {
74   EXPECT_EQ(expected.size(), actual.size());
75   for (size_t i = 0; i < expected.size(); i++) {
76     ExpectEqual(expected[i], actual[i]);
77   }
78 }
79 
80 // Checks that the two SimulcastDescriptions are equal.
ExpectEqual(const SimulcastDescription & expected,const SimulcastDescription & actual)81 void ExpectEqual(const SimulcastDescription& expected,
82                  const SimulcastDescription& actual) {
83   ExpectEqual(expected.send_layers(), actual.send_layers());
84   ExpectEqual(expected.receive_layers(), actual.receive_layers());
85 }
86 
87 // Checks that the two RidDescriptions are equal.
ExpectEqual(const RidDescription & expected,const RidDescription & actual)88 void ExpectEqual(const RidDescription& expected, const RidDescription& actual) {
89   EXPECT_EQ(expected.rid, actual.rid);
90   EXPECT_EQ(expected.direction, actual.direction);
91   ExpectEqual(expected.payload_types, actual.payload_types);
92   ExpectEqual(expected.restrictions, actual.restrictions);
93 }
94 }  // namespace
95 
96 class SimulcastSdpSerializerTest : public TestWithParam<const char*> {
97  public:
98   // Runs a test for deserializing Simulcast.
99   // |str| - The serialized Simulcast to parse.
100   // |expected| - The expected output Simulcast to compare to.
TestDeserialization(const std::string & str,const SimulcastDescription & expected) const101   void TestDeserialization(const std::string& str,
102                            const SimulcastDescription& expected) const {
103     SdpSerializer deserializer;
104     auto result = deserializer.DeserializeSimulcastDescription(str);
105     EXPECT_TRUE(result.ok());
106     ExpectEqual(expected, result.value());
107   }
108 
109   // Runs a test for serializing Simulcast.
110   // |simulcast| - The Simulcast to serialize.
111   // |expected| - The expected output string to compare to.
TestSerialization(const SimulcastDescription & simulcast,const std::string & expected) const112   void TestSerialization(const SimulcastDescription& simulcast,
113                          const std::string& expected) const {
114     SdpSerializer serializer;
115     auto result = serializer.SerializeSimulcastDescription(simulcast);
116     EXPECT_EQ(expected, result);
117   }
118 };
119 
120 // Test Cases
121 
122 // Test simple deserialization with no alternative streams.
TEST_F(SimulcastSdpSerializerTest,Deserialize_SimpleCaseNoAlternatives)123 TEST_F(SimulcastSdpSerializerTest, Deserialize_SimpleCaseNoAlternatives) {
124   std::string simulcast_str = "send 1;2 recv 3;4";
125   SimulcastDescription expected;
126   expected.send_layers().AddLayer(SimulcastLayer("1", false));
127   expected.send_layers().AddLayer(SimulcastLayer("2", false));
128   expected.receive_layers().AddLayer(SimulcastLayer("3", false));
129   expected.receive_layers().AddLayer(SimulcastLayer("4", false));
130   TestDeserialization(simulcast_str, expected);
131 }
132 
133 // Test simulcast deserialization with alternative streams.
TEST_F(SimulcastSdpSerializerTest,Deserialize_SimpleCaseWithAlternatives)134 TEST_F(SimulcastSdpSerializerTest, Deserialize_SimpleCaseWithAlternatives) {
135   std::string simulcast_str = "send 1,5;2,6 recv 3,7;4,8";
136   SimulcastDescription expected;
137   expected.send_layers().AddLayerWithAlternatives(
138       {SimulcastLayer("1", false), SimulcastLayer("5", false)});
139   expected.send_layers().AddLayerWithAlternatives(
140       {SimulcastLayer("2", false), SimulcastLayer("6", false)});
141   expected.receive_layers().AddLayerWithAlternatives(
142       {SimulcastLayer("3", false), SimulcastLayer("7", false)});
143   expected.receive_layers().AddLayerWithAlternatives(
144       {SimulcastLayer("4", false), SimulcastLayer("8", false)});
145   TestDeserialization(simulcast_str, expected);
146 }
147 
148 // Test simulcast deserialization when only some streams have alternatives.
TEST_F(SimulcastSdpSerializerTest,Deserialize_WithSomeAlternatives)149 TEST_F(SimulcastSdpSerializerTest, Deserialize_WithSomeAlternatives) {
150   std::string simulcast_str = "send 1;2,6 recv 3,7;4";
151   SimulcastDescription expected;
152   expected.send_layers().AddLayer(SimulcastLayer("1", false));
153   expected.send_layers().AddLayerWithAlternatives(
154       {SimulcastLayer("2", false), SimulcastLayer("6", false)});
155   expected.receive_layers().AddLayerWithAlternatives(
156       {SimulcastLayer("3", false), SimulcastLayer("7", false)});
157   expected.receive_layers().AddLayer(SimulcastLayer("4", false));
158   TestDeserialization(simulcast_str, expected);
159 }
160 
161 // Test simulcast deserialization when only send streams are specified.
TEST_F(SimulcastSdpSerializerTest,Deserialize_OnlySendStreams)162 TEST_F(SimulcastSdpSerializerTest, Deserialize_OnlySendStreams) {
163   std::string simulcast_str = "send 1;2,6;3,7;4";
164   SimulcastDescription expected;
165   expected.send_layers().AddLayer(SimulcastLayer("1", false));
166   expected.send_layers().AddLayerWithAlternatives(
167       {SimulcastLayer("2", false), SimulcastLayer("6", false)});
168   expected.send_layers().AddLayerWithAlternatives(
169       {SimulcastLayer("3", false), SimulcastLayer("7", false)});
170   expected.send_layers().AddLayer(SimulcastLayer("4", false));
171   TestDeserialization(simulcast_str, expected);
172 }
173 
174 // Test simulcast deserialization when only receive streams are specified.
TEST_F(SimulcastSdpSerializerTest,Deserialize_OnlyReceiveStreams)175 TEST_F(SimulcastSdpSerializerTest, Deserialize_OnlyReceiveStreams) {
176   std::string simulcast_str = "recv 1;2,6;3,7;4";
177   SimulcastDescription expected;
178   expected.receive_layers().AddLayer(SimulcastLayer("1", false));
179   expected.receive_layers().AddLayerWithAlternatives(
180       {SimulcastLayer("2", false), SimulcastLayer("6", false)});
181   expected.receive_layers().AddLayerWithAlternatives(
182       {SimulcastLayer("3", false), SimulcastLayer("7", false)});
183   expected.receive_layers().AddLayer(SimulcastLayer("4", false));
184   TestDeserialization(simulcast_str, expected);
185 }
186 
187 // Test simulcast deserialization with receive streams before send streams.
TEST_F(SimulcastSdpSerializerTest,Deserialize_SendReceiveReversed)188 TEST_F(SimulcastSdpSerializerTest, Deserialize_SendReceiveReversed) {
189   std::string simulcast_str = "recv 1;2,6 send 3,7;4";
190   SimulcastDescription expected;
191   expected.receive_layers().AddLayer(SimulcastLayer("1", false));
192   expected.receive_layers().AddLayerWithAlternatives(
193       {SimulcastLayer("2", false), SimulcastLayer("6", false)});
194   expected.send_layers().AddLayerWithAlternatives(
195       {SimulcastLayer("3", false), SimulcastLayer("7", false)});
196   expected.send_layers().AddLayer(SimulcastLayer("4", false));
197   TestDeserialization(simulcast_str, expected);
198 }
199 
200 // Test simulcast deserialization with some streams set to paused state.
TEST_F(SimulcastSdpSerializerTest,Deserialize_PausedStreams)201 TEST_F(SimulcastSdpSerializerTest, Deserialize_PausedStreams) {
202   std::string simulcast_str = "recv 1;~2,6 send 3,7;~4";
203   SimulcastDescription expected;
204   expected.receive_layers().AddLayer(SimulcastLayer("1", false));
205   expected.receive_layers().AddLayerWithAlternatives(
206       {SimulcastLayer("2", true), SimulcastLayer("6", false)});
207   expected.send_layers().AddLayerWithAlternatives(
208       {SimulcastLayer("3", false), SimulcastLayer("7", false)});
209   expected.send_layers().AddLayer(SimulcastLayer("4", true));
210   TestDeserialization(simulcast_str, expected);
211 }
212 
213 // Parameterized negative test case for deserialization with invalid inputs.
TEST_P(SimulcastSdpSerializerTest,SimulcastDeserializationFailed)214 TEST_P(SimulcastSdpSerializerTest, SimulcastDeserializationFailed) {
215   SdpSerializer deserializer;
216   auto result = deserializer.DeserializeSimulcastDescription(GetParam());
217   EXPECT_FALSE(result.ok());
218 }
219 
220 // The malformed Simulcast inputs to use in the negative test case.
221 const char* kSimulcastMalformedStrings[] = {
222     "send ",
223     "recv ",
224     "recv 1 send",
225     "receive 1",
226     "recv 1;~2,6 recv 3,7;~4",
227     "send 1;~2,6 send 3,7;~4",
228     "send ~;~2,6",
229     "send 1; ;~2,6",
230     "send 1,;~2,6",
231     "recv 1 send 2 3",
232     "",
233 };
234 
235 INSTANTIATE_TEST_SUITE_P(SimulcastDeserializationErrors,
236                          SimulcastSdpSerializerTest,
237                          ValuesIn(kSimulcastMalformedStrings));
238 
239 // Test a simple serialization scenario.
TEST_F(SimulcastSdpSerializerTest,Serialize_SimpleCase)240 TEST_F(SimulcastSdpSerializerTest, Serialize_SimpleCase) {
241   SimulcastDescription simulcast;
242   simulcast.send_layers().AddLayer(SimulcastLayer("1", false));
243   simulcast.receive_layers().AddLayer(SimulcastLayer("2", false));
244   TestSerialization(simulcast, "send 1 recv 2");
245 }
246 
247 // Test serialization with only send streams.
TEST_F(SimulcastSdpSerializerTest,Serialize_OnlySend)248 TEST_F(SimulcastSdpSerializerTest, Serialize_OnlySend) {
249   SimulcastDescription simulcast;
250   simulcast.send_layers().AddLayer(SimulcastLayer("1", false));
251   simulcast.send_layers().AddLayer(SimulcastLayer("2", false));
252   TestSerialization(simulcast, "send 1;2");
253 }
254 
255 // Test serialization with only receive streams
TEST_F(SimulcastSdpSerializerTest,Serialize_OnlyReceive)256 TEST_F(SimulcastSdpSerializerTest, Serialize_OnlyReceive) {
257   SimulcastDescription simulcast;
258   simulcast.receive_layers().AddLayer(SimulcastLayer("1", false));
259   simulcast.receive_layers().AddLayer(SimulcastLayer("2", false));
260   TestSerialization(simulcast, "recv 1;2");
261 }
262 
263 // Test a complex serialization with multiple streams, alternatives and states.
TEST_F(SimulcastSdpSerializerTest,Serialize_ComplexSerialization)264 TEST_F(SimulcastSdpSerializerTest, Serialize_ComplexSerialization) {
265   SimulcastDescription simulcast;
266   simulcast.send_layers().AddLayerWithAlternatives(
267       {SimulcastLayer("2", false), SimulcastLayer("1", true)});
268   simulcast.send_layers().AddLayerWithAlternatives(
269       {SimulcastLayer("4", false), SimulcastLayer("3", false)});
270 
271   simulcast.receive_layers().AddLayerWithAlternatives(
272       {SimulcastLayer("6", false), SimulcastLayer("7", false)});
273   simulcast.receive_layers().AddLayer(SimulcastLayer("8", true));
274   simulcast.receive_layers().AddLayerWithAlternatives(
275       {SimulcastLayer("9", false), SimulcastLayer("10", true),
276        SimulcastLayer("11", false)});
277   TestSerialization(simulcast, "send 2,~1;4,3 recv 6,7;~8;9,~10,11");
278 }
279 
280 class RidDescriptionSdpSerializerTest : public TestWithParam<const char*> {
281  public:
282   // Runs a test for deserializing Rid Descriptions.
283   // |str| - The serialized Rid Description to parse.
284   // |expected| - The expected output RidDescription to compare to.
TestDeserialization(const std::string & str,const RidDescription & expected) const285   void TestDeserialization(const std::string& str,
286                            const RidDescription& expected) const {
287     SdpSerializer deserializer;
288     auto result = deserializer.DeserializeRidDescription(str);
289     EXPECT_TRUE(result.ok());
290     ExpectEqual(expected, result.value());
291   }
292 
293   // Runs a test for serializing RidDescriptions.
294   // |rid_description| - The RidDescription to serialize.
295   // |expected| - The expected output string to compare to.
TestSerialization(const RidDescription & rid_description,const std::string & expected) const296   void TestSerialization(const RidDescription& rid_description,
297                          const std::string& expected) const {
298     SdpSerializer serializer;
299     auto result = serializer.SerializeRidDescription(rid_description);
300     EXPECT_EQ(expected, result);
301   }
302 };
303 
304 // Test serialization for RidDescription that only specifies send.
TEST_F(RidDescriptionSdpSerializerTest,Serialize_OnlyDirectionSend)305 TEST_F(RidDescriptionSdpSerializerTest, Serialize_OnlyDirectionSend) {
306   RidDescription rid_description("1", RidDirection::kSend);
307   TestSerialization(rid_description, "1 send");
308 }
309 
310 // Test serialization for RidDescription that only specifies receive.
TEST_F(RidDescriptionSdpSerializerTest,Serialize_OnlyDirectionReceive)311 TEST_F(RidDescriptionSdpSerializerTest, Serialize_OnlyDirectionReceive) {
312   RidDescription rid_description("2", RidDirection::kReceive);
313   TestSerialization(rid_description, "2 recv");
314 }
315 
316 // Test serialization for RidDescription with format list.
TEST_F(RidDescriptionSdpSerializerTest,Serialize_FormatList)317 TEST_F(RidDescriptionSdpSerializerTest, Serialize_FormatList) {
318   RidDescription rid_description("3", RidDirection::kSend);
319   rid_description.payload_types = {102, 101};
320   TestSerialization(rid_description, "3 send pt=102,101");
321 }
322 
323 // Test serialization for RidDescription with format list.
TEST_F(RidDescriptionSdpSerializerTest,Serialize_FormatListSingleFormat)324 TEST_F(RidDescriptionSdpSerializerTest, Serialize_FormatListSingleFormat) {
325   RidDescription rid_description("4", RidDirection::kReceive);
326   rid_description.payload_types = {100};
327   TestSerialization(rid_description, "4 recv pt=100");
328 }
329 
330 // Test serialization for RidDescription with restriction list.
331 // Note: restriction list will be sorted because it is stored in a map.
TEST_F(RidDescriptionSdpSerializerTest,Serialize_AttributeList)332 TEST_F(RidDescriptionSdpSerializerTest, Serialize_AttributeList) {
333   RidDescription rid_description("5", RidDirection::kSend);
334   rid_description.restrictions["max-width"] = "1280";
335   rid_description.restrictions["max-height"] = "720";
336   TestSerialization(rid_description, "5 send max-height=720;max-width=1280");
337 }
338 
339 // Test serialization for RidDescription with format list and attribute list.
340 // Note: restriction list will be sorted because it is stored in a map.
TEST_F(RidDescriptionSdpSerializerTest,Serialize_FormatAndAttributeList)341 TEST_F(RidDescriptionSdpSerializerTest, Serialize_FormatAndAttributeList) {
342   RidDescription rid_description("6", RidDirection::kSend);
343   rid_description.payload_types = {103, 104};
344   rid_description.restrictions["max-mbps"] = "108000";
345   rid_description.restrictions["max-br"] = "64000";
346   TestSerialization(rid_description,
347                     "6 send pt=103,104;max-br=64000;max-mbps=108000");
348 }
349 
350 // Test serialization for attribute list that has key with no value.
351 // Note: restriction list will be sorted because it is stored in a map.
TEST_F(RidDescriptionSdpSerializerTest,Serialize_RestrictionWithoutValue)352 TEST_F(RidDescriptionSdpSerializerTest, Serialize_RestrictionWithoutValue) {
353   RidDescription rid_description("7", RidDirection::kReceive);
354   rid_description.payload_types = {103};
355   rid_description.restrictions["max-width"] = "1280";
356   rid_description.restrictions["max-height"] = "720";
357   rid_description.restrictions["max-myval"] = "";
358   TestSerialization(rid_description,
359                     "7 recv pt=103;max-height=720;max-myval;max-width=1280");
360 }
361 
362 // Test simulcast deserialization with simple send stream.
TEST_F(RidDescriptionSdpSerializerTest,Deserialize_SimpleSendCase)363 TEST_F(RidDescriptionSdpSerializerTest, Deserialize_SimpleSendCase) {
364   RidDescription rid_description("1", RidDirection::kSend);
365   TestDeserialization("1 send", rid_description);
366 }
367 
368 // Test simulcast deserialization with simple receive stream.
TEST_F(RidDescriptionSdpSerializerTest,Deserialize_SimpleReceiveCase)369 TEST_F(RidDescriptionSdpSerializerTest, Deserialize_SimpleReceiveCase) {
370   RidDescription rid_description("2", RidDirection::kReceive);
371   TestDeserialization("2 recv", rid_description);
372 }
373 
374 // Test simulcast deserialization with single format.
TEST_F(RidDescriptionSdpSerializerTest,Deserialize_WithFormat)375 TEST_F(RidDescriptionSdpSerializerTest, Deserialize_WithFormat) {
376   RidDescription rid_description("3", RidDirection::kSend);
377   rid_description.payload_types = {101};
378   TestDeserialization("3 send pt=101", rid_description);
379 }
380 
381 // Test simulcast deserialization with multiple formats.
TEST_F(RidDescriptionSdpSerializerTest,Deserialize_WithMultipleFormats)382 TEST_F(RidDescriptionSdpSerializerTest, Deserialize_WithMultipleFormats) {
383   RidDescription rid_description("4", RidDirection::kSend);
384   rid_description.payload_types = {103, 104, 101, 102};
385   TestDeserialization("4 send pt=103,104,101,102", rid_description);
386 }
387 
388 // Test simulcast deserialization with restriction.
TEST_F(RidDescriptionSdpSerializerTest,Deserialize_WithRestriction)389 TEST_F(RidDescriptionSdpSerializerTest, Deserialize_WithRestriction) {
390   RidDescription rid_description("5", RidDirection::kReceive);
391   rid_description.restrictions["max-height"] = "720";
392   TestDeserialization("5 recv max-height=720", rid_description);
393 }
394 
395 // Test simulcast deserialization with multiple restrictions.
TEST_F(RidDescriptionSdpSerializerTest,Deserialize_WithMultipleRestrictions)396 TEST_F(RidDescriptionSdpSerializerTest, Deserialize_WithMultipleRestrictions) {
397   RidDescription rid_description("6", RidDirection::kReceive);
398   rid_description.restrictions["max-height"] = "720";
399   rid_description.restrictions["max-width"] = "1920";
400   rid_description.restrictions["max-fr"] = "60";
401   rid_description.restrictions["max-bps"] = "14000";
402   TestDeserialization(
403       "6 recv max-height=720;max-width=1920;max-bps=14000;max-fr=60",
404       rid_description);
405 }
406 
407 // Test simulcast deserialization with custom (non-standard) restriction.
TEST_F(RidDescriptionSdpSerializerTest,Deserialize_WithCustomRestrictions)408 TEST_F(RidDescriptionSdpSerializerTest, Deserialize_WithCustomRestrictions) {
409   RidDescription rid_description("7", RidDirection::kSend);
410   rid_description.restrictions["foo"] = "bar";
411   rid_description.restrictions["max-height"] = "720";
412   TestDeserialization("7 send max-height=720;foo=bar", rid_description);
413 }
414 
415 // Test simulcast deserialization with multiple formats and restrictions.
TEST_F(RidDescriptionSdpSerializerTest,Deserialize_WithFormatAndRestrictions)416 TEST_F(RidDescriptionSdpSerializerTest, Deserialize_WithFormatAndRestrictions) {
417   RidDescription rid_description("8", RidDirection::kSend);
418   rid_description.payload_types = {104, 103};
419   rid_description.restrictions["max-height"] = "720";
420   rid_description.restrictions["max-width"] = "1920";
421   TestDeserialization("8 send pt=104,103;max-height=720;max-width=1920",
422                       rid_description);
423 }
424 
425 // Test simulcast deserialization with restriction that has no value.
TEST_F(RidDescriptionSdpSerializerTest,Deserialize_RestrictionHasNoValue)426 TEST_F(RidDescriptionSdpSerializerTest, Deserialize_RestrictionHasNoValue) {
427   RidDescription rid_description("9", RidDirection::kReceive);
428   rid_description.payload_types = {104};
429   rid_description.restrictions["max-height"];
430   rid_description.restrictions["max-width"] = "1920";
431   TestDeserialization("9 recv pt=104;max-height;max-width=1920",
432                       rid_description);
433 }
434 
435 // Add this test to explicitly indicate that this is not an error.
436 // The following string "1 send recv" looks malformed because it specifies
437 // two directions, but in fact, the recv can be interpreted as a parameter
438 // without a value. While such a use case is dubious, the input string is
439 // not malformed.
TEST_F(RidDescriptionSdpSerializerTest,Deserialize_AmbiguousCase)440 TEST_F(RidDescriptionSdpSerializerTest, Deserialize_AmbiguousCase) {
441   RidDescription rid_description("1", RidDirection::kSend);
442   rid_description.restrictions["recv"];  // No value.
443   TestDeserialization("1 send recv", rid_description);
444 }
445 
446 // Parameterized negative test case for deserialization with invalid inputs.
TEST_P(RidDescriptionSdpSerializerTest,RidDescriptionDeserializationFailed)447 TEST_P(RidDescriptionSdpSerializerTest, RidDescriptionDeserializationFailed) {
448   SdpSerializer deserializer;
449   auto result = deserializer.DeserializeRidDescription(GetParam());
450   EXPECT_FALSE(result.ok());
451 }
452 
453 // The malformed Rid Description inputs to use in the negative test case.
454 const char* kRidDescriptionMalformedStrings[] = {
455     "1",
456     "recv",
457     "send",
458     "recv 1",
459     "send 1",
460     "1 receive",
461     "one direction",
462     "1 send pt=1 max-width=720",  // The ' ' should be ';' in restriction list.
463     "1 recv ;",
464     "1 recv =",
465     "1 recv a=b=c",
466     "1 send max-width=720;pt=101",  // pt= should appear first.
467     "1 send pt=101;pt=102",
468     "1 send pt=101,101",
469     "1 recv max-width=720;max-width=720",
470     "1 send pt=",
471     "1 send pt=abc",
472     "1 recv ;;",
473     "~1 recv",
474     "1$2 send",
475     "1=2 send",
476     "1* send",
477 };
478 
479 INSTANTIATE_TEST_SUITE_P(RidDescriptionDeserializationErrors,
480                          RidDescriptionSdpSerializerTest,
481                          ValuesIn(kRidDescriptionMalformedStrings));
482 
483 }  // namespace webrtc
484