1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
|
/*
* Copyright (c) 2022 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.
*/
// This file contains tests that verify that field trials do what they're
// supposed to do.
#include <memory>
#include <set>
#include <utility>
#include "absl/algorithm/container.h"
#include "absl/strings/string_view.h"
#include "api/enable_media_with_defaults.h"
#include "api/environment/environment_factory.h"
#include "api/field_trials.h"
#include "api/media_types.h"
#include "api/peer_connection_interface.h"
#include "api/rtp_parameters.h"
#include "api/scoped_refptr.h"
#include "pc/peer_connection_wrapper.h"
#include "pc/session_description.h"
#include "pc/test/fake_audio_capture_module.h"
#include "pc/test/mock_peer_connection_observers.h"
#include "rtc_base/checks.h"
#include "rtc_base/internal/default_socket_server.h"
#include "rtc_base/socket_server.h"
#include "rtc_base/thread.h"
#include "system_wrappers/include/clock.h"
#include "test/create_test_field_trials.h"
#include "test/gtest.h"
#ifdef WEBRTC_ANDROID
#include "pc/test/android_test_initializer.h"
#endif
namespace webrtc {
using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
class PeerConnectionFieldTrialTest : public ::testing::Test {
protected:
typedef std::unique_ptr<PeerConnectionWrapper> WrapperPtr;
PeerConnectionFieldTrialTest()
: clock_(Clock::GetRealTimeClock()),
socket_server_(CreateDefaultSocketServer()),
main_thread_(socket_server_.get()) {
#ifdef WEBRTC_ANDROID
InitializeAndroidObjects();
#endif
PeerConnectionInterface::IceServer ice_server;
ice_server.uri = "stun:stun.l.google.com:19302";
config_.servers.push_back(ice_server);
config_.sdp_semantics = SdpSemantics::kUnifiedPlan;
}
void TearDown() override { pc_factory_ = nullptr; }
void CreatePCFactory(absl::string_view field_trials) {
PeerConnectionFactoryDependencies pcf_deps;
pcf_deps.signaling_thread = Thread::Current();
pcf_deps.env = CreateEnvironment(
std::make_unique<FieldTrials>(CreateTestFieldTrials(field_trials)));
pcf_deps.adm = FakeAudioCaptureModule::Create();
EnableMediaWithDefaults(pcf_deps);
pc_factory_ = CreateModularPeerConnectionFactory(std::move(pcf_deps));
// Allow ADAPTER_TYPE_LOOPBACK to create PeerConnections with loopback in
// this test.
RTC_DCHECK(pc_factory_);
PeerConnectionFactoryInterface::Options options;
options.network_ignore_mask = 0;
pc_factory_->SetOptions(options);
}
WrapperPtr CreatePeerConnection() {
auto observer = std::make_unique<MockPeerConnectionObserver>();
auto result = pc_factory_->CreatePeerConnectionOrError(
config_, PeerConnectionDependencies(observer.get()));
RTC_CHECK(result.ok());
observer->SetPeerConnectionInterface(result.value().get());
return std::make_unique<PeerConnectionWrapper>(
pc_factory_, result.MoveValue(), std::move(observer));
}
Clock* const clock_;
std::unique_ptr<SocketServer> socket_server_;
AutoSocketServerThread main_thread_;
scoped_refptr<PeerConnectionFactoryInterface> pc_factory_ = nullptr;
PeerConnectionInterface::RTCConfiguration config_;
};
// Tests for the dependency descriptor field trial. The dependency descriptor
// field trial is implemented in media/engine/webrtc_video_engine.cc.
TEST_F(PeerConnectionFieldTrialTest, EnableDependencyDescriptorAdvertised) {
CreatePCFactory("WebRTC-DependencyDescriptorAdvertised/Enabled/");
WrapperPtr caller = CreatePeerConnection();
caller->AddTransceiver(MediaType::VIDEO);
auto offer = caller->CreateOffer();
auto contents1 = offer->description()->contents();
ASSERT_EQ(1u, contents1.size());
const MediaContentDescription* media_description1 =
contents1[0].media_description();
EXPECT_EQ(MediaType::VIDEO, media_description1->type());
const RtpHeaderExtensions& rtp_header_extensions1 =
media_description1->rtp_header_extensions();
bool found =
absl::c_find_if(
rtp_header_extensions1, [](const RtpExtension& rtp_extension) {
return rtp_extension.uri == RtpExtension::kDependencyDescriptorUri;
}) != rtp_header_extensions1.end();
EXPECT_TRUE(found);
}
// Tests that dependency descriptor RTP header extensions can be exchanged
// via SDP munging, even if dependency descriptor field trial is disabled.
#ifdef WEBRTC_WIN
// TODO: crbug.com/webrtc/15876 - Test is flaky on Windows machines.
#define MAYBE_InjectDependencyDescriptor DISABLED_InjectDependencyDescriptor
#else
#define MAYBE_InjectDependencyDescriptor InjectDependencyDescriptor
#endif
TEST_F(PeerConnectionFieldTrialTest, MAYBE_InjectDependencyDescriptor) {
CreatePCFactory("WebRTC-DependencyDescriptorAdvertised/Disabled/");
WrapperPtr caller = CreatePeerConnection();
WrapperPtr callee = CreatePeerConnection();
caller->AddTransceiver(MediaType::VIDEO);
auto offer = caller->CreateOffer();
ContentInfos& contents1 = offer->description()->contents();
ASSERT_EQ(1u, contents1.size());
MediaContentDescription* media_description1 =
contents1[0].media_description();
EXPECT_EQ(MediaType::VIDEO, media_description1->type());
RtpHeaderExtensions rtp_header_extensions1 =
media_description1->rtp_header_extensions();
bool found1 =
absl::c_find_if(
rtp_header_extensions1, [](const RtpExtension& rtp_extension) {
return rtp_extension.uri == RtpExtension::kDependencyDescriptorUri;
}) != rtp_header_extensions1.end();
EXPECT_FALSE(found1);
std::set<int> existing_ids;
for (const RtpExtension& rtp_extension : rtp_header_extensions1) {
existing_ids.insert(rtp_extension.id);
}
// Find the currently unused RTP header extension ID.
int insert_id = 1;
std::set<int>::const_iterator iter = existing_ids.begin();
while (true) {
if (iter == existing_ids.end()) {
break;
}
if (*iter != insert_id) {
break;
}
insert_id++;
iter++;
}
rtp_header_extensions1.emplace_back(RtpExtension::kDependencyDescriptorUri,
insert_id);
media_description1->set_rtp_header_extensions(rtp_header_extensions1);
caller->SetLocalDescription(offer->Clone());
ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
auto answer = callee->CreateAnswer();
ContentInfos& contents2 = answer->description()->contents();
ASSERT_EQ(1u, contents2.size());
MediaContentDescription* media_description2 =
contents2[0].media_description();
EXPECT_EQ(MediaType::VIDEO, media_description2->type());
RtpHeaderExtensions rtp_header_extensions2 =
media_description2->rtp_header_extensions();
bool found2 =
absl::c_find_if(
rtp_header_extensions2, [](const RtpExtension& rtp_extension) {
return rtp_extension.uri == RtpExtension::kDependencyDescriptorUri;
}) != rtp_header_extensions2.end();
EXPECT_TRUE(found2);
}
} // namespace webrtc
|