blob: 2f997aecbd31ed809a491a99faddb7f6f8ea3eb6 [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
Karl Wiberg918f50c2018-07-05 11:40:33 +020017#include "absl/memory/memory.h"
Yves Gerey3e707812018-11-28 16:47:49 +010018#include "absl/types/optional.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"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "api/peer_connection_interface.h"
22#include "api/peer_connection_proxy.h"
23#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"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "media/base/fake_media_engine.h"
Jeroen de Borstaf242c82019-04-24 13:13:48 -070027#include "p2p/base/mock_async_resolver.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "p2p/base/port_allocator.h"
29#include "p2p/client/basic_port_allocator.h"
30#include "pc/peer_connection.h"
31#include "pc/peer_connection_factory.h"
32#include "pc/peer_connection_wrapper.h"
33#include "pc/sdp_utils.h"
34#include "pc/test/mock_peer_connection_observers.h"
Jeroen de Borstaf242c82019-04-24 13:13:48 -070035#include "rtc_base/arraysize.h"
Yves Gerey3e707812018-11-28 16:47:49 +010036#include "rtc_base/checks.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070037#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080038#include "rtc_base/fake_network.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020039#include "rtc_base/gunit.h"
Steve Anton10542f22019-01-11 09:11:00 -080040#include "rtc_base/ref_counted_object.h"
41#include "rtc_base/rtc_certificate_generator.h"
Steve Anton10542f22019-01-11 09:11:00 -080042#include "rtc_base/socket_address.h"
Yves Gerey3e707812018-11-28 16:47:49 +010043#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080044#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020045#include "system_wrappers/include/metrics.h"
Jeroen de Borstaf242c82019-04-24 13:13:48 -070046#include "test/gmock.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020047
48namespace webrtc {
49
50using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
51using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
Jeroen de Borstaf242c82019-04-24 13:13:48 -070052using ::testing::NiceMock;
Harald Alvestrand19793842018-06-25 12:03:50 +020053using ::testing::Values;
54
Harald Alvestrandc0e97252018-07-26 10:39:55 +020055static const char kUsagePatternMetric[] = "WebRTC.PeerConnection.UsagePattern";
Harald Alvestrand19793842018-06-25 12:03:50 +020056static constexpr int kDefaultTimeout = 10000;
Jeroen de Borstaf242c82019-04-24 13:13:48 -070057static const rtc::SocketAddress kLocalAddrs[2] = {
58 rtc::SocketAddress("1.1.1.1", 0), rtc::SocketAddress("2.2.2.2", 0)};
Harald Alvestrand056d8112018-07-16 19:18:58 +020059static const rtc::SocketAddress kPrivateLocalAddress("10.1.1.1", 0);
Harald Alvestrand19793842018-06-25 12:03:50 +020060
61int MakeUsageFingerprint(std::set<PeerConnection::UsageEvent> events) {
62 int signature = 0;
63 for (const auto it : events) {
64 signature |= static_cast<int>(it);
65 }
66 return signature;
67}
68
69class PeerConnectionFactoryForUsageHistogramTest
70 : public rtc::RefCountedObject<PeerConnectionFactory> {
71 public:
72 PeerConnectionFactoryForUsageHistogramTest()
Danil Chapovalovf5258be2019-03-19 17:45:24 +010073 : rtc::RefCountedObject<PeerConnectionFactory>([] {
74 PeerConnectionFactoryDependencies dependencies;
75 dependencies.network_thread = rtc::Thread::Current();
76 dependencies.worker_thread = rtc::Thread::Current();
77 dependencies.signaling_thread = rtc::Thread::Current();
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020078 dependencies.task_queue_factory = CreateDefaultTaskQueueFactory();
Danil Chapovalovf5258be2019-03-19 17:45:24 +010079 dependencies.media_engine =
80 absl::make_unique<cricket::FakeMediaEngine>();
81 dependencies.call_factory = CreateCallFactory();
82 return dependencies;
83 }()) {}
Harald Alvestrand19793842018-06-25 12:03:50 +020084
85 void ActionsBeforeInitializeForTesting(PeerConnectionInterface* pc) override {
86 PeerConnection* internal_pc = static_cast<PeerConnection*>(pc);
87 if (return_histogram_very_quickly_) {
88 internal_pc->ReturnHistogramVeryQuicklyForTesting();
89 }
90 }
91
92 void ReturnHistogramVeryQuickly() { return_histogram_very_quickly_ = true; }
93
94 private:
Harald Alvestrand183e09d2018-06-28 12:04:41 +020095 bool return_histogram_very_quickly_ = false;
96};
97
98class PeerConnectionWrapperForUsageHistogramTest;
Yves Gerey3e707812018-11-28 16:47:49 +010099
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200100typedef PeerConnectionWrapperForUsageHistogramTest* RawWrapperPtr;
101
102class ObserverForUsageHistogramTest : public MockPeerConnectionObserver {
103 public:
104 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override;
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200105
106 void OnInterestingUsage(int usage_pattern) override {
107 interesting_usage_detected_ = usage_pattern;
108 }
109
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200110 void PrepareToExchangeCandidates(RawWrapperPtr other) {
111 candidate_target_ = other;
112 }
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200113
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200114 bool HaveDataChannel() { return last_datachannel_; }
115
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200116 absl::optional<int> interesting_usage_detected() {
117 return interesting_usage_detected_;
118 }
119
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200120 void ClearInterestingUsageDetector() {
121 interesting_usage_detected_ = absl::optional<int>();
122 }
123
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200124 private:
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200125 absl::optional<int> interesting_usage_detected_;
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200126 RawWrapperPtr candidate_target_; // Note: Not thread-safe against deletions.
Harald Alvestrand19793842018-06-25 12:03:50 +0200127};
128
129class PeerConnectionWrapperForUsageHistogramTest
130 : public PeerConnectionWrapper {
131 public:
132 using PeerConnectionWrapper::PeerConnectionWrapper;
133
134 PeerConnection* GetInternalPeerConnection() {
135 auto* pci =
136 static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
137 pc());
138 return static_cast<PeerConnection*>(pci->internal());
139 }
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200140
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200141 // Override with different return type
142 ObserverForUsageHistogramTest* observer() {
143 return static_cast<ObserverForUsageHistogramTest*>(
144 PeerConnectionWrapper::observer());
145 }
146
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200147 void PrepareToExchangeCandidates(
148 PeerConnectionWrapperForUsageHistogramTest* other) {
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200149 observer()->PrepareToExchangeCandidates(other);
150 other->observer()->PrepareToExchangeCandidates(this);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200151 }
152
153 bool IsConnected() {
154 return pc()->ice_connection_state() ==
155 PeerConnectionInterface::kIceConnectionConnected ||
156 pc()->ice_connection_state() ==
157 PeerConnectionInterface::kIceConnectionCompleted;
158 }
159
160 bool HaveDataChannel() {
161 return static_cast<ObserverForUsageHistogramTest*>(observer())
162 ->HaveDataChannel();
163 }
Harald Alvestrand42386282018-07-12 07:56:05 +0200164 void AddOrBufferIceCandidate(const webrtc::IceCandidateInterface* candidate) {
165 if (!pc()->AddIceCandidate(candidate)) {
166 std::string sdp;
167 EXPECT_TRUE(candidate->ToString(&sdp));
168 std::unique_ptr<webrtc::IceCandidateInterface> candidate_copy(
169 CreateIceCandidate(candidate->sdp_mid(), candidate->sdp_mline_index(),
170 sdp, nullptr));
171 buffered_candidates_.push_back(std::move(candidate_copy));
172 }
173 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200174
Harald Alvestrand42386282018-07-12 07:56:05 +0200175 void AddBufferedIceCandidates() {
176 for (const auto& candidate : buffered_candidates_) {
177 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
178 }
179 buffered_candidates_.clear();
180 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200181
Harald Alvestrand42386282018-07-12 07:56:05 +0200182 bool ConnectTo(PeerConnectionWrapperForUsageHistogramTest* callee) {
183 PrepareToExchangeCandidates(callee);
Harald Alvestrand056d8112018-07-16 19:18:58 +0200184 if (!ExchangeOfferAnswerWith(callee)) {
185 return false;
186 }
Harald Alvestrand42386282018-07-12 07:56:05 +0200187 AddBufferedIceCandidates();
188 callee->AddBufferedIceCandidates();
Harald Alvestrand056d8112018-07-16 19:18:58 +0200189 WAIT(IsConnected(), kDefaultTimeout);
190 WAIT(callee->IsConnected(), kDefaultTimeout);
Harald Alvestrand42386282018-07-12 07:56:05 +0200191 return IsConnected() && callee->IsConnected();
192 }
193
Harald Alvestrand056d8112018-07-16 19:18:58 +0200194 bool GenerateOfferAndCollectCandidates() {
195 auto offer = CreateOffer(RTCOfferAnswerOptions());
196 if (!offer) {
197 return false;
198 }
199 bool set_local_offer =
200 SetLocalDescription(CloneSessionDescription(offer.get()));
201 EXPECT_TRUE(set_local_offer);
202 if (!set_local_offer) {
203 return false;
204 }
205 EXPECT_TRUE_WAIT(observer()->ice_gathering_complete_, kDefaultTimeout);
206 return true;
207 }
208
Harald Alvestrand42386282018-07-12 07:56:05 +0200209 private:
210 // Candidates that have been sent but not yet configured
211 std::vector<std::unique_ptr<webrtc::IceCandidateInterface>>
212 buffered_candidates_;
Harald Alvestrand19793842018-06-25 12:03:50 +0200213};
214
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200215void ObserverForUsageHistogramTest::OnIceCandidate(
216 const webrtc::IceCandidateInterface* candidate) {
217 if (candidate_target_) {
Harald Alvestrand42386282018-07-12 07:56:05 +0200218 this->candidate_target_->AddOrBufferIceCandidate(candidate);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200219 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200220 // If target is not set, ignore. This happens in one-ended unit tests.
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200221}
222
Harald Alvestrand19793842018-06-25 12:03:50 +0200223class PeerConnectionUsageHistogramTest : public ::testing::Test {
224 protected:
225 typedef std::unique_ptr<PeerConnectionWrapperForUsageHistogramTest>
226 WrapperPtr;
227
228 PeerConnectionUsageHistogramTest()
229 : vss_(new rtc::VirtualSocketServer()), main_(vss_.get()) {
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700230 webrtc::metrics::Reset();
Harald Alvestrand19793842018-06-25 12:03:50 +0200231 }
232
233 WrapperPtr CreatePeerConnection() {
Harald Alvestrand056d8112018-07-16 19:18:58 +0200234 return CreatePeerConnection(RTCConfiguration(),
235 PeerConnectionFactoryInterface::Options(),
236 nullptr, false);
Harald Alvestrand19793842018-06-25 12:03:50 +0200237 }
238
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200239 WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
240 return CreatePeerConnection(
Harald Alvestrand056d8112018-07-16 19:18:58 +0200241 config, PeerConnectionFactoryInterface::Options(), nullptr, false);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200242 }
243
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700244 WrapperPtr CreatePeerConnectionWithMdns(const RTCConfiguration& config) {
245 auto resolver_factory =
246 absl::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
247
248 webrtc::PeerConnectionDependencies deps(nullptr /* observer_in */);
249
250 auto fake_network = NewFakeNetwork();
Qingsi Wangecd30542019-05-22 14:34:56 -0700251 fake_network->set_mdns_responder(
252 absl::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700253 fake_network->AddInterface(NextLocalAddress());
254
255 std::unique_ptr<cricket::BasicPortAllocator> port_allocator(
256 new cricket::BasicPortAllocator(fake_network));
257
258 deps.async_resolver_factory = std::move(resolver_factory);
259 deps.allocator = std::move(port_allocator);
260
261 return CreatePeerConnection(config,
262 PeerConnectionFactoryInterface::Options(),
263 std::move(deps), false);
264 }
265
Harald Alvestrand19793842018-06-25 12:03:50 +0200266 WrapperPtr CreatePeerConnectionWithImmediateReport() {
Harald Alvestrand056d8112018-07-16 19:18:58 +0200267 return CreatePeerConnection(RTCConfiguration(),
268 PeerConnectionFactoryInterface::Options(),
269 nullptr, true);
270 }
271
272 WrapperPtr CreatePeerConnectionWithPrivateLocalAddresses() {
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700273 auto* fake_network = NewFakeNetwork();
274 fake_network->AddInterface(NextLocalAddress());
275 fake_network->AddInterface(kPrivateLocalAddress);
276
277 auto port_allocator =
278 absl::make_unique<cricket::BasicPortAllocator>(fake_network);
279
Harald Alvestrand056d8112018-07-16 19:18:58 +0200280 return CreatePeerConnection(RTCConfiguration(),
281 PeerConnectionFactoryInterface::Options(),
282 std::move(port_allocator), false);
Harald Alvestrand19793842018-06-25 12:03:50 +0200283 }
284
285 WrapperPtr CreatePeerConnection(
286 const RTCConfiguration& config,
287 const PeerConnectionFactoryInterface::Options factory_options,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200288 std::unique_ptr<cricket::PortAllocator> allocator,
Harald Alvestrand19793842018-06-25 12:03:50 +0200289 bool immediate_report) {
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700290 PeerConnectionDependencies deps(nullptr);
291 deps.allocator = std::move(allocator);
292
293 return CreatePeerConnection(config, factory_options, std::move(deps),
294 immediate_report);
295 }
296
297 WrapperPtr CreatePeerConnection(
298 const RTCConfiguration& config,
299 const PeerConnectionFactoryInterface::Options factory_options,
300 PeerConnectionDependencies deps,
301 bool immediate_report) {
Harald Alvestrand19793842018-06-25 12:03:50 +0200302 rtc::scoped_refptr<PeerConnectionFactoryForUsageHistogramTest> pc_factory(
303 new PeerConnectionFactoryForUsageHistogramTest());
304 pc_factory->SetOptions(factory_options);
305 RTC_CHECK(pc_factory->Initialize());
306 if (immediate_report) {
307 pc_factory->ReturnHistogramVeryQuickly();
308 }
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700309
310 // If no allocator is provided, one will be created using a network manager
311 // that uses the host network. This doesn't work on all trybots.
312 if (!deps.allocator) {
313 auto fake_network = NewFakeNetwork();
314 fake_network->AddInterface(NextLocalAddress());
315 deps.allocator =
316 absl::make_unique<cricket::BasicPortAllocator>(fake_network);
317 }
318
Karl Wiberg918f50c2018-07-05 11:40:33 +0200319 auto observer = absl::make_unique<ObserverForUsageHistogramTest>();
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700320 deps.observer = observer.get();
321
322 auto pc = pc_factory->CreatePeerConnection(config, std::move(deps));
Harald Alvestrand19793842018-06-25 12:03:50 +0200323 if (!pc) {
324 return nullptr;
325 }
326
Yves Gerey4e933292018-10-31 15:36:05 +0100327 observer->SetPeerConnectionInterface(pc.get());
Karl Wiberg918f50c2018-07-05 11:40:33 +0200328 auto wrapper =
329 absl::make_unique<PeerConnectionWrapperForUsageHistogramTest>(
330 pc_factory, pc, std::move(observer));
Harald Alvestrand19793842018-06-25 12:03:50 +0200331 return wrapper;
332 }
333
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200334 int ObservedFingerprint() {
335 // This works correctly only if there is only one sample value
336 // that has been counted.
337 // Returns -1 for "not found".
338 return webrtc::metrics::MinSample(kUsagePatternMetric);
339 }
340
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700341 // The PeerConnection's port allocator is tied to the PeerConnection's
342 // lifetime and expects the underlying NetworkManager to outlive it. That
343 // prevents us from having the PeerConnectionWrapper own the fake network.
344 // Therefore, the test fixture will own all the fake networks even though
345 // tests should access the fake network through the PeerConnectionWrapper.
346 rtc::FakeNetworkManager* NewFakeNetwork() {
347 fake_networks_.emplace_back(absl::make_unique<rtc::FakeNetworkManager>());
348 return fake_networks_.back().get();
349 }
350
351 rtc::SocketAddress NextLocalAddress() {
352 RTC_DCHECK(next_local_address_ < (int)arraysize(kLocalAddrs));
353 return kLocalAddrs[next_local_address_++];
354 }
355
356 std::vector<std::unique_ptr<rtc::FakeNetworkManager>> fake_networks_;
357 int next_local_address_ = 0;
Harald Alvestrand19793842018-06-25 12:03:50 +0200358 std::unique_ptr<rtc::VirtualSocketServer> vss_;
359 rtc::AutoSocketServerThread main_;
360};
361
362TEST_F(PeerConnectionUsageHistogramTest, UsageFingerprintHistogramFromTimeout) {
363 auto pc = CreatePeerConnectionWithImmediateReport();
364
Harald Alvestrand19793842018-06-25 12:03:50 +0200365 int expected_fingerprint = MakeUsageFingerprint({});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200366 ASSERT_EQ_WAIT(1, webrtc::metrics::NumSamples(kUsagePatternMetric),
367 kDefaultTimeout);
368 EXPECT_EQ(
369 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrand19793842018-06-25 12:03:50 +0200370}
371
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200372#ifndef WEBRTC_ANDROID
373// These tests do not work on Android. Why is unclear.
374// https://bugs.webrtc.org/9461
375
376// Test getting the usage fingerprint for an audio/video connection.
377TEST_F(PeerConnectionUsageHistogramTest, FingerprintAudioVideo) {
378 auto caller = CreatePeerConnection();
379 auto callee = CreatePeerConnection();
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200380 caller->AddAudioTrack("audio");
381 caller->AddVideoTrack("video");
Harald Alvestrand42386282018-07-12 07:56:05 +0200382 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200383 caller->pc()->Close();
384 callee->pc()->Close();
385 int expected_fingerprint = MakeUsageFingerprint(
386 {PeerConnection::UsageEvent::AUDIO_ADDED,
387 PeerConnection::UsageEvent::VIDEO_ADDED,
388 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
389 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
390 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
391 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
392 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
393 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrand056d8112018-07-16 19:18:58 +0200394 // In this case, we may or may not have PRIVATE_CANDIDATE_COLLECTED,
395 // depending on the machine configuration.
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200396 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200397 EXPECT_TRUE(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200398 webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint) ==
399 2 ||
Harald Alvestrand056d8112018-07-16 19:18:58 +0200400 webrtc::metrics::NumEvents(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200401 kUsagePatternMetric,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200402 expected_fingerprint |
403 static_cast<int>(
404 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
405 2);
406}
407
408// Test getting the usage fingerprint when there are no host candidates.
409TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithNoHostCandidates) {
410 RTCConfiguration config;
411 config.type = PeerConnectionInterface::kNoHost;
412 auto caller = CreatePeerConnection(config);
413 auto callee = CreatePeerConnection(config);
414 caller->AddAudioTrack("audio");
415 caller->AddVideoTrack("video");
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700416 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200417 caller->pc()->Close();
418 callee->pc()->Close();
419 int expected_fingerprint = MakeUsageFingerprint(
420 {PeerConnection::UsageEvent::AUDIO_ADDED,
421 PeerConnection::UsageEvent::VIDEO_ADDED,
422 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
423 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
424 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
425 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
426 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
427 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200428 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
429 EXPECT_EQ(
430 2, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200431}
432
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700433// Test getting the usage fingerprint when there are no host candidates.
434TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithMdnsCaller) {
435 RTCConfiguration config;
436
437 // Enable hostname candidates with mDNS names.
438 auto caller = CreatePeerConnectionWithMdns(config);
439 auto callee = CreatePeerConnection(config);
440
441 caller->AddAudioTrack("audio");
442 caller->AddVideoTrack("video");
443 ASSERT_TRUE(caller->ConnectTo(callee.get()));
444 caller->pc()->Close();
445 callee->pc()->Close();
446
447 int expected_fingerprint_caller = MakeUsageFingerprint(
448 {PeerConnection::UsageEvent::AUDIO_ADDED,
449 PeerConnection::UsageEvent::VIDEO_ADDED,
450 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
451 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
452 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
453 PeerConnection::UsageEvent::MDNS_CANDIDATE_COLLECTED,
454 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
455 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
456 PeerConnection::UsageEvent::CLOSE_CALLED});
457
458 int expected_fingerprint_callee = MakeUsageFingerprint(
459 {PeerConnection::UsageEvent::AUDIO_ADDED,
460 PeerConnection::UsageEvent::VIDEO_ADDED,
461 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
462 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
463 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
464 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
465 PeerConnection::UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED,
466 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
467 PeerConnection::UsageEvent::CLOSE_CALLED});
468
469 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
470 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
471 expected_fingerprint_caller));
472 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
473 expected_fingerprint_callee));
474}
475
476TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithMdnsCallee) {
477 RTCConfiguration config;
478
479 // Enable hostname candidates with mDNS names.
480 auto caller = CreatePeerConnection(config);
481 auto callee = CreatePeerConnectionWithMdns(config);
482
483 caller->AddAudioTrack("audio");
484 caller->AddVideoTrack("video");
485 ASSERT_TRUE(caller->ConnectTo(callee.get()));
486 caller->pc()->Close();
487 callee->pc()->Close();
488
489 int expected_fingerprint_caller = MakeUsageFingerprint(
490 {PeerConnection::UsageEvent::AUDIO_ADDED,
491 PeerConnection::UsageEvent::VIDEO_ADDED,
492 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
493 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
494 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
495 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
496 PeerConnection::UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED,
497 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
498 PeerConnection::UsageEvent::CLOSE_CALLED});
499
500 int expected_fingerprint_callee = MakeUsageFingerprint(
501 {PeerConnection::UsageEvent::AUDIO_ADDED,
502 PeerConnection::UsageEvent::VIDEO_ADDED,
503 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
504 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
505 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
506 PeerConnection::UsageEvent::MDNS_CANDIDATE_COLLECTED,
507 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
508 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
509 PeerConnection::UsageEvent::CLOSE_CALLED});
510
511 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
512 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
513 expected_fingerprint_caller));
514 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
515 expected_fingerprint_callee));
516}
517
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200518#ifdef HAVE_SCTP
519TEST_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(
528 {PeerConnection::UsageEvent::DATA_ADDED,
529 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
530 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
531 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
532 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
533 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
534 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200535 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200536 EXPECT_TRUE(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200537 webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint) ==
538 2 ||
Harald Alvestrand056d8112018-07-16 19:18:58 +0200539 webrtc::metrics::NumEvents(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200540 kUsagePatternMetric,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200541 expected_fingerprint |
542 static_cast<int>(
543 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
544 2);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200545}
546#endif // HAVE_SCTP
547#endif // WEBRTC_ANDROID
548
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200549TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurn) {
550 RTCConfiguration configuration;
551 PeerConnection::IceServer server;
552 server.urls = {"stun:dummy.stun.server/"};
553 configuration.servers.push_back(server);
554 server.urls = {"turn:dummy.turn.server/"};
555 server.username = "username";
556 server.password = "password";
557 configuration.servers.push_back(server);
558 auto caller = CreatePeerConnection(configuration);
559 ASSERT_TRUE(caller);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200560 caller->pc()->Close();
561 int expected_fingerprint =
562 MakeUsageFingerprint({PeerConnection::UsageEvent::STUN_SERVER_ADDED,
563 PeerConnection::UsageEvent::TURN_SERVER_ADDED,
564 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200565 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
566 EXPECT_EQ(
567 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200568}
569
570TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurnInReconfiguration) {
571 RTCConfiguration configuration;
572 PeerConnection::IceServer server;
573 server.urls = {"stun:dummy.stun.server/"};
574 configuration.servers.push_back(server);
575 server.urls = {"turn:dummy.turn.server/"};
576 server.username = "username";
577 server.password = "password";
578 configuration.servers.push_back(server);
579 auto caller = CreatePeerConnection();
580 ASSERT_TRUE(caller);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200581 RTCError error;
582 caller->pc()->SetConfiguration(configuration, &error);
583 ASSERT_TRUE(error.ok());
584 caller->pc()->Close();
585 int expected_fingerprint =
586 MakeUsageFingerprint({PeerConnection::UsageEvent::STUN_SERVER_ADDED,
587 PeerConnection::UsageEvent::TURN_SERVER_ADDED,
588 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200589 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
590 EXPECT_EQ(
591 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200592}
593
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700594TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIPCaller) {
Harald Alvestrand056d8112018-07-16 19:18:58 +0200595 auto caller = CreatePeerConnectionWithPrivateLocalAddresses();
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700596 auto callee = CreatePeerConnection();
Harald Alvestrand056d8112018-07-16 19:18:58 +0200597 caller->AddAudioTrack("audio");
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700598 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200599 caller->pc()->Close();
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700600 callee->pc()->Close();
601
602 int expected_fingerprint_caller = MakeUsageFingerprint(
Harald Alvestrand056d8112018-07-16 19:18:58 +0200603 {PeerConnection::UsageEvent::AUDIO_ADDED,
604 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700605 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200606 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700607 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED,
608 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
609 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
610 PeerConnection::UsageEvent::CLOSE_CALLED});
611
612 int expected_fingerprint_callee = MakeUsageFingerprint(
613 {PeerConnection::UsageEvent::AUDIO_ADDED,
614 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
615 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
616 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
617 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
618 PeerConnection::UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED,
619 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
620 PeerConnection::UsageEvent::CLOSE_CALLED});
621
622 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
623 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
624 expected_fingerprint_caller));
625 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
626 expected_fingerprint_callee));
627}
628
629TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIPCallee) {
630 auto caller = CreatePeerConnection();
631 auto callee = CreatePeerConnectionWithPrivateLocalAddresses();
632 caller->AddAudioTrack("audio");
633 ASSERT_TRUE(caller->ConnectTo(callee.get()));
634 caller->pc()->Close();
635 callee->pc()->Close();
636
637 int expected_fingerprint_caller = MakeUsageFingerprint(
638 {PeerConnection::UsageEvent::AUDIO_ADDED,
639 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
640 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
641 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
642 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
643 PeerConnection::UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED,
644 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
645 PeerConnection::UsageEvent::CLOSE_CALLED});
646
647 int expected_fingerprint_callee = MakeUsageFingerprint(
648 {PeerConnection::UsageEvent::AUDIO_ADDED,
649 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
650 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
651 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
652 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED,
653 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
654 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
655 PeerConnection::UsageEvent::CLOSE_CALLED});
656
657 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
658 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
659 expected_fingerprint_caller));
660 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
661 expected_fingerprint_callee));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200662}
663
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200664#ifndef WEBRTC_ANDROID
665#ifdef HAVE_SCTP
666TEST_F(PeerConnectionUsageHistogramTest, NotableUsageNoted) {
667 auto caller = CreatePeerConnection();
668 caller->CreateDataChannel("foo");
669 caller->GenerateOfferAndCollectCandidates();
670 caller->pc()->Close();
671 int expected_fingerprint = MakeUsageFingerprint(
672 {PeerConnection::UsageEvent::DATA_ADDED,
673 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
674 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
675 PeerConnection::UsageEvent::CLOSE_CALLED});
676 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
677 EXPECT_TRUE(expected_fingerprint == ObservedFingerprint() ||
678 (expected_fingerprint |
679 static_cast<int>(
680 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
681 ObservedFingerprint());
682 EXPECT_EQ(absl::make_optional(ObservedFingerprint()),
683 caller->observer()->interesting_usage_detected());
684}
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200685
686TEST_F(PeerConnectionUsageHistogramTest, NotableUsageOnEventFiring) {
687 auto caller = CreatePeerConnection();
688 caller->CreateDataChannel("foo");
689 caller->GenerateOfferAndCollectCandidates();
690 int expected_fingerprint = MakeUsageFingerprint(
691 {PeerConnection::UsageEvent::DATA_ADDED,
692 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
693 PeerConnection::UsageEvent::CANDIDATE_COLLECTED});
694 EXPECT_EQ(0, webrtc::metrics::NumSamples(kUsagePatternMetric));
695 caller->GetInternalPeerConnection()->RequestUsagePatternReportForTesting();
696 EXPECT_EQ_WAIT(1, webrtc::metrics::NumSamples(kUsagePatternMetric),
697 kDefaultTimeout);
698 EXPECT_TRUE(expected_fingerprint == ObservedFingerprint() ||
699 (expected_fingerprint |
700 static_cast<int>(
701 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
702 ObservedFingerprint());
703 EXPECT_EQ(absl::make_optional(ObservedFingerprint()),
704 caller->observer()->interesting_usage_detected());
705}
706
707TEST_F(PeerConnectionUsageHistogramTest,
708 NoNotableUsageOnEventFiringAfterClose) {
709 auto caller = CreatePeerConnection();
710 caller->CreateDataChannel("foo");
711 caller->GenerateOfferAndCollectCandidates();
712 int expected_fingerprint = MakeUsageFingerprint(
713 {PeerConnection::UsageEvent::DATA_ADDED,
714 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
715 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
716 PeerConnection::UsageEvent::CLOSE_CALLED});
717 EXPECT_EQ(0, webrtc::metrics::NumSamples(kUsagePatternMetric));
718 caller->pc()->Close();
719 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
720 caller->GetInternalPeerConnection()->RequestUsagePatternReportForTesting();
721 caller->observer()->ClearInterestingUsageDetector();
722 EXPECT_EQ_WAIT(2, webrtc::metrics::NumSamples(kUsagePatternMetric),
723 kDefaultTimeout);
724 EXPECT_TRUE(expected_fingerprint == ObservedFingerprint() ||
725 (expected_fingerprint |
726 static_cast<int>(
727 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
728 ObservedFingerprint());
729 // After close, the usage-detection callback should NOT have been called.
730 EXPECT_FALSE(caller->observer()->interesting_usage_detected());
731}
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200732#endif
733#endif
734
Harald Alvestrand19793842018-06-25 12:03:50 +0200735} // namespace webrtc