blob: 987fa3a63fceb3ab0bbc67830fb06280b8d4cf24 [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"
19#include "api/call/callfactoryinterface.h"
Harald Alvestrand42386282018-07-12 07:56:05 +020020#include "api/jsep.h"
Yves Gerey3e707812018-11-28 16:47:49 +010021#include "api/peerconnectioninterface.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020022#include "api/peerconnectionproxy.h"
Yves Gerey3e707812018-11-28 16:47:49 +010023#include "api/rtcerror.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020024#include "media/base/fakemediaengine.h"
Yves Gerey3e707812018-11-28 16:47:49 +010025#include "p2p/base/portallocator.h"
Harald Alvestrand056d8112018-07-16 19:18:58 +020026#include "p2p/client/basicportallocator.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020027#include "pc/peerconnection.h"
28#include "pc/peerconnectionfactory.h"
29#include "pc/peerconnectionwrapper.h"
30#include "pc/sdputils.h"
Yves Gerey3e707812018-11-28 16:47:49 +010031#include "pc/test/mockpeerconnectionobservers.h"
32#include "rtc_base/checks.h"
Harald Alvestrand056d8112018-07-16 19:18:58 +020033#include "rtc_base/fakenetwork.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020034#include "rtc_base/gunit.h"
Yves Gerey3e707812018-11-28 16:47:49 +010035#include "rtc_base/refcountedobject.h"
36#include "rtc_base/rtccertificategenerator.h"
37#include "rtc_base/scoped_ref_ptr.h"
38#include "rtc_base/socketaddress.h"
39#include "rtc_base/thread.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020040#include "rtc_base/virtualsocketserver.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020041#include "system_wrappers/include/metrics.h"
Yves Gerey3e707812018-11-28 16:47:49 +010042#include "test/gtest.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020043
44namespace webrtc {
45
46using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
47using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
48using ::testing::Values;
49
Harald Alvestrandc0e97252018-07-26 10:39:55 +020050static const char kUsagePatternMetric[] = "WebRTC.PeerConnection.UsagePattern";
Harald Alvestrand19793842018-06-25 12:03:50 +020051static constexpr int kDefaultTimeout = 10000;
Harald Alvestrand056d8112018-07-16 19:18:58 +020052static const rtc::SocketAddress kDefaultLocalAddress("1.1.1.1", 0);
53static const rtc::SocketAddress kPrivateLocalAddress("10.1.1.1", 0);
Harald Alvestrand19793842018-06-25 12:03:50 +020054
55int MakeUsageFingerprint(std::set<PeerConnection::UsageEvent> events) {
56 int signature = 0;
57 for (const auto it : events) {
58 signature |= static_cast<int>(it);
59 }
60 return signature;
61}
62
63class PeerConnectionFactoryForUsageHistogramTest
64 : public rtc::RefCountedObject<PeerConnectionFactory> {
65 public:
66 PeerConnectionFactoryForUsageHistogramTest()
67 : rtc::RefCountedObject<PeerConnectionFactory>(
68 rtc::Thread::Current(),
69 rtc::Thread::Current(),
70 rtc::Thread::Current(),
Karl Wiberg918f50c2018-07-05 11:40:33 +020071 absl::make_unique<cricket::FakeMediaEngine>(),
Harald Alvestrand19793842018-06-25 12:03:50 +020072 CreateCallFactory(),
73 nullptr) {}
74
75 void ActionsBeforeInitializeForTesting(PeerConnectionInterface* pc) override {
76 PeerConnection* internal_pc = static_cast<PeerConnection*>(pc);
77 if (return_histogram_very_quickly_) {
78 internal_pc->ReturnHistogramVeryQuicklyForTesting();
79 }
80 }
81
82 void ReturnHistogramVeryQuickly() { return_histogram_very_quickly_ = true; }
83
84 private:
Harald Alvestrand183e09d2018-06-28 12:04:41 +020085 bool return_histogram_very_quickly_ = false;
86};
87
88class PeerConnectionWrapperForUsageHistogramTest;
Yves Gerey3e707812018-11-28 16:47:49 +010089
Harald Alvestrand183e09d2018-06-28 12:04:41 +020090typedef PeerConnectionWrapperForUsageHistogramTest* RawWrapperPtr;
91
92class ObserverForUsageHistogramTest : public MockPeerConnectionObserver {
93 public:
94 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override;
Harald Alvestrandc0e97252018-07-26 10:39:55 +020095
96 void OnInterestingUsage(int usage_pattern) override {
97 interesting_usage_detected_ = usage_pattern;
98 }
99
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200100 void PrepareToExchangeCandidates(RawWrapperPtr other) {
101 candidate_target_ = other;
102 }
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200103
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200104 bool HaveDataChannel() { return last_datachannel_; }
105
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200106 absl::optional<int> interesting_usage_detected() {
107 return interesting_usage_detected_;
108 }
109
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200110 void ClearInterestingUsageDetector() {
111 interesting_usage_detected_ = absl::optional<int>();
112 }
113
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200114 private:
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200115 absl::optional<int> interesting_usage_detected_;
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200116 RawWrapperPtr candidate_target_; // Note: Not thread-safe against deletions.
Harald Alvestrand19793842018-06-25 12:03:50 +0200117};
118
119class PeerConnectionWrapperForUsageHistogramTest
120 : public PeerConnectionWrapper {
121 public:
122 using PeerConnectionWrapper::PeerConnectionWrapper;
123
124 PeerConnection* GetInternalPeerConnection() {
125 auto* pci =
126 static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
127 pc());
128 return static_cast<PeerConnection*>(pci->internal());
129 }
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200130
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200131 // Override with different return type
132 ObserverForUsageHistogramTest* observer() {
133 return static_cast<ObserverForUsageHistogramTest*>(
134 PeerConnectionWrapper::observer());
135 }
136
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200137 void PrepareToExchangeCandidates(
138 PeerConnectionWrapperForUsageHistogramTest* other) {
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200139 observer()->PrepareToExchangeCandidates(other);
140 other->observer()->PrepareToExchangeCandidates(this);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200141 }
142
143 bool IsConnected() {
144 return pc()->ice_connection_state() ==
145 PeerConnectionInterface::kIceConnectionConnected ||
146 pc()->ice_connection_state() ==
147 PeerConnectionInterface::kIceConnectionCompleted;
148 }
149
150 bool HaveDataChannel() {
151 return static_cast<ObserverForUsageHistogramTest*>(observer())
152 ->HaveDataChannel();
153 }
Harald Alvestrand42386282018-07-12 07:56:05 +0200154 void AddOrBufferIceCandidate(const webrtc::IceCandidateInterface* candidate) {
155 if (!pc()->AddIceCandidate(candidate)) {
156 std::string sdp;
157 EXPECT_TRUE(candidate->ToString(&sdp));
158 std::unique_ptr<webrtc::IceCandidateInterface> candidate_copy(
159 CreateIceCandidate(candidate->sdp_mid(), candidate->sdp_mline_index(),
160 sdp, nullptr));
161 buffered_candidates_.push_back(std::move(candidate_copy));
162 }
163 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200164
Harald Alvestrand42386282018-07-12 07:56:05 +0200165 void AddBufferedIceCandidates() {
166 for (const auto& candidate : buffered_candidates_) {
167 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
168 }
169 buffered_candidates_.clear();
170 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200171
Harald Alvestrand42386282018-07-12 07:56:05 +0200172 bool ConnectTo(PeerConnectionWrapperForUsageHistogramTest* callee) {
173 PrepareToExchangeCandidates(callee);
Harald Alvestrand056d8112018-07-16 19:18:58 +0200174 if (!ExchangeOfferAnswerWith(callee)) {
175 return false;
176 }
Harald Alvestrand42386282018-07-12 07:56:05 +0200177 AddBufferedIceCandidates();
178 callee->AddBufferedIceCandidates();
Harald Alvestrand056d8112018-07-16 19:18:58 +0200179 WAIT(IsConnected(), kDefaultTimeout);
180 WAIT(callee->IsConnected(), kDefaultTimeout);
Harald Alvestrand42386282018-07-12 07:56:05 +0200181 return IsConnected() && callee->IsConnected();
182 }
183
Harald Alvestrand056d8112018-07-16 19:18:58 +0200184 bool GenerateOfferAndCollectCandidates() {
185 auto offer = CreateOffer(RTCOfferAnswerOptions());
186 if (!offer) {
187 return false;
188 }
189 bool set_local_offer =
190 SetLocalDescription(CloneSessionDescription(offer.get()));
191 EXPECT_TRUE(set_local_offer);
192 if (!set_local_offer) {
193 return false;
194 }
195 EXPECT_TRUE_WAIT(observer()->ice_gathering_complete_, kDefaultTimeout);
196 return true;
197 }
198
Harald Alvestrand42386282018-07-12 07:56:05 +0200199 private:
200 // Candidates that have been sent but not yet configured
201 std::vector<std::unique_ptr<webrtc::IceCandidateInterface>>
202 buffered_candidates_;
Harald Alvestrand19793842018-06-25 12:03:50 +0200203};
204
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200205void ObserverForUsageHistogramTest::OnIceCandidate(
206 const webrtc::IceCandidateInterface* candidate) {
207 if (candidate_target_) {
Harald Alvestrand42386282018-07-12 07:56:05 +0200208 this->candidate_target_->AddOrBufferIceCandidate(candidate);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200209 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200210 // If target is not set, ignore. This happens in one-ended unit tests.
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200211}
212
Harald Alvestrand19793842018-06-25 12:03:50 +0200213class PeerConnectionUsageHistogramTest : public ::testing::Test {
214 protected:
215 typedef std::unique_ptr<PeerConnectionWrapperForUsageHistogramTest>
216 WrapperPtr;
217
218 PeerConnectionUsageHistogramTest()
219 : vss_(new rtc::VirtualSocketServer()), main_(vss_.get()) {
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700220 webrtc::metrics::Reset();
Harald Alvestrand19793842018-06-25 12:03:50 +0200221 }
222
223 WrapperPtr CreatePeerConnection() {
Harald Alvestrand056d8112018-07-16 19:18:58 +0200224 return CreatePeerConnection(RTCConfiguration(),
225 PeerConnectionFactoryInterface::Options(),
226 nullptr, false);
Harald Alvestrand19793842018-06-25 12:03:50 +0200227 }
228
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200229 WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
230 return CreatePeerConnection(
Harald Alvestrand056d8112018-07-16 19:18:58 +0200231 config, PeerConnectionFactoryInterface::Options(), nullptr, false);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200232 }
233
Harald Alvestrand19793842018-06-25 12:03:50 +0200234 WrapperPtr CreatePeerConnectionWithImmediateReport() {
Harald Alvestrand056d8112018-07-16 19:18:58 +0200235 return CreatePeerConnection(RTCConfiguration(),
236 PeerConnectionFactoryInterface::Options(),
237 nullptr, true);
238 }
239
240 WrapperPtr CreatePeerConnectionWithPrivateLocalAddresses() {
241 fake_network_manager_.reset(new rtc::FakeNetworkManager());
242 fake_network_manager_->AddInterface(kDefaultLocalAddress);
243 fake_network_manager_->AddInterface(kPrivateLocalAddress);
244 std::unique_ptr<cricket::BasicPortAllocator> port_allocator(
245 new cricket::BasicPortAllocator(fake_network_manager_.get()));
246 return CreatePeerConnection(RTCConfiguration(),
247 PeerConnectionFactoryInterface::Options(),
248 std::move(port_allocator), false);
Harald Alvestrand19793842018-06-25 12:03:50 +0200249 }
250
251 WrapperPtr CreatePeerConnection(
252 const RTCConfiguration& config,
253 const PeerConnectionFactoryInterface::Options factory_options,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200254 std::unique_ptr<cricket::PortAllocator> allocator,
Harald Alvestrand19793842018-06-25 12:03:50 +0200255 bool immediate_report) {
256 rtc::scoped_refptr<PeerConnectionFactoryForUsageHistogramTest> pc_factory(
257 new PeerConnectionFactoryForUsageHistogramTest());
258 pc_factory->SetOptions(factory_options);
259 RTC_CHECK(pc_factory->Initialize());
260 if (immediate_report) {
261 pc_factory->ReturnHistogramVeryQuickly();
262 }
Karl Wiberg918f50c2018-07-05 11:40:33 +0200263 auto observer = absl::make_unique<ObserverForUsageHistogramTest>();
Harald Alvestrand056d8112018-07-16 19:18:58 +0200264 auto pc = pc_factory->CreatePeerConnection(config, std::move(allocator),
265 nullptr, observer.get());
Harald Alvestrand19793842018-06-25 12:03:50 +0200266 if (!pc) {
267 return nullptr;
268 }
269
Yves Gerey4e933292018-10-31 15:36:05 +0100270 observer->SetPeerConnectionInterface(pc.get());
Karl Wiberg918f50c2018-07-05 11:40:33 +0200271 auto wrapper =
272 absl::make_unique<PeerConnectionWrapperForUsageHistogramTest>(
273 pc_factory, pc, std::move(observer));
Harald Alvestrand19793842018-06-25 12:03:50 +0200274 return wrapper;
275 }
276
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200277 int ObservedFingerprint() {
278 // This works correctly only if there is only one sample value
279 // that has been counted.
280 // Returns -1 for "not found".
281 return webrtc::metrics::MinSample(kUsagePatternMetric);
282 }
283
Harald Alvestrand056d8112018-07-16 19:18:58 +0200284 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
Harald Alvestrand19793842018-06-25 12:03:50 +0200285 std::unique_ptr<rtc::VirtualSocketServer> vss_;
286 rtc::AutoSocketServerThread main_;
287};
288
289TEST_F(PeerConnectionUsageHistogramTest, UsageFingerprintHistogramFromTimeout) {
290 auto pc = CreatePeerConnectionWithImmediateReport();
291
Harald Alvestrand19793842018-06-25 12:03:50 +0200292 int expected_fingerprint = MakeUsageFingerprint({});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200293 ASSERT_EQ_WAIT(1, webrtc::metrics::NumSamples(kUsagePatternMetric),
294 kDefaultTimeout);
295 EXPECT_EQ(
296 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrand19793842018-06-25 12:03:50 +0200297}
298
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200299#ifndef WEBRTC_ANDROID
300// These tests do not work on Android. Why is unclear.
301// https://bugs.webrtc.org/9461
302
303// Test getting the usage fingerprint for an audio/video connection.
304TEST_F(PeerConnectionUsageHistogramTest, FingerprintAudioVideo) {
305 auto caller = CreatePeerConnection();
306 auto callee = CreatePeerConnection();
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200307 caller->AddAudioTrack("audio");
308 caller->AddVideoTrack("video");
Harald Alvestrand42386282018-07-12 07:56:05 +0200309 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200310 caller->pc()->Close();
311 callee->pc()->Close();
312 int expected_fingerprint = MakeUsageFingerprint(
313 {PeerConnection::UsageEvent::AUDIO_ADDED,
314 PeerConnection::UsageEvent::VIDEO_ADDED,
315 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
316 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
317 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
318 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
319 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
320 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrand056d8112018-07-16 19:18:58 +0200321 // In this case, we may or may not have PRIVATE_CANDIDATE_COLLECTED,
322 // depending on the machine configuration.
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200323 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200324 EXPECT_TRUE(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200325 webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint) ==
326 2 ||
Harald Alvestrand056d8112018-07-16 19:18:58 +0200327 webrtc::metrics::NumEvents(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200328 kUsagePatternMetric,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200329 expected_fingerprint |
330 static_cast<int>(
331 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
332 2);
333}
334
335// Test getting the usage fingerprint when there are no host candidates.
336TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithNoHostCandidates) {
337 RTCConfiguration config;
338 config.type = PeerConnectionInterface::kNoHost;
339 auto caller = CreatePeerConnection(config);
340 auto callee = CreatePeerConnection(config);
341 caller->AddAudioTrack("audio");
342 caller->AddVideoTrack("video");
343 // Under some bot configurations, this will fail - presumably bots where
344 // no working non-host addresses exist.
345 if (!caller->ConnectTo(callee.get())) {
346 return;
347 }
348 // If we manage to connect, we should get this precise fingerprint.
349 caller->pc()->Close();
350 callee->pc()->Close();
351 int expected_fingerprint = MakeUsageFingerprint(
352 {PeerConnection::UsageEvent::AUDIO_ADDED,
353 PeerConnection::UsageEvent::VIDEO_ADDED,
354 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
355 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
356 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
357 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
358 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
359 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200360 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
361 EXPECT_EQ(
362 2, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200363}
364
365#ifdef HAVE_SCTP
366TEST_F(PeerConnectionUsageHistogramTest, FingerprintDataOnly) {
367 auto caller = CreatePeerConnection();
368 auto callee = CreatePeerConnection();
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200369 caller->CreateDataChannel("foodata");
Harald Alvestrand42386282018-07-12 07:56:05 +0200370 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200371 ASSERT_TRUE_WAIT(callee->HaveDataChannel(), kDefaultTimeout);
372 caller->pc()->Close();
373 callee->pc()->Close();
374 int expected_fingerprint = MakeUsageFingerprint(
375 {PeerConnection::UsageEvent::DATA_ADDED,
376 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
377 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
378 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
379 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
380 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
381 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200382 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200383 EXPECT_TRUE(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200384 webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint) ==
385 2 ||
Harald Alvestrand056d8112018-07-16 19:18:58 +0200386 webrtc::metrics::NumEvents(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200387 kUsagePatternMetric,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200388 expected_fingerprint |
389 static_cast<int>(
390 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
391 2);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200392}
393#endif // HAVE_SCTP
394#endif // WEBRTC_ANDROID
395
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200396TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurn) {
397 RTCConfiguration configuration;
398 PeerConnection::IceServer server;
399 server.urls = {"stun:dummy.stun.server/"};
400 configuration.servers.push_back(server);
401 server.urls = {"turn:dummy.turn.server/"};
402 server.username = "username";
403 server.password = "password";
404 configuration.servers.push_back(server);
405 auto caller = CreatePeerConnection(configuration);
406 ASSERT_TRUE(caller);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200407 caller->pc()->Close();
408 int expected_fingerprint =
409 MakeUsageFingerprint({PeerConnection::UsageEvent::STUN_SERVER_ADDED,
410 PeerConnection::UsageEvent::TURN_SERVER_ADDED,
411 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200412 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
413 EXPECT_EQ(
414 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200415}
416
417TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurnInReconfiguration) {
418 RTCConfiguration configuration;
419 PeerConnection::IceServer server;
420 server.urls = {"stun:dummy.stun.server/"};
421 configuration.servers.push_back(server);
422 server.urls = {"turn:dummy.turn.server/"};
423 server.username = "username";
424 server.password = "password";
425 configuration.servers.push_back(server);
426 auto caller = CreatePeerConnection();
427 ASSERT_TRUE(caller);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200428 RTCError error;
429 caller->pc()->SetConfiguration(configuration, &error);
430 ASSERT_TRUE(error.ok());
431 caller->pc()->Close();
432 int expected_fingerprint =
433 MakeUsageFingerprint({PeerConnection::UsageEvent::STUN_SERVER_ADDED,
434 PeerConnection::UsageEvent::TURN_SERVER_ADDED,
435 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200436 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
437 EXPECT_EQ(
438 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200439}
440
Harald Alvestrand056d8112018-07-16 19:18:58 +0200441TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIP) {
442 auto caller = CreatePeerConnectionWithPrivateLocalAddresses();
443 caller->AddAudioTrack("audio");
444 ASSERT_TRUE(caller->GenerateOfferAndCollectCandidates());
445 caller->pc()->Close();
446 int expected_fingerprint = MakeUsageFingerprint(
447 {PeerConnection::UsageEvent::AUDIO_ADDED,
448 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
449 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
450 PeerConnection::UsageEvent::CLOSE_CALLED,
451 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200452 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
453 EXPECT_EQ(
454 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200455}
456
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200457#ifndef WEBRTC_ANDROID
458#ifdef HAVE_SCTP
459TEST_F(PeerConnectionUsageHistogramTest, NotableUsageNoted) {
460 auto caller = CreatePeerConnection();
461 caller->CreateDataChannel("foo");
462 caller->GenerateOfferAndCollectCandidates();
463 caller->pc()->Close();
464 int expected_fingerprint = MakeUsageFingerprint(
465 {PeerConnection::UsageEvent::DATA_ADDED,
466 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
467 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
468 PeerConnection::UsageEvent::CLOSE_CALLED});
469 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
470 EXPECT_TRUE(expected_fingerprint == ObservedFingerprint() ||
471 (expected_fingerprint |
472 static_cast<int>(
473 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
474 ObservedFingerprint());
475 EXPECT_EQ(absl::make_optional(ObservedFingerprint()),
476 caller->observer()->interesting_usage_detected());
477}
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200478
479TEST_F(PeerConnectionUsageHistogramTest, NotableUsageOnEventFiring) {
480 auto caller = CreatePeerConnection();
481 caller->CreateDataChannel("foo");
482 caller->GenerateOfferAndCollectCandidates();
483 int expected_fingerprint = MakeUsageFingerprint(
484 {PeerConnection::UsageEvent::DATA_ADDED,
485 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
486 PeerConnection::UsageEvent::CANDIDATE_COLLECTED});
487 EXPECT_EQ(0, webrtc::metrics::NumSamples(kUsagePatternMetric));
488 caller->GetInternalPeerConnection()->RequestUsagePatternReportForTesting();
489 EXPECT_EQ_WAIT(1, webrtc::metrics::NumSamples(kUsagePatternMetric),
490 kDefaultTimeout);
491 EXPECT_TRUE(expected_fingerprint == ObservedFingerprint() ||
492 (expected_fingerprint |
493 static_cast<int>(
494 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
495 ObservedFingerprint());
496 EXPECT_EQ(absl::make_optional(ObservedFingerprint()),
497 caller->observer()->interesting_usage_detected());
498}
499
500TEST_F(PeerConnectionUsageHistogramTest,
501 NoNotableUsageOnEventFiringAfterClose) {
502 auto caller = CreatePeerConnection();
503 caller->CreateDataChannel("foo");
504 caller->GenerateOfferAndCollectCandidates();
505 int expected_fingerprint = MakeUsageFingerprint(
506 {PeerConnection::UsageEvent::DATA_ADDED,
507 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
508 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
509 PeerConnection::UsageEvent::CLOSE_CALLED});
510 EXPECT_EQ(0, webrtc::metrics::NumSamples(kUsagePatternMetric));
511 caller->pc()->Close();
512 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
513 caller->GetInternalPeerConnection()->RequestUsagePatternReportForTesting();
514 caller->observer()->ClearInterestingUsageDetector();
515 EXPECT_EQ_WAIT(2, webrtc::metrics::NumSamples(kUsagePatternMetric),
516 kDefaultTimeout);
517 EXPECT_TRUE(expected_fingerprint == ObservedFingerprint() ||
518 (expected_fingerprint |
519 static_cast<int>(
520 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
521 ObservedFingerprint());
522 // After close, the usage-detection callback should NOT have been called.
523 EXPECT_FALSE(caller->observer()->interesting_usage_detected());
524}
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200525#endif
526#endif
527
Harald Alvestrand19793842018-06-25 12:03:50 +0200528} // namespace webrtc