blob: 97555a9b669e870571a8af9fe47a029371256965 [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"
Steve Anton10542f22019-01-11 09:11:00 -080025#include "media/base/fake_media_engine.h"
Jeroen de Borstaf242c82019-04-24 13:13:48 -070026#include "p2p/base/mock_async_resolver.h"
Steve Anton10542f22019-01-11 09:11:00 -080027#include "p2p/base/port_allocator.h"
28#include "p2p/client/basic_port_allocator.h"
29#include "pc/peer_connection.h"
30#include "pc/peer_connection_factory.h"
31#include "pc/peer_connection_wrapper.h"
32#include "pc/sdp_utils.h"
33#include "pc/test/mock_peer_connection_observers.h"
Jeroen de Borstaf242c82019-04-24 13:13:48 -070034#include "rtc_base/arraysize.h"
Yves Gerey3e707812018-11-28 16:47:49 +010035#include "rtc_base/checks.h"
Steve Anton10542f22019-01-11 09:11:00 -080036#include "rtc_base/fake_network.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020037#include "rtc_base/gunit.h"
Steve Anton10542f22019-01-11 09:11:00 -080038#include "rtc_base/ref_counted_object.h"
39#include "rtc_base/rtc_certificate_generator.h"
Steve Anton10542f22019-01-11 09:11:00 -080040#include "rtc_base/socket_address.h"
Yves Gerey3e707812018-11-28 16:47:49 +010041#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080042#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020043#include "system_wrappers/include/metrics.h"
Jeroen de Borstaf242c82019-04-24 13:13:48 -070044#include "test/gmock.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020045
46namespace webrtc {
47
48using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
49using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
Jeroen de Borstaf242c82019-04-24 13:13:48 -070050using ::testing::NiceMock;
Harald Alvestrand19793842018-06-25 12:03:50 +020051using ::testing::Values;
52
Harald Alvestrandc0e97252018-07-26 10:39:55 +020053static const char kUsagePatternMetric[] = "WebRTC.PeerConnection.UsagePattern";
Harald Alvestrand19793842018-06-25 12:03:50 +020054static constexpr int kDefaultTimeout = 10000;
Jeroen de Borstaf242c82019-04-24 13:13:48 -070055static const rtc::SocketAddress kLocalAddrs[2] = {
56 rtc::SocketAddress("1.1.1.1", 0), rtc::SocketAddress("2.2.2.2", 0)};
Harald Alvestrand056d8112018-07-16 19:18:58 +020057static const rtc::SocketAddress kPrivateLocalAddress("10.1.1.1", 0);
Harald Alvestrand19793842018-06-25 12:03:50 +020058
59int MakeUsageFingerprint(std::set<PeerConnection::UsageEvent> events) {
60 int signature = 0;
61 for (const auto it : events) {
62 signature |= static_cast<int>(it);
63 }
64 return signature;
65}
66
67class PeerConnectionFactoryForUsageHistogramTest
68 : public rtc::RefCountedObject<PeerConnectionFactory> {
69 public:
70 PeerConnectionFactoryForUsageHistogramTest()
Danil Chapovalovf5258be2019-03-19 17:45:24 +010071 : rtc::RefCountedObject<PeerConnectionFactory>([] {
72 PeerConnectionFactoryDependencies dependencies;
73 dependencies.network_thread = rtc::Thread::Current();
74 dependencies.worker_thread = rtc::Thread::Current();
75 dependencies.signaling_thread = rtc::Thread::Current();
76 dependencies.media_engine =
77 absl::make_unique<cricket::FakeMediaEngine>();
78 dependencies.call_factory = CreateCallFactory();
79 return dependencies;
80 }()) {}
Harald Alvestrand19793842018-06-25 12:03:50 +020081
82 void ActionsBeforeInitializeForTesting(PeerConnectionInterface* pc) override {
83 PeerConnection* internal_pc = static_cast<PeerConnection*>(pc);
84 if (return_histogram_very_quickly_) {
85 internal_pc->ReturnHistogramVeryQuicklyForTesting();
86 }
87 }
88
89 void ReturnHistogramVeryQuickly() { return_histogram_very_quickly_ = true; }
90
91 private:
Harald Alvestrand183e09d2018-06-28 12:04:41 +020092 bool return_histogram_very_quickly_ = false;
93};
94
95class PeerConnectionWrapperForUsageHistogramTest;
Yves Gerey3e707812018-11-28 16:47:49 +010096
Harald Alvestrand183e09d2018-06-28 12:04:41 +020097typedef PeerConnectionWrapperForUsageHistogramTest* RawWrapperPtr;
98
99class ObserverForUsageHistogramTest : public MockPeerConnectionObserver {
100 public:
101 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override;
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200102
103 void OnInterestingUsage(int usage_pattern) override {
104 interesting_usage_detected_ = usage_pattern;
105 }
106
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200107 void PrepareToExchangeCandidates(RawWrapperPtr other) {
108 candidate_target_ = other;
109 }
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200110
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200111 bool HaveDataChannel() { return last_datachannel_; }
112
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200113 absl::optional<int> interesting_usage_detected() {
114 return interesting_usage_detected_;
115 }
116
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200117 void ClearInterestingUsageDetector() {
118 interesting_usage_detected_ = absl::optional<int>();
119 }
120
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200121 private:
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200122 absl::optional<int> interesting_usage_detected_;
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200123 RawWrapperPtr candidate_target_; // Note: Not thread-safe against deletions.
Harald Alvestrand19793842018-06-25 12:03:50 +0200124};
125
126class PeerConnectionWrapperForUsageHistogramTest
127 : public PeerConnectionWrapper {
128 public:
129 using PeerConnectionWrapper::PeerConnectionWrapper;
130
131 PeerConnection* GetInternalPeerConnection() {
132 auto* pci =
133 static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
134 pc());
135 return static_cast<PeerConnection*>(pci->internal());
136 }
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200137
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200138 // Override with different return type
139 ObserverForUsageHistogramTest* observer() {
140 return static_cast<ObserverForUsageHistogramTest*>(
141 PeerConnectionWrapper::observer());
142 }
143
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200144 void PrepareToExchangeCandidates(
145 PeerConnectionWrapperForUsageHistogramTest* other) {
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200146 observer()->PrepareToExchangeCandidates(other);
147 other->observer()->PrepareToExchangeCandidates(this);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200148 }
149
150 bool IsConnected() {
151 return pc()->ice_connection_state() ==
152 PeerConnectionInterface::kIceConnectionConnected ||
153 pc()->ice_connection_state() ==
154 PeerConnectionInterface::kIceConnectionCompleted;
155 }
156
157 bool HaveDataChannel() {
158 return static_cast<ObserverForUsageHistogramTest*>(observer())
159 ->HaveDataChannel();
160 }
Harald Alvestrand42386282018-07-12 07:56:05 +0200161 void AddOrBufferIceCandidate(const webrtc::IceCandidateInterface* candidate) {
162 if (!pc()->AddIceCandidate(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));
169 }
170 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200171
Harald Alvestrand42386282018-07-12 07:56:05 +0200172 void AddBufferedIceCandidates() {
173 for (const auto& candidate : buffered_candidates_) {
174 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
175 }
176 buffered_candidates_.clear();
177 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200178
Harald Alvestrand42386282018-07-12 07:56:05 +0200179 bool ConnectTo(PeerConnectionWrapperForUsageHistogramTest* callee) {
180 PrepareToExchangeCandidates(callee);
Harald Alvestrand056d8112018-07-16 19:18:58 +0200181 if (!ExchangeOfferAnswerWith(callee)) {
182 return false;
183 }
Harald Alvestrand42386282018-07-12 07:56:05 +0200184 AddBufferedIceCandidates();
185 callee->AddBufferedIceCandidates();
Harald Alvestrand056d8112018-07-16 19:18:58 +0200186 WAIT(IsConnected(), kDefaultTimeout);
187 WAIT(callee->IsConnected(), kDefaultTimeout);
Harald Alvestrand42386282018-07-12 07:56:05 +0200188 return IsConnected() && callee->IsConnected();
189 }
190
Harald Alvestrand056d8112018-07-16 19:18:58 +0200191 bool GenerateOfferAndCollectCandidates() {
192 auto offer = CreateOffer(RTCOfferAnswerOptions());
193 if (!offer) {
194 return false;
195 }
196 bool set_local_offer =
197 SetLocalDescription(CloneSessionDescription(offer.get()));
198 EXPECT_TRUE(set_local_offer);
199 if (!set_local_offer) {
200 return false;
201 }
202 EXPECT_TRUE_WAIT(observer()->ice_gathering_complete_, kDefaultTimeout);
203 return true;
204 }
205
Harald Alvestrand42386282018-07-12 07:56:05 +0200206 private:
207 // Candidates that have been sent but not yet configured
208 std::vector<std::unique_ptr<webrtc::IceCandidateInterface>>
209 buffered_candidates_;
Harald Alvestrand19793842018-06-25 12:03:50 +0200210};
211
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200212void ObserverForUsageHistogramTest::OnIceCandidate(
213 const webrtc::IceCandidateInterface* candidate) {
214 if (candidate_target_) {
Harald Alvestrand42386282018-07-12 07:56:05 +0200215 this->candidate_target_->AddOrBufferIceCandidate(candidate);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200216 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200217 // If target is not set, ignore. This happens in one-ended unit tests.
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200218}
219
Harald Alvestrand19793842018-06-25 12:03:50 +0200220class PeerConnectionUsageHistogramTest : public ::testing::Test {
221 protected:
222 typedef std::unique_ptr<PeerConnectionWrapperForUsageHistogramTest>
223 WrapperPtr;
224
225 PeerConnectionUsageHistogramTest()
226 : vss_(new rtc::VirtualSocketServer()), main_(vss_.get()) {
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700227 webrtc::metrics::Reset();
Harald Alvestrand19793842018-06-25 12:03:50 +0200228 }
229
230 WrapperPtr CreatePeerConnection() {
Harald Alvestrand056d8112018-07-16 19:18:58 +0200231 return CreatePeerConnection(RTCConfiguration(),
232 PeerConnectionFactoryInterface::Options(),
233 nullptr, false);
Harald Alvestrand19793842018-06-25 12:03:50 +0200234 }
235
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200236 WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
237 return CreatePeerConnection(
Harald Alvestrand056d8112018-07-16 19:18:58 +0200238 config, PeerConnectionFactoryInterface::Options(), nullptr, false);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200239 }
240
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700241 WrapperPtr CreatePeerConnectionWithMdns(const RTCConfiguration& config) {
242 auto resolver_factory =
243 absl::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
244
245 webrtc::PeerConnectionDependencies deps(nullptr /* observer_in */);
246
247 auto fake_network = NewFakeNetwork();
248 fake_network->CreateMdnsResponder(rtc::Thread::Current());
249 fake_network->AddInterface(NextLocalAddress());
250
251 std::unique_ptr<cricket::BasicPortAllocator> port_allocator(
252 new cricket::BasicPortAllocator(fake_network));
253
254 deps.async_resolver_factory = std::move(resolver_factory);
255 deps.allocator = std::move(port_allocator);
256
257 return CreatePeerConnection(config,
258 PeerConnectionFactoryInterface::Options(),
259 std::move(deps), false);
260 }
261
Harald Alvestrand19793842018-06-25 12:03:50 +0200262 WrapperPtr CreatePeerConnectionWithImmediateReport() {
Harald Alvestrand056d8112018-07-16 19:18:58 +0200263 return CreatePeerConnection(RTCConfiguration(),
264 PeerConnectionFactoryInterface::Options(),
265 nullptr, true);
266 }
267
268 WrapperPtr CreatePeerConnectionWithPrivateLocalAddresses() {
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700269 auto* fake_network = NewFakeNetwork();
270 fake_network->AddInterface(NextLocalAddress());
271 fake_network->AddInterface(kPrivateLocalAddress);
272
273 auto port_allocator =
274 absl::make_unique<cricket::BasicPortAllocator>(fake_network);
275
Harald Alvestrand056d8112018-07-16 19:18:58 +0200276 return CreatePeerConnection(RTCConfiguration(),
277 PeerConnectionFactoryInterface::Options(),
278 std::move(port_allocator), false);
Harald Alvestrand19793842018-06-25 12:03:50 +0200279 }
280
281 WrapperPtr CreatePeerConnection(
282 const RTCConfiguration& config,
283 const PeerConnectionFactoryInterface::Options factory_options,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200284 std::unique_ptr<cricket::PortAllocator> allocator,
Harald Alvestrand19793842018-06-25 12:03:50 +0200285 bool immediate_report) {
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700286 PeerConnectionDependencies deps(nullptr);
287 deps.allocator = std::move(allocator);
288
289 return CreatePeerConnection(config, factory_options, std::move(deps),
290 immediate_report);
291 }
292
293 WrapperPtr CreatePeerConnection(
294 const RTCConfiguration& config,
295 const PeerConnectionFactoryInterface::Options factory_options,
296 PeerConnectionDependencies deps,
297 bool immediate_report) {
Harald Alvestrand19793842018-06-25 12:03:50 +0200298 rtc::scoped_refptr<PeerConnectionFactoryForUsageHistogramTest> pc_factory(
299 new PeerConnectionFactoryForUsageHistogramTest());
300 pc_factory->SetOptions(factory_options);
301 RTC_CHECK(pc_factory->Initialize());
302 if (immediate_report) {
303 pc_factory->ReturnHistogramVeryQuickly();
304 }
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700305
306 // If no allocator is provided, one will be created using a network manager
307 // that uses the host network. This doesn't work on all trybots.
308 if (!deps.allocator) {
309 auto fake_network = NewFakeNetwork();
310 fake_network->AddInterface(NextLocalAddress());
311 deps.allocator =
312 absl::make_unique<cricket::BasicPortAllocator>(fake_network);
313 }
314
Karl Wiberg918f50c2018-07-05 11:40:33 +0200315 auto observer = absl::make_unique<ObserverForUsageHistogramTest>();
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700316 deps.observer = observer.get();
317
318 auto pc = pc_factory->CreatePeerConnection(config, std::move(deps));
Harald Alvestrand19793842018-06-25 12:03:50 +0200319 if (!pc) {
320 return nullptr;
321 }
322
Yves Gerey4e933292018-10-31 15:36:05 +0100323 observer->SetPeerConnectionInterface(pc.get());
Karl Wiberg918f50c2018-07-05 11:40:33 +0200324 auto wrapper =
325 absl::make_unique<PeerConnectionWrapperForUsageHistogramTest>(
326 pc_factory, pc, std::move(observer));
Harald Alvestrand19793842018-06-25 12:03:50 +0200327 return wrapper;
328 }
329
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200330 int ObservedFingerprint() {
331 // This works correctly only if there is only one sample value
332 // that has been counted.
333 // Returns -1 for "not found".
334 return webrtc::metrics::MinSample(kUsagePatternMetric);
335 }
336
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700337 // The PeerConnection's port allocator is tied to the PeerConnection's
338 // lifetime and expects the underlying NetworkManager to outlive it. That
339 // prevents us from having the PeerConnectionWrapper own the fake network.
340 // Therefore, the test fixture will own all the fake networks even though
341 // tests should access the fake network through the PeerConnectionWrapper.
342 rtc::FakeNetworkManager* NewFakeNetwork() {
343 fake_networks_.emplace_back(absl::make_unique<rtc::FakeNetworkManager>());
344 return fake_networks_.back().get();
345 }
346
347 rtc::SocketAddress NextLocalAddress() {
348 RTC_DCHECK(next_local_address_ < (int)arraysize(kLocalAddrs));
349 return kLocalAddrs[next_local_address_++];
350 }
351
352 std::vector<std::unique_ptr<rtc::FakeNetworkManager>> fake_networks_;
353 int next_local_address_ = 0;
Harald Alvestrand19793842018-06-25 12:03:50 +0200354 std::unique_ptr<rtc::VirtualSocketServer> vss_;
355 rtc::AutoSocketServerThread main_;
356};
357
358TEST_F(PeerConnectionUsageHistogramTest, UsageFingerprintHistogramFromTimeout) {
359 auto pc = CreatePeerConnectionWithImmediateReport();
360
Harald Alvestrand19793842018-06-25 12:03:50 +0200361 int expected_fingerprint = MakeUsageFingerprint({});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200362 ASSERT_EQ_WAIT(1, webrtc::metrics::NumSamples(kUsagePatternMetric),
363 kDefaultTimeout);
364 EXPECT_EQ(
365 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrand19793842018-06-25 12:03:50 +0200366}
367
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200368#ifndef WEBRTC_ANDROID
369// These tests do not work on Android. Why is unclear.
370// https://bugs.webrtc.org/9461
371
372// Test getting the usage fingerprint for an audio/video connection.
373TEST_F(PeerConnectionUsageHistogramTest, FingerprintAudioVideo) {
374 auto caller = CreatePeerConnection();
375 auto callee = CreatePeerConnection();
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200376 caller->AddAudioTrack("audio");
377 caller->AddVideoTrack("video");
Harald Alvestrand42386282018-07-12 07:56:05 +0200378 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200379 caller->pc()->Close();
380 callee->pc()->Close();
381 int expected_fingerprint = MakeUsageFingerprint(
382 {PeerConnection::UsageEvent::AUDIO_ADDED,
383 PeerConnection::UsageEvent::VIDEO_ADDED,
384 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
385 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
386 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
387 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
388 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
389 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrand056d8112018-07-16 19:18:58 +0200390 // In this case, we may or may not have PRIVATE_CANDIDATE_COLLECTED,
391 // depending on the machine configuration.
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200392 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200393 EXPECT_TRUE(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200394 webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint) ==
395 2 ||
Harald Alvestrand056d8112018-07-16 19:18:58 +0200396 webrtc::metrics::NumEvents(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200397 kUsagePatternMetric,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200398 expected_fingerprint |
399 static_cast<int>(
400 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
401 2);
402}
403
404// Test getting the usage fingerprint when there are no host candidates.
405TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithNoHostCandidates) {
406 RTCConfiguration config;
407 config.type = PeerConnectionInterface::kNoHost;
408 auto caller = CreatePeerConnection(config);
409 auto callee = CreatePeerConnection(config);
410 caller->AddAudioTrack("audio");
411 caller->AddVideoTrack("video");
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700412 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200413 caller->pc()->Close();
414 callee->pc()->Close();
415 int expected_fingerprint = MakeUsageFingerprint(
416 {PeerConnection::UsageEvent::AUDIO_ADDED,
417 PeerConnection::UsageEvent::VIDEO_ADDED,
418 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
419 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
420 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
421 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
422 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
423 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200424 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
425 EXPECT_EQ(
426 2, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200427}
428
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700429// Test getting the usage fingerprint when there are no host candidates.
430TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithMdnsCaller) {
431 RTCConfiguration config;
432
433 // Enable hostname candidates with mDNS names.
434 auto caller = CreatePeerConnectionWithMdns(config);
435 auto callee = CreatePeerConnection(config);
436
437 caller->AddAudioTrack("audio");
438 caller->AddVideoTrack("video");
439 ASSERT_TRUE(caller->ConnectTo(callee.get()));
440 caller->pc()->Close();
441 callee->pc()->Close();
442
443 int expected_fingerprint_caller = MakeUsageFingerprint(
444 {PeerConnection::UsageEvent::AUDIO_ADDED,
445 PeerConnection::UsageEvent::VIDEO_ADDED,
446 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
447 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
448 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
449 PeerConnection::UsageEvent::MDNS_CANDIDATE_COLLECTED,
450 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
451 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
452 PeerConnection::UsageEvent::CLOSE_CALLED});
453
454 int expected_fingerprint_callee = MakeUsageFingerprint(
455 {PeerConnection::UsageEvent::AUDIO_ADDED,
456 PeerConnection::UsageEvent::VIDEO_ADDED,
457 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
458 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
459 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
460 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
461 PeerConnection::UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED,
462 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
463 PeerConnection::UsageEvent::CLOSE_CALLED});
464
465 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
466 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
467 expected_fingerprint_caller));
468 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
469 expected_fingerprint_callee));
470}
471
472TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithMdnsCallee) {
473 RTCConfiguration config;
474
475 // Enable hostname candidates with mDNS names.
476 auto caller = CreatePeerConnection(config);
477 auto callee = CreatePeerConnectionWithMdns(config);
478
479 caller->AddAudioTrack("audio");
480 caller->AddVideoTrack("video");
481 ASSERT_TRUE(caller->ConnectTo(callee.get()));
482 caller->pc()->Close();
483 callee->pc()->Close();
484
485 int expected_fingerprint_caller = MakeUsageFingerprint(
486 {PeerConnection::UsageEvent::AUDIO_ADDED,
487 PeerConnection::UsageEvent::VIDEO_ADDED,
488 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
489 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
490 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
491 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
492 PeerConnection::UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED,
493 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
494 PeerConnection::UsageEvent::CLOSE_CALLED});
495
496 int expected_fingerprint_callee = MakeUsageFingerprint(
497 {PeerConnection::UsageEvent::AUDIO_ADDED,
498 PeerConnection::UsageEvent::VIDEO_ADDED,
499 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
500 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
501 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
502 PeerConnection::UsageEvent::MDNS_CANDIDATE_COLLECTED,
503 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
504 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
505 PeerConnection::UsageEvent::CLOSE_CALLED});
506
507 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
508 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
509 expected_fingerprint_caller));
510 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
511 expected_fingerprint_callee));
512}
513
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200514#ifdef HAVE_SCTP
515TEST_F(PeerConnectionUsageHistogramTest, FingerprintDataOnly) {
516 auto caller = CreatePeerConnection();
517 auto callee = CreatePeerConnection();
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200518 caller->CreateDataChannel("foodata");
Harald Alvestrand42386282018-07-12 07:56:05 +0200519 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200520 ASSERT_TRUE_WAIT(callee->HaveDataChannel(), kDefaultTimeout);
521 caller->pc()->Close();
522 callee->pc()->Close();
523 int expected_fingerprint = MakeUsageFingerprint(
524 {PeerConnection::UsageEvent::DATA_ADDED,
525 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
526 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
527 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
528 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
529 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
530 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200531 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200532 EXPECT_TRUE(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200533 webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint) ==
534 2 ||
Harald Alvestrand056d8112018-07-16 19:18:58 +0200535 webrtc::metrics::NumEvents(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200536 kUsagePatternMetric,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200537 expected_fingerprint |
538 static_cast<int>(
539 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
540 2);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200541}
542#endif // HAVE_SCTP
543#endif // WEBRTC_ANDROID
544
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200545TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurn) {
546 RTCConfiguration configuration;
547 PeerConnection::IceServer server;
548 server.urls = {"stun:dummy.stun.server/"};
549 configuration.servers.push_back(server);
550 server.urls = {"turn:dummy.turn.server/"};
551 server.username = "username";
552 server.password = "password";
553 configuration.servers.push_back(server);
554 auto caller = CreatePeerConnection(configuration);
555 ASSERT_TRUE(caller);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200556 caller->pc()->Close();
557 int expected_fingerprint =
558 MakeUsageFingerprint({PeerConnection::UsageEvent::STUN_SERVER_ADDED,
559 PeerConnection::UsageEvent::TURN_SERVER_ADDED,
560 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200561 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
562 EXPECT_EQ(
563 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200564}
565
566TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurnInReconfiguration) {
567 RTCConfiguration configuration;
568 PeerConnection::IceServer server;
569 server.urls = {"stun:dummy.stun.server/"};
570 configuration.servers.push_back(server);
571 server.urls = {"turn:dummy.turn.server/"};
572 server.username = "username";
573 server.password = "password";
574 configuration.servers.push_back(server);
575 auto caller = CreatePeerConnection();
576 ASSERT_TRUE(caller);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200577 RTCError error;
578 caller->pc()->SetConfiguration(configuration, &error);
579 ASSERT_TRUE(error.ok());
580 caller->pc()->Close();
581 int expected_fingerprint =
582 MakeUsageFingerprint({PeerConnection::UsageEvent::STUN_SERVER_ADDED,
583 PeerConnection::UsageEvent::TURN_SERVER_ADDED,
584 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200585 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
586 EXPECT_EQ(
587 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200588}
589
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700590TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIPCaller) {
Harald Alvestrand056d8112018-07-16 19:18:58 +0200591 auto caller = CreatePeerConnectionWithPrivateLocalAddresses();
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700592 auto callee = CreatePeerConnection();
Harald Alvestrand056d8112018-07-16 19:18:58 +0200593 caller->AddAudioTrack("audio");
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700594 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200595 caller->pc()->Close();
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700596 callee->pc()->Close();
597
598 int expected_fingerprint_caller = MakeUsageFingerprint(
Harald Alvestrand056d8112018-07-16 19:18:58 +0200599 {PeerConnection::UsageEvent::AUDIO_ADDED,
600 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700601 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200602 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700603 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED,
604 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
605 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
606 PeerConnection::UsageEvent::CLOSE_CALLED});
607
608 int expected_fingerprint_callee = MakeUsageFingerprint(
609 {PeerConnection::UsageEvent::AUDIO_ADDED,
610 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
611 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
612 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
613 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
614 PeerConnection::UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED,
615 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
616 PeerConnection::UsageEvent::CLOSE_CALLED});
617
618 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
619 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
620 expected_fingerprint_caller));
621 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
622 expected_fingerprint_callee));
623}
624
625TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIPCallee) {
626 auto caller = CreatePeerConnection();
627 auto callee = CreatePeerConnectionWithPrivateLocalAddresses();
628 caller->AddAudioTrack("audio");
629 ASSERT_TRUE(caller->ConnectTo(callee.get()));
630 caller->pc()->Close();
631 callee->pc()->Close();
632
633 int expected_fingerprint_caller = MakeUsageFingerprint(
634 {PeerConnection::UsageEvent::AUDIO_ADDED,
635 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
636 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
637 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
638 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
639 PeerConnection::UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED,
640 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
641 PeerConnection::UsageEvent::CLOSE_CALLED});
642
643 int expected_fingerprint_callee = MakeUsageFingerprint(
644 {PeerConnection::UsageEvent::AUDIO_ADDED,
645 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
646 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
647 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
648 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED,
649 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
650 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
651 PeerConnection::UsageEvent::CLOSE_CALLED});
652
653 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
654 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
655 expected_fingerprint_caller));
656 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
657 expected_fingerprint_callee));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200658}
659
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200660#ifndef WEBRTC_ANDROID
661#ifdef HAVE_SCTP
662TEST_F(PeerConnectionUsageHistogramTest, NotableUsageNoted) {
663 auto caller = CreatePeerConnection();
664 caller->CreateDataChannel("foo");
665 caller->GenerateOfferAndCollectCandidates();
666 caller->pc()->Close();
667 int expected_fingerprint = MakeUsageFingerprint(
668 {PeerConnection::UsageEvent::DATA_ADDED,
669 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
670 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
671 PeerConnection::UsageEvent::CLOSE_CALLED});
672 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
673 EXPECT_TRUE(expected_fingerprint == ObservedFingerprint() ||
674 (expected_fingerprint |
675 static_cast<int>(
676 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
677 ObservedFingerprint());
678 EXPECT_EQ(absl::make_optional(ObservedFingerprint()),
679 caller->observer()->interesting_usage_detected());
680}
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200681
682TEST_F(PeerConnectionUsageHistogramTest, NotableUsageOnEventFiring) {
683 auto caller = CreatePeerConnection();
684 caller->CreateDataChannel("foo");
685 caller->GenerateOfferAndCollectCandidates();
686 int expected_fingerprint = MakeUsageFingerprint(
687 {PeerConnection::UsageEvent::DATA_ADDED,
688 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
689 PeerConnection::UsageEvent::CANDIDATE_COLLECTED});
690 EXPECT_EQ(0, webrtc::metrics::NumSamples(kUsagePatternMetric));
691 caller->GetInternalPeerConnection()->RequestUsagePatternReportForTesting();
692 EXPECT_EQ_WAIT(1, webrtc::metrics::NumSamples(kUsagePatternMetric),
693 kDefaultTimeout);
694 EXPECT_TRUE(expected_fingerprint == ObservedFingerprint() ||
695 (expected_fingerprint |
696 static_cast<int>(
697 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
698 ObservedFingerprint());
699 EXPECT_EQ(absl::make_optional(ObservedFingerprint()),
700 caller->observer()->interesting_usage_detected());
701}
702
703TEST_F(PeerConnectionUsageHistogramTest,
704 NoNotableUsageOnEventFiringAfterClose) {
705 auto caller = CreatePeerConnection();
706 caller->CreateDataChannel("foo");
707 caller->GenerateOfferAndCollectCandidates();
708 int expected_fingerprint = MakeUsageFingerprint(
709 {PeerConnection::UsageEvent::DATA_ADDED,
710 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
711 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
712 PeerConnection::UsageEvent::CLOSE_CALLED});
713 EXPECT_EQ(0, webrtc::metrics::NumSamples(kUsagePatternMetric));
714 caller->pc()->Close();
715 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
716 caller->GetInternalPeerConnection()->RequestUsagePatternReportForTesting();
717 caller->observer()->ClearInterestingUsageDetector();
718 EXPECT_EQ_WAIT(2, webrtc::metrics::NumSamples(kUsagePatternMetric),
719 kDefaultTimeout);
720 EXPECT_TRUE(expected_fingerprint == ObservedFingerprint() ||
721 (expected_fingerprint |
722 static_cast<int>(
723 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
724 ObservedFingerprint());
725 // After close, the usage-detection callback should NOT have been called.
726 EXPECT_FALSE(caller->observer()->interesting_usage_detected());
727}
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200728#endif
729#endif
730
Harald Alvestrand19793842018-06-25 12:03:50 +0200731} // namespace webrtc