484 lines
20 KiB
C++
484 lines
20 KiB
C++
|
/*
|
||
|
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
|
||
|
*
|
||
|
* Use of this source code is governed by a BSD-style license
|
||
|
* that can be found in the LICENSE file in the root of the source
|
||
|
* tree. An additional intellectual property rights grant can be found
|
||
|
* in the file PATENTS. All contributing project authors may
|
||
|
* be found in the AUTHORS file in the root of the source tree.
|
||
|
*/
|
||
|
|
||
|
#include "pc/sdp_serializer.h"
|
||
|
|
||
|
#include <map>
|
||
|
#include <string>
|
||
|
#include <utility>
|
||
|
#include <vector>
|
||
|
|
||
|
#include "rtc_base/gunit.h"
|
||
|
|
||
|
using cricket::RidDescription;
|
||
|
using cricket::RidDirection;
|
||
|
using cricket::SimulcastDescription;
|
||
|
using cricket::SimulcastLayer;
|
||
|
using cricket::SimulcastLayerList;
|
||
|
using ::testing::TestWithParam;
|
||
|
using ::testing::ValuesIn;
|
||
|
|
||
|
namespace webrtc {
|
||
|
|
||
|
namespace {
|
||
|
// Checks that two vectors have the same objects in the same order.
|
||
|
template <typename TElement>
|
||
|
void ExpectEqual(const std::vector<TElement>& expected,
|
||
|
const std::vector<TElement>& actual) {
|
||
|
ASSERT_EQ(expected.size(), actual.size());
|
||
|
for (size_t i = 0; i < expected.size(); i++) {
|
||
|
EXPECT_EQ(expected[i], actual[i]) << "Vectors differ at element " << i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Template specialization for vectors of SimulcastLayer objects.
|
||
|
template <>
|
||
|
void ExpectEqual(const std::vector<SimulcastLayer>& expected,
|
||
|
const std::vector<SimulcastLayer>& actual) {
|
||
|
EXPECT_EQ(expected.size(), actual.size());
|
||
|
for (size_t i = 0; i < expected.size(); i++) {
|
||
|
EXPECT_EQ(expected[i].rid, actual[i].rid);
|
||
|
EXPECT_EQ(expected[i].is_paused, actual[i].is_paused);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Checks that two maps have the same key-value pairs.
|
||
|
// Even though a map is technically ordered, the order semantics are not
|
||
|
// tested because having the same key-set in both maps implies that they
|
||
|
// are ordered the same because the template enforces that they have the
|
||
|
// same Key-Comparer type.
|
||
|
template <typename TKey, typename TValue>
|
||
|
void ExpectEqual(const std::map<TKey, TValue>& expected,
|
||
|
const std::map<TKey, TValue>& actual) {
|
||
|
typedef typename std::map<TKey, TValue>::const_iterator const_iterator;
|
||
|
ASSERT_EQ(expected.size(), actual.size());
|
||
|
// Maps have unique keys, so if size is equal, it is enough to check
|
||
|
// that all the keys (and values) from one map exist in the other.
|
||
|
for (const std::pair<TKey, TValue>& pair : expected) {
|
||
|
const_iterator iter = actual.find(pair.first);
|
||
|
EXPECT_NE(iter, actual.end()) << "Key: " << pair.first << " not found";
|
||
|
EXPECT_EQ(pair.second, iter->second);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Checks that the two SimulcastLayerLists are equal.
|
||
|
void ExpectEqual(const SimulcastLayerList& expected,
|
||
|
const SimulcastLayerList& actual) {
|
||
|
EXPECT_EQ(expected.size(), actual.size());
|
||
|
for (size_t i = 0; i < expected.size(); i++) {
|
||
|
ExpectEqual(expected[i], actual[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Checks that the two SimulcastDescriptions are equal.
|
||
|
void ExpectEqual(const SimulcastDescription& expected,
|
||
|
const SimulcastDescription& actual) {
|
||
|
ExpectEqual(expected.send_layers(), actual.send_layers());
|
||
|
ExpectEqual(expected.receive_layers(), actual.receive_layers());
|
||
|
}
|
||
|
|
||
|
// Checks that the two RidDescriptions are equal.
|
||
|
void ExpectEqual(const RidDescription& expected, const RidDescription& actual) {
|
||
|
EXPECT_EQ(expected.rid, actual.rid);
|
||
|
EXPECT_EQ(expected.direction, actual.direction);
|
||
|
ExpectEqual(expected.payload_types, actual.payload_types);
|
||
|
ExpectEqual(expected.restrictions, actual.restrictions);
|
||
|
}
|
||
|
} // namespace
|
||
|
|
||
|
class SimulcastSdpSerializerTest : public TestWithParam<const char*> {
|
||
|
public:
|
||
|
// Runs a test for deserializing Simulcast.
|
||
|
// |str| - The serialized Simulcast to parse.
|
||
|
// |expected| - The expected output Simulcast to compare to.
|
||
|
void TestDeserialization(const std::string& str,
|
||
|
const SimulcastDescription& expected) const {
|
||
|
SdpSerializer deserializer;
|
||
|
auto result = deserializer.DeserializeSimulcastDescription(str);
|
||
|
EXPECT_TRUE(result.ok());
|
||
|
ExpectEqual(expected, result.value());
|
||
|
}
|
||
|
|
||
|
// Runs a test for serializing Simulcast.
|
||
|
// |simulcast| - The Simulcast to serialize.
|
||
|
// |expected| - The expected output string to compare to.
|
||
|
void TestSerialization(const SimulcastDescription& simulcast,
|
||
|
const std::string& expected) const {
|
||
|
SdpSerializer serializer;
|
||
|
auto result = serializer.SerializeSimulcastDescription(simulcast);
|
||
|
EXPECT_EQ(expected, result);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Test Cases
|
||
|
|
||
|
// Test simple deserialization with no alternative streams.
|
||
|
TEST_F(SimulcastSdpSerializerTest, Deserialize_SimpleCaseNoAlternatives) {
|
||
|
std::string simulcast_str = "send 1;2 recv 3;4";
|
||
|
SimulcastDescription expected;
|
||
|
expected.send_layers().AddLayer(SimulcastLayer("1", false));
|
||
|
expected.send_layers().AddLayer(SimulcastLayer("2", false));
|
||
|
expected.receive_layers().AddLayer(SimulcastLayer("3", false));
|
||
|
expected.receive_layers().AddLayer(SimulcastLayer("4", false));
|
||
|
TestDeserialization(simulcast_str, expected);
|
||
|
}
|
||
|
|
||
|
// Test simulcast deserialization with alternative streams.
|
||
|
TEST_F(SimulcastSdpSerializerTest, Deserialize_SimpleCaseWithAlternatives) {
|
||
|
std::string simulcast_str = "send 1,5;2,6 recv 3,7;4,8";
|
||
|
SimulcastDescription expected;
|
||
|
expected.send_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("1", false), SimulcastLayer("5", false)});
|
||
|
expected.send_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("2", false), SimulcastLayer("6", false)});
|
||
|
expected.receive_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("3", false), SimulcastLayer("7", false)});
|
||
|
expected.receive_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("4", false), SimulcastLayer("8", false)});
|
||
|
TestDeserialization(simulcast_str, expected);
|
||
|
}
|
||
|
|
||
|
// Test simulcast deserialization when only some streams have alternatives.
|
||
|
TEST_F(SimulcastSdpSerializerTest, Deserialize_WithSomeAlternatives) {
|
||
|
std::string simulcast_str = "send 1;2,6 recv 3,7;4";
|
||
|
SimulcastDescription expected;
|
||
|
expected.send_layers().AddLayer(SimulcastLayer("1", false));
|
||
|
expected.send_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("2", false), SimulcastLayer("6", false)});
|
||
|
expected.receive_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("3", false), SimulcastLayer("7", false)});
|
||
|
expected.receive_layers().AddLayer(SimulcastLayer("4", false));
|
||
|
TestDeserialization(simulcast_str, expected);
|
||
|
}
|
||
|
|
||
|
// Test simulcast deserialization when only send streams are specified.
|
||
|
TEST_F(SimulcastSdpSerializerTest, Deserialize_OnlySendStreams) {
|
||
|
std::string simulcast_str = "send 1;2,6;3,7;4";
|
||
|
SimulcastDescription expected;
|
||
|
expected.send_layers().AddLayer(SimulcastLayer("1", false));
|
||
|
expected.send_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("2", false), SimulcastLayer("6", false)});
|
||
|
expected.send_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("3", false), SimulcastLayer("7", false)});
|
||
|
expected.send_layers().AddLayer(SimulcastLayer("4", false));
|
||
|
TestDeserialization(simulcast_str, expected);
|
||
|
}
|
||
|
|
||
|
// Test simulcast deserialization when only receive streams are specified.
|
||
|
TEST_F(SimulcastSdpSerializerTest, Deserialize_OnlyReceiveStreams) {
|
||
|
std::string simulcast_str = "recv 1;2,6;3,7;4";
|
||
|
SimulcastDescription expected;
|
||
|
expected.receive_layers().AddLayer(SimulcastLayer("1", false));
|
||
|
expected.receive_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("2", false), SimulcastLayer("6", false)});
|
||
|
expected.receive_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("3", false), SimulcastLayer("7", false)});
|
||
|
expected.receive_layers().AddLayer(SimulcastLayer("4", false));
|
||
|
TestDeserialization(simulcast_str, expected);
|
||
|
}
|
||
|
|
||
|
// Test simulcast deserialization with receive streams before send streams.
|
||
|
TEST_F(SimulcastSdpSerializerTest, Deserialize_SendReceiveReversed) {
|
||
|
std::string simulcast_str = "recv 1;2,6 send 3,7;4";
|
||
|
SimulcastDescription expected;
|
||
|
expected.receive_layers().AddLayer(SimulcastLayer("1", false));
|
||
|
expected.receive_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("2", false), SimulcastLayer("6", false)});
|
||
|
expected.send_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("3", false), SimulcastLayer("7", false)});
|
||
|
expected.send_layers().AddLayer(SimulcastLayer("4", false));
|
||
|
TestDeserialization(simulcast_str, expected);
|
||
|
}
|
||
|
|
||
|
// Test simulcast deserialization with some streams set to paused state.
|
||
|
TEST_F(SimulcastSdpSerializerTest, Deserialize_PausedStreams) {
|
||
|
std::string simulcast_str = "recv 1;~2,6 send 3,7;~4";
|
||
|
SimulcastDescription expected;
|
||
|
expected.receive_layers().AddLayer(SimulcastLayer("1", false));
|
||
|
expected.receive_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("2", true), SimulcastLayer("6", false)});
|
||
|
expected.send_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("3", false), SimulcastLayer("7", false)});
|
||
|
expected.send_layers().AddLayer(SimulcastLayer("4", true));
|
||
|
TestDeserialization(simulcast_str, expected);
|
||
|
}
|
||
|
|
||
|
// Parameterized negative test case for deserialization with invalid inputs.
|
||
|
TEST_P(SimulcastSdpSerializerTest, SimulcastDeserializationFailed) {
|
||
|
SdpSerializer deserializer;
|
||
|
auto result = deserializer.DeserializeSimulcastDescription(GetParam());
|
||
|
EXPECT_FALSE(result.ok());
|
||
|
}
|
||
|
|
||
|
// The malformed Simulcast inputs to use in the negative test case.
|
||
|
const char* kSimulcastMalformedStrings[] = {
|
||
|
"send ",
|
||
|
"recv ",
|
||
|
"recv 1 send",
|
||
|
"receive 1",
|
||
|
"recv 1;~2,6 recv 3,7;~4",
|
||
|
"send 1;~2,6 send 3,7;~4",
|
||
|
"send ~;~2,6",
|
||
|
"send 1; ;~2,6",
|
||
|
"send 1,;~2,6",
|
||
|
"recv 1 send 2 3",
|
||
|
"",
|
||
|
};
|
||
|
|
||
|
INSTANTIATE_TEST_SUITE_P(SimulcastDeserializationErrors,
|
||
|
SimulcastSdpSerializerTest,
|
||
|
ValuesIn(kSimulcastMalformedStrings));
|
||
|
|
||
|
// Test a simple serialization scenario.
|
||
|
TEST_F(SimulcastSdpSerializerTest, Serialize_SimpleCase) {
|
||
|
SimulcastDescription simulcast;
|
||
|
simulcast.send_layers().AddLayer(SimulcastLayer("1", false));
|
||
|
simulcast.receive_layers().AddLayer(SimulcastLayer("2", false));
|
||
|
TestSerialization(simulcast, "send 1 recv 2");
|
||
|
}
|
||
|
|
||
|
// Test serialization with only send streams.
|
||
|
TEST_F(SimulcastSdpSerializerTest, Serialize_OnlySend) {
|
||
|
SimulcastDescription simulcast;
|
||
|
simulcast.send_layers().AddLayer(SimulcastLayer("1", false));
|
||
|
simulcast.send_layers().AddLayer(SimulcastLayer("2", false));
|
||
|
TestSerialization(simulcast, "send 1;2");
|
||
|
}
|
||
|
|
||
|
// Test serialization with only receive streams
|
||
|
TEST_F(SimulcastSdpSerializerTest, Serialize_OnlyReceive) {
|
||
|
SimulcastDescription simulcast;
|
||
|
simulcast.receive_layers().AddLayer(SimulcastLayer("1", false));
|
||
|
simulcast.receive_layers().AddLayer(SimulcastLayer("2", false));
|
||
|
TestSerialization(simulcast, "recv 1;2");
|
||
|
}
|
||
|
|
||
|
// Test a complex serialization with multiple streams, alternatives and states.
|
||
|
TEST_F(SimulcastSdpSerializerTest, Serialize_ComplexSerialization) {
|
||
|
SimulcastDescription simulcast;
|
||
|
simulcast.send_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("2", false), SimulcastLayer("1", true)});
|
||
|
simulcast.send_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("4", false), SimulcastLayer("3", false)});
|
||
|
|
||
|
simulcast.receive_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("6", false), SimulcastLayer("7", false)});
|
||
|
simulcast.receive_layers().AddLayer(SimulcastLayer("8", true));
|
||
|
simulcast.receive_layers().AddLayerWithAlternatives(
|
||
|
{SimulcastLayer("9", false), SimulcastLayer("10", true),
|
||
|
SimulcastLayer("11", false)});
|
||
|
TestSerialization(simulcast, "send 2,~1;4,3 recv 6,7;~8;9,~10,11");
|
||
|
}
|
||
|
|
||
|
class RidDescriptionSdpSerializerTest : public TestWithParam<const char*> {
|
||
|
public:
|
||
|
// Runs a test for deserializing Rid Descriptions.
|
||
|
// |str| - The serialized Rid Description to parse.
|
||
|
// |expected| - The expected output RidDescription to compare to.
|
||
|
void TestDeserialization(const std::string& str,
|
||
|
const RidDescription& expected) const {
|
||
|
SdpSerializer deserializer;
|
||
|
auto result = deserializer.DeserializeRidDescription(str);
|
||
|
EXPECT_TRUE(result.ok());
|
||
|
ExpectEqual(expected, result.value());
|
||
|
}
|
||
|
|
||
|
// Runs a test for serializing RidDescriptions.
|
||
|
// |rid_description| - The RidDescription to serialize.
|
||
|
// |expected| - The expected output string to compare to.
|
||
|
void TestSerialization(const RidDescription& rid_description,
|
||
|
const std::string& expected) const {
|
||
|
SdpSerializer serializer;
|
||
|
auto result = serializer.SerializeRidDescription(rid_description);
|
||
|
EXPECT_EQ(expected, result);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Test serialization for RidDescription that only specifies send.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Serialize_OnlyDirectionSend) {
|
||
|
RidDescription rid_description("1", RidDirection::kSend);
|
||
|
TestSerialization(rid_description, "1 send");
|
||
|
}
|
||
|
|
||
|
// Test serialization for RidDescription that only specifies receive.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Serialize_OnlyDirectionReceive) {
|
||
|
RidDescription rid_description("2", RidDirection::kReceive);
|
||
|
TestSerialization(rid_description, "2 recv");
|
||
|
}
|
||
|
|
||
|
// Test serialization for RidDescription with format list.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Serialize_FormatList) {
|
||
|
RidDescription rid_description("3", RidDirection::kSend);
|
||
|
rid_description.payload_types = {102, 101};
|
||
|
TestSerialization(rid_description, "3 send pt=102,101");
|
||
|
}
|
||
|
|
||
|
// Test serialization for RidDescription with format list.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Serialize_FormatListSingleFormat) {
|
||
|
RidDescription rid_description("4", RidDirection::kReceive);
|
||
|
rid_description.payload_types = {100};
|
||
|
TestSerialization(rid_description, "4 recv pt=100");
|
||
|
}
|
||
|
|
||
|
// Test serialization for RidDescription with restriction list.
|
||
|
// Note: restriction list will be sorted because it is stored in a map.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Serialize_AttributeList) {
|
||
|
RidDescription rid_description("5", RidDirection::kSend);
|
||
|
rid_description.restrictions["max-width"] = "1280";
|
||
|
rid_description.restrictions["max-height"] = "720";
|
||
|
TestSerialization(rid_description, "5 send max-height=720;max-width=1280");
|
||
|
}
|
||
|
|
||
|
// Test serialization for RidDescription with format list and attribute list.
|
||
|
// Note: restriction list will be sorted because it is stored in a map.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Serialize_FormatAndAttributeList) {
|
||
|
RidDescription rid_description("6", RidDirection::kSend);
|
||
|
rid_description.payload_types = {103, 104};
|
||
|
rid_description.restrictions["max-mbps"] = "108000";
|
||
|
rid_description.restrictions["max-br"] = "64000";
|
||
|
TestSerialization(rid_description,
|
||
|
"6 send pt=103,104;max-br=64000;max-mbps=108000");
|
||
|
}
|
||
|
|
||
|
// Test serialization for attribute list that has key with no value.
|
||
|
// Note: restriction list will be sorted because it is stored in a map.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Serialize_RestrictionWithoutValue) {
|
||
|
RidDescription rid_description("7", RidDirection::kReceive);
|
||
|
rid_description.payload_types = {103};
|
||
|
rid_description.restrictions["max-width"] = "1280";
|
||
|
rid_description.restrictions["max-height"] = "720";
|
||
|
rid_description.restrictions["max-myval"] = "";
|
||
|
TestSerialization(rid_description,
|
||
|
"7 recv pt=103;max-height=720;max-myval;max-width=1280");
|
||
|
}
|
||
|
|
||
|
// Test simulcast deserialization with simple send stream.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Deserialize_SimpleSendCase) {
|
||
|
RidDescription rid_description("1", RidDirection::kSend);
|
||
|
TestDeserialization("1 send", rid_description);
|
||
|
}
|
||
|
|
||
|
// Test simulcast deserialization with simple receive stream.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Deserialize_SimpleReceiveCase) {
|
||
|
RidDescription rid_description("2", RidDirection::kReceive);
|
||
|
TestDeserialization("2 recv", rid_description);
|
||
|
}
|
||
|
|
||
|
// Test simulcast deserialization with single format.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Deserialize_WithFormat) {
|
||
|
RidDescription rid_description("3", RidDirection::kSend);
|
||
|
rid_description.payload_types = {101};
|
||
|
TestDeserialization("3 send pt=101", rid_description);
|
||
|
}
|
||
|
|
||
|
// Test simulcast deserialization with multiple formats.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Deserialize_WithMultipleFormats) {
|
||
|
RidDescription rid_description("4", RidDirection::kSend);
|
||
|
rid_description.payload_types = {103, 104, 101, 102};
|
||
|
TestDeserialization("4 send pt=103,104,101,102", rid_description);
|
||
|
}
|
||
|
|
||
|
// Test simulcast deserialization with restriction.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Deserialize_WithRestriction) {
|
||
|
RidDescription rid_description("5", RidDirection::kReceive);
|
||
|
rid_description.restrictions["max-height"] = "720";
|
||
|
TestDeserialization("5 recv max-height=720", rid_description);
|
||
|
}
|
||
|
|
||
|
// Test simulcast deserialization with multiple restrictions.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Deserialize_WithMultipleRestrictions) {
|
||
|
RidDescription rid_description("6", RidDirection::kReceive);
|
||
|
rid_description.restrictions["max-height"] = "720";
|
||
|
rid_description.restrictions["max-width"] = "1920";
|
||
|
rid_description.restrictions["max-fr"] = "60";
|
||
|
rid_description.restrictions["max-bps"] = "14000";
|
||
|
TestDeserialization(
|
||
|
"6 recv max-height=720;max-width=1920;max-bps=14000;max-fr=60",
|
||
|
rid_description);
|
||
|
}
|
||
|
|
||
|
// Test simulcast deserialization with custom (non-standard) restriction.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Deserialize_WithCustomRestrictions) {
|
||
|
RidDescription rid_description("7", RidDirection::kSend);
|
||
|
rid_description.restrictions["foo"] = "bar";
|
||
|
rid_description.restrictions["max-height"] = "720";
|
||
|
TestDeserialization("7 send max-height=720;foo=bar", rid_description);
|
||
|
}
|
||
|
|
||
|
// Test simulcast deserialization with multiple formats and restrictions.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Deserialize_WithFormatAndRestrictions) {
|
||
|
RidDescription rid_description("8", RidDirection::kSend);
|
||
|
rid_description.payload_types = {104, 103};
|
||
|
rid_description.restrictions["max-height"] = "720";
|
||
|
rid_description.restrictions["max-width"] = "1920";
|
||
|
TestDeserialization("8 send pt=104,103;max-height=720;max-width=1920",
|
||
|
rid_description);
|
||
|
}
|
||
|
|
||
|
// Test simulcast deserialization with restriction that has no value.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Deserialize_RestrictionHasNoValue) {
|
||
|
RidDescription rid_description("9", RidDirection::kReceive);
|
||
|
rid_description.payload_types = {104};
|
||
|
rid_description.restrictions["max-height"];
|
||
|
rid_description.restrictions["max-width"] = "1920";
|
||
|
TestDeserialization("9 recv pt=104;max-height;max-width=1920",
|
||
|
rid_description);
|
||
|
}
|
||
|
|
||
|
// Add this test to explicitly indicate that this is not an error.
|
||
|
// The following string "1 send recv" looks malformed because it specifies
|
||
|
// two directions, but in fact, the recv can be interpreted as a parameter
|
||
|
// without a value. While such a use case is dubious, the input string is
|
||
|
// not malformed.
|
||
|
TEST_F(RidDescriptionSdpSerializerTest, Deserialize_AmbiguousCase) {
|
||
|
RidDescription rid_description("1", RidDirection::kSend);
|
||
|
rid_description.restrictions["recv"]; // No value.
|
||
|
TestDeserialization("1 send recv", rid_description);
|
||
|
}
|
||
|
|
||
|
// Parameterized negative test case for deserialization with invalid inputs.
|
||
|
TEST_P(RidDescriptionSdpSerializerTest, RidDescriptionDeserializationFailed) {
|
||
|
SdpSerializer deserializer;
|
||
|
auto result = deserializer.DeserializeRidDescription(GetParam());
|
||
|
EXPECT_FALSE(result.ok());
|
||
|
}
|
||
|
|
||
|
// The malformed Rid Description inputs to use in the negative test case.
|
||
|
const char* kRidDescriptionMalformedStrings[] = {
|
||
|
"1",
|
||
|
"recv",
|
||
|
"send",
|
||
|
"recv 1",
|
||
|
"send 1",
|
||
|
"1 receive",
|
||
|
"one direction",
|
||
|
"1 send pt=1 max-width=720", // The ' ' should be ';' in restriction list.
|
||
|
"1 recv ;",
|
||
|
"1 recv =",
|
||
|
"1 recv a=b=c",
|
||
|
"1 send max-width=720;pt=101", // pt= should appear first.
|
||
|
"1 send pt=101;pt=102",
|
||
|
"1 send pt=101,101",
|
||
|
"1 recv max-width=720;max-width=720",
|
||
|
"1 send pt=",
|
||
|
"1 send pt=abc",
|
||
|
"1 recv ;;",
|
||
|
"~1 recv",
|
||
|
"1$2 send",
|
||
|
"1=2 send",
|
||
|
"1* send",
|
||
|
};
|
||
|
|
||
|
INSTANTIATE_TEST_SUITE_P(RidDescriptionDeserializationErrors,
|
||
|
RidDescriptionSdpSerializerTest,
|
||
|
ValuesIn(kRidDescriptionMalformedStrings));
|
||
|
|
||
|
} // namespace webrtc
|