blob: 656b022ebdc2e187292ab564c6e5401f5514ffaf [file] [log] [blame]
Harald Alvestrand19793842018-06-25 12:03:50 +02001/*
2 * Copyright 2017 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
Yves Gerey3e707812018-11-28 16:47:49 +010011#include <memory>
12#include <set>
13#include <string>
14#include <utility>
15#include <vector>
Harald Alvestrand19793842018-06-25 12:03:50 +020016
Yves Gerey3e707812018-11-28 16:47:49 +010017#include "absl/types/optional.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000018#include "api/async_resolver_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "api/call/call_factory_interface.h"
Harald Alvestrand42386282018-07-12 07:56:05 +020020#include "api/jsep.h"
Qingsi Wang1ba5dec2019-08-19 11:57:17 -070021#include "api/jsep_session_description.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "api/peer_connection_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "api/rtc_error.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010024#include "api/scoped_refptr.h"
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020025#include "api/task_queue/default_task_queue_factory.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000026#include "api/task_queue/task_queue_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080027#include "media/base/fake_media_engine.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000028#include "media/base/media_engine.h"
Jeroen de Borstaf242c82019-04-24 13:13:48 -070029#include "p2p/base/mock_async_resolver.h"
Steve Anton10542f22019-01-11 09:11:00 -080030#include "p2p/base/port_allocator.h"
31#include "p2p/client/basic_port_allocator.h"
32#include "pc/peer_connection.h"
33#include "pc/peer_connection_factory.h"
Markus Handella1b82012021-05-26 18:56:30 +020034#include "pc/peer_connection_proxy.h"
Steve Anton10542f22019-01-11 09:11:00 -080035#include "pc/peer_connection_wrapper.h"
36#include "pc/sdp_utils.h"
37#include "pc/test/mock_peer_connection_observers.h"
Harald Alvestrand44d0dff2020-10-09 05:43:53 +000038#include "pc/usage_pattern.h"
Qingsi Wang1ba5dec2019-08-19 11:57:17 -070039#include "pc/webrtc_sdp.h"
Jeroen de Borstaf242c82019-04-24 13:13:48 -070040#include "rtc_base/arraysize.h"
Yves Gerey3e707812018-11-28 16:47:49 +010041#include "rtc_base/checks.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070042#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080043#include "rtc_base/fake_network.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020044#include "rtc_base/gunit.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000045#include "rtc_base/mdns_responder_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080046#include "rtc_base/socket_address.h"
Yves Gerey3e707812018-11-28 16:47:49 +010047#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080048#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020049#include "system_wrappers/include/metrics.h"
Jeroen de Borstaf242c82019-04-24 13:13:48 -070050#include "test/gmock.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000051#include "test/gtest.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020052
53namespace webrtc {
54
55using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
56using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
Jeroen de Borstaf242c82019-04-24 13:13:48 -070057using ::testing::NiceMock;
Harald Alvestrand19793842018-06-25 12:03:50 +020058using ::testing::Values;
59
Harald Alvestrandc0e97252018-07-26 10:39:55 +020060static const char kUsagePatternMetric[] = "WebRTC.PeerConnection.UsagePattern";
Harald Alvestrand19793842018-06-25 12:03:50 +020061static constexpr int kDefaultTimeout = 10000;
Jeroen de Borstaf242c82019-04-24 13:13:48 -070062static const rtc::SocketAddress kLocalAddrs[2] = {
63 rtc::SocketAddress("1.1.1.1", 0), rtc::SocketAddress("2.2.2.2", 0)};
Harald Alvestrand056d8112018-07-16 19:18:58 +020064static const rtc::SocketAddress kPrivateLocalAddress("10.1.1.1", 0);
Qingsi Wang1ba5dec2019-08-19 11:57:17 -070065static const rtc::SocketAddress kPrivateIpv6LocalAddress("fd12:3456:789a:1::1",
66 0);
Harald Alvestrand19793842018-06-25 12:03:50 +020067
Harald Alvestrand44d0dff2020-10-09 05:43:53 +000068int MakeUsageFingerprint(std::set<UsageEvent> events) {
Harald Alvestrand19793842018-06-25 12:03:50 +020069 int signature = 0;
70 for (const auto it : events) {
71 signature |= static_cast<int>(it);
72 }
73 return signature;
74}
75
76class PeerConnectionFactoryForUsageHistogramTest
Niels Möllerdf411872022-03-24 16:13:25 +010077 : public PeerConnectionFactory {
Harald Alvestrand19793842018-06-25 12:03:50 +020078 public:
79 PeerConnectionFactoryForUsageHistogramTest()
Niels Möllerdf411872022-03-24 16:13:25 +010080 : PeerConnectionFactory([] {
Danil Chapovalovf5258be2019-03-19 17:45:24 +010081 PeerConnectionFactoryDependencies dependencies;
82 dependencies.network_thread = rtc::Thread::Current();
83 dependencies.worker_thread = rtc::Thread::Current();
84 dependencies.signaling_thread = rtc::Thread::Current();
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020085 dependencies.task_queue_factory = CreateDefaultTaskQueueFactory();
Danil Chapovalovf5258be2019-03-19 17:45:24 +010086 dependencies.media_engine =
Mirko Bonadei317a1f02019-09-17 17:06:18 +020087 std::make_unique<cricket::FakeMediaEngine>();
Danil Chapovalovf5258be2019-03-19 17:45:24 +010088 dependencies.call_factory = CreateCallFactory();
89 return dependencies;
90 }()) {}
Harald Alvestrand183e09d2018-06-28 12:04:41 +020091};
92
93class PeerConnectionWrapperForUsageHistogramTest;
Yves Gerey3e707812018-11-28 16:47:49 +010094
Harald Alvestrand183e09d2018-06-28 12:04:41 +020095typedef PeerConnectionWrapperForUsageHistogramTest* RawWrapperPtr;
96
97class ObserverForUsageHistogramTest : public MockPeerConnectionObserver {
98 public:
99 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override;
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200100
101 void OnInterestingUsage(int usage_pattern) override {
102 interesting_usage_detected_ = usage_pattern;
103 }
104
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200105 void PrepareToExchangeCandidates(RawWrapperPtr other) {
106 candidate_target_ = other;
107 }
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200108
Niels Möller94327682022-04-28 13:20:29 +0200109 bool HaveDataChannel() { return last_datachannel_ != nullptr; }
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200110
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200111 absl::optional<int> interesting_usage_detected() {
112 return interesting_usage_detected_;
113 }
114
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200115 void ClearInterestingUsageDetector() {
116 interesting_usage_detected_ = absl::optional<int>();
117 }
118
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700119 bool candidate_gathered() const { return candidate_gathered_; }
120
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200121 private:
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200122 absl::optional<int> interesting_usage_detected_;
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700123 bool candidate_gathered_ = false;
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200124 RawWrapperPtr candidate_target_; // Note: Not thread-safe against deletions.
Harald Alvestrand19793842018-06-25 12:03:50 +0200125};
126
127class PeerConnectionWrapperForUsageHistogramTest
128 : public PeerConnectionWrapper {
129 public:
130 using PeerConnectionWrapper::PeerConnectionWrapper;
131
132 PeerConnection* GetInternalPeerConnection() {
133 auto* pci =
134 static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
135 pc());
136 return static_cast<PeerConnection*>(pci->internal());
137 }
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200138
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200139 // Override with different return type
140 ObserverForUsageHistogramTest* observer() {
141 return static_cast<ObserverForUsageHistogramTest*>(
142 PeerConnectionWrapper::observer());
143 }
144
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200145 void PrepareToExchangeCandidates(
146 PeerConnectionWrapperForUsageHistogramTest* other) {
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200147 observer()->PrepareToExchangeCandidates(other);
148 other->observer()->PrepareToExchangeCandidates(this);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200149 }
150
151 bool IsConnected() {
152 return pc()->ice_connection_state() ==
153 PeerConnectionInterface::kIceConnectionConnected ||
154 pc()->ice_connection_state() ==
155 PeerConnectionInterface::kIceConnectionCompleted;
156 }
157
158 bool HaveDataChannel() {
159 return static_cast<ObserverForUsageHistogramTest*>(observer())
160 ->HaveDataChannel();
161 }
Qingsi Wang32913c12019-10-30 16:03:46 -0700162 void BufferIceCandidate(const webrtc::IceCandidateInterface* candidate) {
163 std::string sdp;
164 EXPECT_TRUE(candidate->ToString(&sdp));
165 std::unique_ptr<webrtc::IceCandidateInterface> candidate_copy(
166 CreateIceCandidate(candidate->sdp_mid(), candidate->sdp_mline_index(),
167 sdp, nullptr));
168 buffered_candidates_.push_back(std::move(candidate_copy));
Harald Alvestrand42386282018-07-12 07:56:05 +0200169 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200170
Harald Alvestrand42386282018-07-12 07:56:05 +0200171 void AddBufferedIceCandidates() {
172 for (const auto& candidate : buffered_candidates_) {
173 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
174 }
175 buffered_candidates_.clear();
176 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200177
Qingsi Wang32913c12019-10-30 16:03:46 -0700178 // This method performs the following actions in sequence:
179 // 1. Exchange Offer and Answer.
180 // 2. Exchange ICE candidates after both caller and callee complete
181 // gathering.
182 // 3. Wait for ICE to connect.
183 //
184 // This guarantees a deterministic sequence of events and also rules out the
185 // occurrence of prflx candidates if the offer/answer signaling and the
186 // candidate trickling race in order. In case prflx candidates need to be
187 // simulated, see the approach used by tests below for that.
Harald Alvestrand42386282018-07-12 07:56:05 +0200188 bool ConnectTo(PeerConnectionWrapperForUsageHistogramTest* callee) {
189 PrepareToExchangeCandidates(callee);
Harald Alvestrand056d8112018-07-16 19:18:58 +0200190 if (!ExchangeOfferAnswerWith(callee)) {
191 return false;
192 }
Qingsi Wang32913c12019-10-30 16:03:46 -0700193 // Wait until the gathering completes before we signal the candidate.
194 WAIT(observer()->ice_gathering_complete_, kDefaultTimeout);
195 WAIT(callee->observer()->ice_gathering_complete_, kDefaultTimeout);
Harald Alvestrand42386282018-07-12 07:56:05 +0200196 AddBufferedIceCandidates();
197 callee->AddBufferedIceCandidates();
Harald Alvestrand056d8112018-07-16 19:18:58 +0200198 WAIT(IsConnected(), kDefaultTimeout);
199 WAIT(callee->IsConnected(), kDefaultTimeout);
Harald Alvestrand42386282018-07-12 07:56:05 +0200200 return IsConnected() && callee->IsConnected();
201 }
202
Harald Alvestrand056d8112018-07-16 19:18:58 +0200203 bool GenerateOfferAndCollectCandidates() {
204 auto offer = CreateOffer(RTCOfferAnswerOptions());
205 if (!offer) {
206 return false;
207 }
208 bool set_local_offer =
209 SetLocalDescription(CloneSessionDescription(offer.get()));
210 EXPECT_TRUE(set_local_offer);
211 if (!set_local_offer) {
212 return false;
213 }
214 EXPECT_TRUE_WAIT(observer()->ice_gathering_complete_, kDefaultTimeout);
215 return true;
216 }
217
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700218 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() {
219 return pc()->ice_gathering_state();
220 }
221
Harald Alvestrand42386282018-07-12 07:56:05 +0200222 private:
223 // Candidates that have been sent but not yet configured
224 std::vector<std::unique_ptr<webrtc::IceCandidateInterface>>
225 buffered_candidates_;
Harald Alvestrand19793842018-06-25 12:03:50 +0200226};
227
Qingsi Wang32913c12019-10-30 16:03:46 -0700228// Buffers candidates until we add them via AddBufferedIceCandidates.
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200229void ObserverForUsageHistogramTest::OnIceCandidate(
230 const webrtc::IceCandidateInterface* candidate) {
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700231 // If target is not set, ignore. This happens in one-ended unit tests.
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200232 if (candidate_target_) {
Qingsi Wang32913c12019-10-30 16:03:46 -0700233 this->candidate_target_->BufferIceCandidate(candidate);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200234 }
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700235 candidate_gathered_ = true;
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200236}
237
Harald Alvestrand19793842018-06-25 12:03:50 +0200238class PeerConnectionUsageHistogramTest : public ::testing::Test {
239 protected:
240 typedef std::unique_ptr<PeerConnectionWrapperForUsageHistogramTest>
241 WrapperPtr;
242
243 PeerConnectionUsageHistogramTest()
244 : vss_(new rtc::VirtualSocketServer()), main_(vss_.get()) {
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700245 webrtc::metrics::Reset();
Harald Alvestrand19793842018-06-25 12:03:50 +0200246 }
247
248 WrapperPtr CreatePeerConnection() {
Henrik Boström62995db2022-01-03 09:58:10 +0100249 RTCConfiguration config;
250 config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
Harald Alvestrand62166932020-10-26 08:30:41 +0000251 return CreatePeerConnection(
Henrik Boström62995db2022-01-03 09:58:10 +0100252 config, PeerConnectionFactoryInterface::Options(), nullptr);
Harald Alvestrand19793842018-06-25 12:03:50 +0200253 }
254
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200255 WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
256 return CreatePeerConnection(
Harald Alvestrand62166932020-10-26 08:30:41 +0000257 config, PeerConnectionFactoryInterface::Options(), nullptr);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200258 }
259
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700260 WrapperPtr CreatePeerConnectionWithMdns(const RTCConfiguration& config) {
261 auto resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200262 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700263
264 webrtc::PeerConnectionDependencies deps(nullptr /* observer_in */);
265
266 auto fake_network = NewFakeNetwork();
Qingsi Wangecd30542019-05-22 14:34:56 -0700267 fake_network->set_mdns_responder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200268 std::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700269 fake_network->AddInterface(NextLocalAddress());
270
271 std::unique_ptr<cricket::BasicPortAllocator> port_allocator(
Byoungchan Leed197e0b2022-05-30 23:59:55 +0900272 new cricket::BasicPortAllocator(
273 fake_network,
274 std::make_unique<rtc::BasicPacketSocketFactory>(vss_.get())));
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700275
276 deps.async_resolver_factory = std::move(resolver_factory);
277 deps.allocator = std::move(port_allocator);
278
Harald Alvestrand62166932020-10-26 08:30:41 +0000279 return CreatePeerConnection(
280 config, PeerConnectionFactoryInterface::Options(), std::move(deps));
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700281 }
282
Harald Alvestrand19793842018-06-25 12:03:50 +0200283 WrapperPtr CreatePeerConnectionWithImmediateReport() {
Harald Alvestrand62166932020-10-26 08:30:41 +0000284 RTCConfiguration configuration;
Henrik Boström62995db2022-01-03 09:58:10 +0100285 configuration.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
Harald Alvestrand62166932020-10-26 08:30:41 +0000286 configuration.report_usage_pattern_delay_ms = 0;
287 return CreatePeerConnection(
288 configuration, PeerConnectionFactoryInterface::Options(), nullptr);
Harald Alvestrand056d8112018-07-16 19:18:58 +0200289 }
290
291 WrapperPtr CreatePeerConnectionWithPrivateLocalAddresses() {
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700292 auto* fake_network = NewFakeNetwork();
293 fake_network->AddInterface(NextLocalAddress());
294 fake_network->AddInterface(kPrivateLocalAddress);
295
Byoungchan Leed197e0b2022-05-30 23:59:55 +0900296 auto port_allocator = std::make_unique<cricket::BasicPortAllocator>(
297 fake_network,
298 std::make_unique<rtc::BasicPacketSocketFactory>(vss_.get()));
Henrik Boström62995db2022-01-03 09:58:10 +0100299 RTCConfiguration config;
300 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
301 return CreatePeerConnection(config,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200302 PeerConnectionFactoryInterface::Options(),
Harald Alvestrand62166932020-10-26 08:30:41 +0000303 std::move(port_allocator));
Harald Alvestrand19793842018-06-25 12:03:50 +0200304 }
305
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700306 WrapperPtr CreatePeerConnectionWithPrivateIpv6LocalAddresses() {
307 auto* fake_network = NewFakeNetwork();
308 fake_network->AddInterface(NextLocalAddress());
309 fake_network->AddInterface(kPrivateIpv6LocalAddress);
310
Byoungchan Leed197e0b2022-05-30 23:59:55 +0900311 auto port_allocator = std::make_unique<cricket::BasicPortAllocator>(
312 fake_network,
313 std::make_unique<rtc::BasicPacketSocketFactory>(vss_.get()));
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700314
Henrik Boström62995db2022-01-03 09:58:10 +0100315 RTCConfiguration config;
316 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
317 return CreatePeerConnection(config,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700318 PeerConnectionFactoryInterface::Options(),
Harald Alvestrand62166932020-10-26 08:30:41 +0000319 std::move(port_allocator));
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700320 }
321
Harald Alvestrand19793842018-06-25 12:03:50 +0200322 WrapperPtr CreatePeerConnection(
323 const RTCConfiguration& config,
324 const PeerConnectionFactoryInterface::Options factory_options,
Harald Alvestrand62166932020-10-26 08:30:41 +0000325 std::unique_ptr<cricket::PortAllocator> allocator) {
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700326 PeerConnectionDependencies deps(nullptr);
327 deps.allocator = std::move(allocator);
328
Harald Alvestrand62166932020-10-26 08:30:41 +0000329 return CreatePeerConnection(config, factory_options, std::move(deps));
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700330 }
331
332 WrapperPtr CreatePeerConnection(
333 const RTCConfiguration& config,
334 const PeerConnectionFactoryInterface::Options factory_options,
Harald Alvestrand62166932020-10-26 08:30:41 +0000335 PeerConnectionDependencies deps) {
Niels Möllerdf411872022-03-24 16:13:25 +0100336 auto pc_factory =
337 rtc::make_ref_counted<PeerConnectionFactoryForUsageHistogramTest>();
Harald Alvestrand19793842018-06-25 12:03:50 +0200338 pc_factory->SetOptions(factory_options);
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700339
340 // If no allocator is provided, one will be created using a network manager
341 // that uses the host network. This doesn't work on all trybots.
342 if (!deps.allocator) {
343 auto fake_network = NewFakeNetwork();
344 fake_network->AddInterface(NextLocalAddress());
Byoungchan Leed197e0b2022-05-30 23:59:55 +0900345 deps.allocator = std::make_unique<cricket::BasicPortAllocator>(
346 fake_network,
347 std::make_unique<rtc::BasicPacketSocketFactory>(vss_.get()));
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700348 }
349
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200350 auto observer = std::make_unique<ObserverForUsageHistogramTest>();
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700351 deps.observer = observer.get();
352
Florent Castelli72424402022-04-06 03:45:10 +0200353 auto result =
354 pc_factory->CreatePeerConnectionOrError(config, std::move(deps));
355 if (!result.ok()) {
Harald Alvestrand19793842018-06-25 12:03:50 +0200356 return nullptr;
357 }
358
Niels Möllerafb246b2022-04-20 14:26:50 +0200359 observer->SetPeerConnectionInterface(result.value().get());
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200360 auto wrapper = std::make_unique<PeerConnectionWrapperForUsageHistogramTest>(
Florent Castelli72424402022-04-06 03:45:10 +0200361 pc_factory, result.MoveValue(), std::move(observer));
Harald Alvestrand19793842018-06-25 12:03:50 +0200362 return wrapper;
363 }
364
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200365 int ObservedFingerprint() {
366 // This works correctly only if there is only one sample value
367 // that has been counted.
368 // Returns -1 for "not found".
369 return webrtc::metrics::MinSample(kUsagePatternMetric);
370 }
371
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700372 // The PeerConnection's port allocator is tied to the PeerConnection's
373 // lifetime and expects the underlying NetworkManager to outlive it. That
374 // prevents us from having the PeerConnectionWrapper own the fake network.
375 // Therefore, the test fixture will own all the fake networks even though
376 // tests should access the fake network through the PeerConnectionWrapper.
377 rtc::FakeNetworkManager* NewFakeNetwork() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200378 fake_networks_.emplace_back(std::make_unique<rtc::FakeNetworkManager>());
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700379 return fake_networks_.back().get();
380 }
381
382 rtc::SocketAddress NextLocalAddress() {
383 RTC_DCHECK(next_local_address_ < (int)arraysize(kLocalAddrs));
384 return kLocalAddrs[next_local_address_++];
385 }
386
387 std::vector<std::unique_ptr<rtc::FakeNetworkManager>> fake_networks_;
388 int next_local_address_ = 0;
Harald Alvestrand19793842018-06-25 12:03:50 +0200389 std::unique_ptr<rtc::VirtualSocketServer> vss_;
390 rtc::AutoSocketServerThread main_;
391};
392
393TEST_F(PeerConnectionUsageHistogramTest, UsageFingerprintHistogramFromTimeout) {
394 auto pc = CreatePeerConnectionWithImmediateReport();
395
Harald Alvestrand19793842018-06-25 12:03:50 +0200396 int expected_fingerprint = MakeUsageFingerprint({});
Ying Wangef3998f2019-12-09 13:06:53 +0100397 EXPECT_METRIC_EQ_WAIT(1, webrtc::metrics::NumSamples(kUsagePatternMetric),
398 kDefaultTimeout);
399 EXPECT_METRIC_EQ(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200400 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrand19793842018-06-25 12:03:50 +0200401}
402
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200403#ifndef WEBRTC_ANDROID
404// These tests do not work on Android. Why is unclear.
405// https://bugs.webrtc.org/9461
406
407// Test getting the usage fingerprint for an audio/video connection.
408TEST_F(PeerConnectionUsageHistogramTest, FingerprintAudioVideo) {
409 auto caller = CreatePeerConnection();
410 auto callee = CreatePeerConnection();
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200411 caller->AddAudioTrack("audio");
412 caller->AddVideoTrack("video");
Harald Alvestrand42386282018-07-12 07:56:05 +0200413 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200414 caller->pc()->Close();
415 callee->pc()->Close();
416 int expected_fingerprint = MakeUsageFingerprint(
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000417 {UsageEvent::AUDIO_ADDED, UsageEvent::VIDEO_ADDED,
418 UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
419 UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
420 UsageEvent::CANDIDATE_COLLECTED, UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
421 UsageEvent::ICE_STATE_CONNECTED, UsageEvent::REMOTE_CANDIDATE_ADDED,
422 UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED});
Harald Alvestrand056d8112018-07-16 19:18:58 +0200423 // In this case, we may or may not have PRIVATE_CANDIDATE_COLLECTED,
424 // depending on the machine configuration.
Ying Wangef3998f2019-12-09 13:06:53 +0100425 EXPECT_METRIC_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
426 EXPECT_METRIC_TRUE(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200427 webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint) ==
428 2 ||
Harald Alvestrand056d8112018-07-16 19:18:58 +0200429 webrtc::metrics::NumEvents(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200430 kUsagePatternMetric,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200431 expected_fingerprint |
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000432 static_cast<int>(UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) == 2);
Harald Alvestrand056d8112018-07-16 19:18:58 +0200433}
434
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700435// Test getting the usage fingerprint when the caller collects an mDNS
436// candidate.
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700437TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithMdnsCaller) {
438 RTCConfiguration config;
Henrik Boström62995db2022-01-03 09:58:10 +0100439 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700440
441 // Enable hostname candidates with mDNS names.
442 auto caller = CreatePeerConnectionWithMdns(config);
443 auto callee = CreatePeerConnection(config);
444
445 caller->AddAudioTrack("audio");
446 caller->AddVideoTrack("video");
447 ASSERT_TRUE(caller->ConnectTo(callee.get()));
448 caller->pc()->Close();
449 callee->pc()->Close();
450
451 int expected_fingerprint_caller = MakeUsageFingerprint(
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000452 {UsageEvent::AUDIO_ADDED, UsageEvent::VIDEO_ADDED,
453 UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
454 UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
455 UsageEvent::CANDIDATE_COLLECTED, UsageEvent::MDNS_CANDIDATE_COLLECTED,
456 UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, UsageEvent::ICE_STATE_CONNECTED,
457 UsageEvent::REMOTE_CANDIDATE_ADDED,
458 UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED});
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700459
Qingsi Wangcc46b102019-09-12 11:19:01 -0700460 // Without a resolver, the callee cannot resolve the received mDNS candidate
461 // but can still connect with the caller via a prflx candidate. As a result,
462 // the bit for the direct connection should not be logged.
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700463 int expected_fingerprint_callee = MakeUsageFingerprint(
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000464 {UsageEvent::AUDIO_ADDED, UsageEvent::VIDEO_ADDED,
465 UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
466 UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
467 UsageEvent::CANDIDATE_COLLECTED, UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
468 UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED, UsageEvent::ICE_STATE_CONNECTED,
469 UsageEvent::REMOTE_CANDIDATE_ADDED, UsageEvent::CLOSE_CALLED});
Ying Wangef3998f2019-12-09 13:06:53 +0100470 EXPECT_METRIC_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
471 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
472 expected_fingerprint_caller));
473 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
474 expected_fingerprint_callee));
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700475}
476
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700477// Test getting the usage fingerprint when the callee collects an mDNS
478// candidate.
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700479TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithMdnsCallee) {
480 RTCConfiguration config;
Henrik Boström62995db2022-01-03 09:58:10 +0100481 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700482
483 // Enable hostname candidates with mDNS names.
484 auto caller = CreatePeerConnection(config);
485 auto callee = CreatePeerConnectionWithMdns(config);
486
487 caller->AddAudioTrack("audio");
488 caller->AddVideoTrack("video");
489 ASSERT_TRUE(caller->ConnectTo(callee.get()));
490 caller->pc()->Close();
491 callee->pc()->Close();
492
Qingsi Wangcc46b102019-09-12 11:19:01 -0700493 // Similar to the test above, the caller connects with the callee via a prflx
494 // candidate.
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700495 int expected_fingerprint_caller = MakeUsageFingerprint(
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000496 {UsageEvent::AUDIO_ADDED, UsageEvent::VIDEO_ADDED,
497 UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
498 UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
499 UsageEvent::CANDIDATE_COLLECTED, UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
500 UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED, UsageEvent::ICE_STATE_CONNECTED,
501 UsageEvent::REMOTE_CANDIDATE_ADDED, UsageEvent::CLOSE_CALLED});
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700502
503 int expected_fingerprint_callee = MakeUsageFingerprint(
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000504 {UsageEvent::AUDIO_ADDED, UsageEvent::VIDEO_ADDED,
505 UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
506 UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
507 UsageEvent::CANDIDATE_COLLECTED, UsageEvent::MDNS_CANDIDATE_COLLECTED,
508 UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, UsageEvent::ICE_STATE_CONNECTED,
509 UsageEvent::REMOTE_CANDIDATE_ADDED,
510 UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED});
Ying Wangef3998f2019-12-09 13:06:53 +0100511 EXPECT_METRIC_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
512 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
513 expected_fingerprint_caller));
514 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
515 expected_fingerprint_callee));
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700516}
517
Mirko Bonadei5eb43b42021-01-18 13:24:40 +0100518#ifdef WEBRTC_HAVE_SCTP
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200519TEST_F(PeerConnectionUsageHistogramTest, FingerprintDataOnly) {
520 auto caller = CreatePeerConnection();
521 auto callee = CreatePeerConnection();
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200522 caller->CreateDataChannel("foodata");
Harald Alvestrand42386282018-07-12 07:56:05 +0200523 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200524 ASSERT_TRUE_WAIT(callee->HaveDataChannel(), kDefaultTimeout);
525 caller->pc()->Close();
526 callee->pc()->Close();
527 int expected_fingerprint = MakeUsageFingerprint(
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000528 {UsageEvent::DATA_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
529 UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
530 UsageEvent::CANDIDATE_COLLECTED, UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
531 UsageEvent::ICE_STATE_CONNECTED, UsageEvent::REMOTE_CANDIDATE_ADDED,
532 UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED});
Ying Wangef3998f2019-12-09 13:06:53 +0100533 EXPECT_METRIC_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
534 EXPECT_METRIC_TRUE(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200535 webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint) ==
536 2 ||
Harald Alvestrand056d8112018-07-16 19:18:58 +0200537 webrtc::metrics::NumEvents(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200538 kUsagePatternMetric,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200539 expected_fingerprint |
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000540 static_cast<int>(UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) == 2);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200541}
Mirko Bonadei5eb43b42021-01-18 13:24:40 +0100542#endif // WEBRTC_HAVE_SCTP
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200543#endif // WEBRTC_ANDROID
544
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200545TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurn) {
546 RTCConfiguration configuration;
Henrik Boström62995db2022-01-03 09:58:10 +0100547 configuration.sdp_semantics = SdpSemantics::kUnifiedPlan;
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200548 PeerConnection::IceServer server;
Harald Alvestranda3dd7722020-11-27 08:05:42 +0000549 server.urls = {"stun:dummy.stun.server"};
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200550 configuration.servers.push_back(server);
Harald Alvestranda3dd7722020-11-27 08:05:42 +0000551 server.urls = {"turn:dummy.turn.server"};
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200552 server.username = "username";
553 server.password = "password";
554 configuration.servers.push_back(server);
555 auto caller = CreatePeerConnection(configuration);
556 ASSERT_TRUE(caller);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200557 caller->pc()->Close();
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000558 int expected_fingerprint = MakeUsageFingerprint(
559 {UsageEvent::STUN_SERVER_ADDED, UsageEvent::TURN_SERVER_ADDED,
560 UsageEvent::CLOSE_CALLED});
Ying Wangef3998f2019-12-09 13:06:53 +0100561 EXPECT_METRIC_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
562 EXPECT_METRIC_EQ(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200563 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200564}
565
566TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurnInReconfiguration) {
567 RTCConfiguration configuration;
Henrik Boström62995db2022-01-03 09:58:10 +0100568 configuration.sdp_semantics = SdpSemantics::kUnifiedPlan;
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200569 PeerConnection::IceServer server;
Harald Alvestranda3dd7722020-11-27 08:05:42 +0000570 server.urls = {"stun:dummy.stun.server"};
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200571 configuration.servers.push_back(server);
Harald Alvestranda3dd7722020-11-27 08:05:42 +0000572 server.urls = {"turn:dummy.turn.server"};
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200573 server.username = "username";
574 server.password = "password";
575 configuration.servers.push_back(server);
576 auto caller = CreatePeerConnection();
577 ASSERT_TRUE(caller);
Niels Möller2579f0c2019-08-19 09:58:17 +0200578 ASSERT_TRUE(caller->pc()->SetConfiguration(configuration).ok());
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200579 caller->pc()->Close();
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000580 int expected_fingerprint = MakeUsageFingerprint(
581 {UsageEvent::STUN_SERVER_ADDED, UsageEvent::TURN_SERVER_ADDED,
582 UsageEvent::CLOSE_CALLED});
Ying Wangef3998f2019-12-09 13:06:53 +0100583 EXPECT_METRIC_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
584 EXPECT_METRIC_EQ(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200585 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200586}
587
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700588TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIPCaller) {
Harald Alvestrand056d8112018-07-16 19:18:58 +0200589 auto caller = CreatePeerConnectionWithPrivateLocalAddresses();
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700590 auto callee = CreatePeerConnection();
Harald Alvestrand056d8112018-07-16 19:18:58 +0200591 caller->AddAudioTrack("audio");
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700592 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200593 caller->pc()->Close();
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700594 callee->pc()->Close();
595
596 int expected_fingerprint_caller = MakeUsageFingerprint(
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000597 {UsageEvent::AUDIO_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
598 UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
599 UsageEvent::CANDIDATE_COLLECTED, UsageEvent::PRIVATE_CANDIDATE_COLLECTED,
600 UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, UsageEvent::ICE_STATE_CONNECTED,
601 UsageEvent::REMOTE_CANDIDATE_ADDED,
602 UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED});
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700603
604 int expected_fingerprint_callee = MakeUsageFingerprint(
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000605 {UsageEvent::AUDIO_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
606 UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
607 UsageEvent::CANDIDATE_COLLECTED, UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
608 UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED,
609 UsageEvent::ICE_STATE_CONNECTED, UsageEvent::REMOTE_CANDIDATE_ADDED,
610 UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED});
Ying Wangef3998f2019-12-09 13:06:53 +0100611 EXPECT_METRIC_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
612 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
613 expected_fingerprint_caller));
614 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
615 expected_fingerprint_callee));
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700616}
617
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700618TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIpv6Callee) {
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700619 auto caller = CreatePeerConnection();
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700620 auto callee = CreatePeerConnectionWithPrivateIpv6LocalAddresses();
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700621 caller->AddAudioTrack("audio");
622 ASSERT_TRUE(caller->ConnectTo(callee.get()));
623 caller->pc()->Close();
624 callee->pc()->Close();
625
626 int expected_fingerprint_caller = MakeUsageFingerprint(
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000627 {UsageEvent::AUDIO_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
628 UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
629 UsageEvent::CANDIDATE_COLLECTED, UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
630 UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED,
631 UsageEvent::ICE_STATE_CONNECTED, UsageEvent::REMOTE_CANDIDATE_ADDED,
632 UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED,
633 UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED});
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700634
635 int expected_fingerprint_callee = MakeUsageFingerprint(
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000636 {UsageEvent::AUDIO_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
637 UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
638 UsageEvent::CANDIDATE_COLLECTED, UsageEvent::PRIVATE_CANDIDATE_COLLECTED,
639 UsageEvent::IPV6_CANDIDATE_COLLECTED,
640 UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
641 UsageEvent::REMOTE_CANDIDATE_ADDED, UsageEvent::ICE_STATE_CONNECTED,
642 UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED});
Ying Wangef3998f2019-12-09 13:06:53 +0100643 EXPECT_METRIC_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
644 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
645 expected_fingerprint_caller));
646 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
647 expected_fingerprint_callee));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200648}
649
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200650#ifndef WEBRTC_ANDROID
Mirko Bonadei5eb43b42021-01-18 13:24:40 +0100651#ifdef WEBRTC_HAVE_SCTP
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700652// Test that the usage pattern bits for adding remote (private IPv6) candidates
653// are set when the remote candidates are retrieved from the Offer SDP instead
654// of trickled ICE messages.
655TEST_F(PeerConnectionUsageHistogramTest,
656 AddRemoteCandidatesFromRemoteDescription) {
657 // We construct the following data-channel-only scenario. The caller collects
658 // IPv6 private local candidates and appends them in the Offer as in
659 // non-trickled sessions. The callee collects mDNS candidates that are not
660 // contained in the Answer as in Trickle ICE. Only the Offer and Answer are
661 // signaled and we expect a connection with prflx remote candidates at the
662 // caller side.
663 auto caller = CreatePeerConnectionWithPrivateIpv6LocalAddresses();
Henrik Boström62995db2022-01-03 09:58:10 +0100664 RTCConfiguration config;
665 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
666 auto callee = CreatePeerConnectionWithMdns(config);
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700667 caller->CreateDataChannel("test_channel");
668 ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
669 // Wait until the gathering completes so that the session description would
670 // have contained ICE candidates.
671 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
672 caller->ice_gathering_state(), kDefaultTimeout);
673 EXPECT_TRUE(caller->observer()->candidate_gathered());
674 // Get the current offer that contains candidates and pass it to the callee.
675 //
Artem Titov880fa812021-07-30 22:30:23 +0200676 // Note that we cannot use CloneSessionDescription on `cur_offer` to obtain an
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700677 // SDP with candidates. The method above does not strictly copy everything, in
678 // particular, not copying the ICE candidates.
679 // TODO(qingsi): Technically, this is a bug. Fix it.
680 auto cur_offer = caller->pc()->local_description();
681 ASSERT_TRUE(cur_offer);
682 std::string sdp_with_candidates_str;
683 cur_offer->ToString(&sdp_with_candidates_str);
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200684 auto offer = std::make_unique<JsepSessionDescription>(SdpType::kOffer);
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700685 ASSERT_TRUE(SdpDeserialize(sdp_with_candidates_str, offer.get(),
686 nullptr /* error */));
687 ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
688
689 // By default, the Answer created does not contain ICE candidates.
690 auto answer = callee->CreateAnswer();
691 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
692 caller->SetRemoteDescription(std::move(answer));
693 EXPECT_TRUE_WAIT(caller->IsConnected(), kDefaultTimeout);
694 EXPECT_TRUE_WAIT(callee->IsConnected(), kDefaultTimeout);
695 // The callee needs to process the open message to have the data channel open.
696 EXPECT_TRUE_WAIT(callee->observer()->last_datachannel_ != nullptr,
697 kDefaultTimeout);
698 caller->pc()->Close();
699 callee->pc()->Close();
700
701 // The caller should not have added any remote candidate either via
Qingsi Wangcc46b102019-09-12 11:19:01 -0700702 // AddIceCandidate or from the remote description. Also, the caller connects
703 // with the callee via a prflx candidate and hence no direct connection bit
704 // should be set.
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700705 int expected_fingerprint_caller = MakeUsageFingerprint(
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000706 {UsageEvent::DATA_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
707 UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
708 UsageEvent::CANDIDATE_COLLECTED, UsageEvent::PRIVATE_CANDIDATE_COLLECTED,
709 UsageEvent::IPV6_CANDIDATE_COLLECTED, UsageEvent::ICE_STATE_CONNECTED,
710 UsageEvent::CLOSE_CALLED});
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700711
712 int expected_fingerprint_callee = MakeUsageFingerprint(
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000713 {UsageEvent::DATA_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
714 UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
715 UsageEvent::CANDIDATE_COLLECTED, UsageEvent::MDNS_CANDIDATE_COLLECTED,
716 UsageEvent::REMOTE_CANDIDATE_ADDED,
717 UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED,
718 UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED, UsageEvent::ICE_STATE_CONNECTED,
719 UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED});
Ying Wangef3998f2019-12-09 13:06:53 +0100720 EXPECT_METRIC_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
721 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
722 expected_fingerprint_caller));
723 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
724 expected_fingerprint_callee));
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700725}
726
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200727TEST_F(PeerConnectionUsageHistogramTest, NotableUsageNoted) {
728 auto caller = CreatePeerConnection();
729 caller->CreateDataChannel("foo");
730 caller->GenerateOfferAndCollectCandidates();
731 caller->pc()->Close();
732 int expected_fingerprint = MakeUsageFingerprint(
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000733 {UsageEvent::DATA_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
734 UsageEvent::CANDIDATE_COLLECTED, UsageEvent::CLOSE_CALLED});
Ying Wangef3998f2019-12-09 13:06:53 +0100735 EXPECT_METRIC_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
736 EXPECT_METRIC_TRUE(
737 expected_fingerprint == ObservedFingerprint() ||
738 (expected_fingerprint |
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000739 static_cast<int>(UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
Ying Wangef3998f2019-12-09 13:06:53 +0100740 ObservedFingerprint());
741 EXPECT_METRIC_EQ(absl::make_optional(ObservedFingerprint()),
742 caller->observer()->interesting_usage_detected());
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200743}
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200744
745TEST_F(PeerConnectionUsageHistogramTest, NotableUsageOnEventFiring) {
746 auto caller = CreatePeerConnection();
747 caller->CreateDataChannel("foo");
748 caller->GenerateOfferAndCollectCandidates();
749 int expected_fingerprint = MakeUsageFingerprint(
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000750 {UsageEvent::DATA_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
751 UsageEvent::CANDIDATE_COLLECTED});
Ying Wangef3998f2019-12-09 13:06:53 +0100752 EXPECT_METRIC_EQ(0, webrtc::metrics::NumSamples(kUsagePatternMetric));
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200753 caller->GetInternalPeerConnection()->RequestUsagePatternReportForTesting();
Ying Wangef3998f2019-12-09 13:06:53 +0100754 EXPECT_METRIC_EQ_WAIT(1, webrtc::metrics::NumSamples(kUsagePatternMetric),
755 kDefaultTimeout);
756 EXPECT_METRIC_TRUE(
757 expected_fingerprint == ObservedFingerprint() ||
758 (expected_fingerprint |
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000759 static_cast<int>(UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
Ying Wangef3998f2019-12-09 13:06:53 +0100760 ObservedFingerprint());
761 EXPECT_METRIC_EQ(absl::make_optional(ObservedFingerprint()),
762 caller->observer()->interesting_usage_detected());
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200763}
764
765TEST_F(PeerConnectionUsageHistogramTest,
766 NoNotableUsageOnEventFiringAfterClose) {
767 auto caller = CreatePeerConnection();
768 caller->CreateDataChannel("foo");
769 caller->GenerateOfferAndCollectCandidates();
770 int expected_fingerprint = MakeUsageFingerprint(
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000771 {UsageEvent::DATA_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
772 UsageEvent::CANDIDATE_COLLECTED, UsageEvent::CLOSE_CALLED});
Ying Wangef3998f2019-12-09 13:06:53 +0100773 EXPECT_METRIC_EQ(0, webrtc::metrics::NumSamples(kUsagePatternMetric));
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200774 caller->pc()->Close();
Ying Wangef3998f2019-12-09 13:06:53 +0100775 EXPECT_METRIC_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200776 caller->GetInternalPeerConnection()->RequestUsagePatternReportForTesting();
777 caller->observer()->ClearInterestingUsageDetector();
Ying Wangef3998f2019-12-09 13:06:53 +0100778 EXPECT_METRIC_EQ_WAIT(2, webrtc::metrics::NumSamples(kUsagePatternMetric),
779 kDefaultTimeout);
780 EXPECT_METRIC_TRUE(
781 expected_fingerprint == ObservedFingerprint() ||
782 (expected_fingerprint |
Harald Alvestrand44d0dff2020-10-09 05:43:53 +0000783 static_cast<int>(UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
Ying Wangef3998f2019-12-09 13:06:53 +0100784 ObservedFingerprint());
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200785 // After close, the usage-detection callback should NOT have been called.
Ying Wangef3998f2019-12-09 13:06:53 +0100786 EXPECT_METRIC_FALSE(caller->observer()->interesting_usage_detected());
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200787}
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200788#endif
789#endif
790
Harald Alvestrand19793842018-06-25 12:03:50 +0200791} // namespace webrtc