From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../libwebrtc/pc/sdp_serializer_unittest.cc | 485 +++++++++++++++++++++ 1 file changed, 485 insertions(+) create mode 100644 third_party/libwebrtc/pc/sdp_serializer_unittest.cc (limited to 'third_party/libwebrtc/pc/sdp_serializer_unittest.cc') diff --git a/third_party/libwebrtc/pc/sdp_serializer_unittest.cc b/third_party/libwebrtc/pc/sdp_serializer_unittest.cc new file mode 100644 index 0000000000..0c31750df4 --- /dev/null +++ b/third_party/libwebrtc/pc/sdp_serializer_unittest.cc @@ -0,0 +1,485 @@ +/* + * 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 + +#include +#include +#include +#include + +#include "test/gtest.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 +void ExpectEqual(const std::vector& expected, + const std::vector& 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& expected, + const std::vector& 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 +void ExpectEqual(const std::map& expected, + const std::map& actual) { + typedef typename std::map::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& 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 { + 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 { + 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 -- cgit v1.2.3