Source code

Revision control

Copy as Markdown

Other Tools

/*
* Copyright 2019 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/used_ids.h"
#include "absl/strings/string_view.h"
#include "test/gtest.h"
using cricket::UsedIds;
using cricket::UsedRtpHeaderExtensionIds;
struct Foo {
int id;
};
TEST(UsedIdsTest, UniqueIdsAreUnchanged) {
UsedIds<Foo> used_ids(1, 5);
for (int i = 1; i <= 5; ++i) {
Foo id = {i};
used_ids.FindAndSetIdUsed(&id);
EXPECT_EQ(id.id, i);
}
}
TEST(UsedIdsTest, IdsOutsideRangeAreUnchanged) {
UsedIds<Foo> used_ids(1, 5);
Foo id_11 = {11};
Foo id_12 = {12};
Foo id_12_collision = {12};
Foo id_13 = {13};
Foo id_13_collision = {13};
used_ids.FindAndSetIdUsed(&id_11);
EXPECT_EQ(id_11.id, 11);
used_ids.FindAndSetIdUsed(&id_12);
EXPECT_EQ(id_12.id, 12);
used_ids.FindAndSetIdUsed(&id_12_collision);
EXPECT_EQ(id_12_collision.id, 12);
used_ids.FindAndSetIdUsed(&id_13);
EXPECT_EQ(id_13.id, 13);
used_ids.FindAndSetIdUsed(&id_13_collision);
EXPECT_EQ(id_13_collision.id, 13);
}
TEST(UsedIdsTest, CollisionsAreReassignedIdsInReverseOrder) {
UsedIds<Foo> used_ids(1, 10);
Foo id_1 = {1};
Foo id_2 = {2};
Foo id_2_collision = {2};
Foo id_3 = {3};
Foo id_3_collision = {3};
used_ids.FindAndSetIdUsed(&id_1);
used_ids.FindAndSetIdUsed(&id_2);
used_ids.FindAndSetIdUsed(&id_2_collision);
EXPECT_EQ(id_2_collision.id, 10);
used_ids.FindAndSetIdUsed(&id_3);
used_ids.FindAndSetIdUsed(&id_3_collision);
EXPECT_EQ(id_3_collision.id, 9);
}
struct TestParams {
UsedRtpHeaderExtensionIds::IdDomain id_domain;
int max_id;
};
class UsedRtpHeaderExtensionIdsTest
: public ::testing::TestWithParam<TestParams> {};
constexpr TestParams kOneByteTestParams = {
UsedRtpHeaderExtensionIds::IdDomain::kOneByteOnly, 14};
constexpr TestParams kTwoByteTestParams = {
UsedRtpHeaderExtensionIds::IdDomain::kTwoByteAllowed, 255};
INSTANTIATE_TEST_SUITE_P(All,
UsedRtpHeaderExtensionIdsTest,
::testing::Values(kOneByteTestParams,
kTwoByteTestParams));
TEST_P(UsedRtpHeaderExtensionIdsTest, UniqueIdsAreUnchanged) {
UsedRtpHeaderExtensionIds used_ids(GetParam().id_domain);
// Fill all IDs.
for (int j = 1; j <= GetParam().max_id; ++j) {
webrtc::RtpExtension extension("", j);
used_ids.FindAndSetIdUsed(&extension);
EXPECT_EQ(extension.id, j);
}
}
TEST_P(UsedRtpHeaderExtensionIdsTest, PrioritizeReassignmentToOneByteIds) {
UsedRtpHeaderExtensionIds used_ids(GetParam().id_domain);
webrtc::RtpExtension id_1("", 1);
webrtc::RtpExtension id_2("", 2);
webrtc::RtpExtension id_2_collision("", 2);
webrtc::RtpExtension id_3("", 3);
webrtc::RtpExtension id_3_collision("", 3);
// Expect that colliding IDs are reassigned to one-byte IDs.
used_ids.FindAndSetIdUsed(&id_1);
used_ids.FindAndSetIdUsed(&id_2);
used_ids.FindAndSetIdUsed(&id_2_collision);
EXPECT_EQ(id_2_collision.id, 14);
used_ids.FindAndSetIdUsed(&id_3);
used_ids.FindAndSetIdUsed(&id_3_collision);
EXPECT_EQ(id_3_collision.id, 13);
}
TEST_F(UsedRtpHeaderExtensionIdsTest, TwoByteIdsAllowed) {
UsedRtpHeaderExtensionIds used_ids(
UsedRtpHeaderExtensionIds::IdDomain::kTwoByteAllowed);
// Fill all one byte IDs.
for (int i = 1; i <= webrtc::RtpExtension::kOneByteHeaderExtensionMaxId;
++i) {
webrtc::RtpExtension id("", i);
used_ids.FindAndSetIdUsed(&id);
}
// Add new extensions with colliding IDs.
webrtc::RtpExtension id1_collision("", 1);
webrtc::RtpExtension id2_collision("", 2);
webrtc::RtpExtension id3_collision("", 3);
// Expect to reassign to two-byte header extension IDs.
used_ids.FindAndSetIdUsed(&id1_collision);
EXPECT_EQ(id1_collision.id, 16);
used_ids.FindAndSetIdUsed(&id2_collision);
EXPECT_EQ(id2_collision.id, 17);
used_ids.FindAndSetIdUsed(&id3_collision);
EXPECT_EQ(id3_collision.id, 18);
}
// Death tests.
// Disabled on Android because death tests misbehave on Android, see
// base/test/gtest_util.h.
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
TEST(UsedIdsDeathTest, DieWhenAllIdsAreOccupied) {
UsedIds<Foo> used_ids(1, 5);
for (int i = 1; i <= 5; ++i) {
Foo id = {i};
used_ids.FindAndSetIdUsed(&id);
}
Foo id_collision = {3};
EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id_collision), "");
}
using UsedRtpHeaderExtensionIdsDeathTest = UsedRtpHeaderExtensionIdsTest;
INSTANTIATE_TEST_SUITE_P(All,
UsedRtpHeaderExtensionIdsDeathTest,
::testing::Values(kOneByteTestParams,
kTwoByteTestParams));
TEST_P(UsedRtpHeaderExtensionIdsDeathTest, DieWhenAllIdsAreOccupied) {
UsedRtpHeaderExtensionIds used_ids(GetParam().id_domain);
// Fill all IDs.
for (int j = 1; j <= GetParam().max_id; ++j) {
webrtc::RtpExtension id("", j);
used_ids.FindAndSetIdUsed(&id);
}
webrtc::RtpExtension id1_collision("", 1);
webrtc::RtpExtension id2_collision("", 2);
webrtc::RtpExtension id3_collision("", GetParam().max_id);
EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id1_collision), "");
EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id2_collision), "");
EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id3_collision), "");
}
#endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)