blob: f1203e4cb49c1e8d7674ace5fcc0b54047d13508 [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
11#include <tuple>
12
Karl Wiberg918f50c2018-07-05 11:40:33 +020013#include "absl/memory/memory.h"
Harald Alvestrand42386282018-07-12 07:56:05 +020014#include "api/jsep.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020015#include "api/peerconnectionproxy.h"
16#include "media/base/fakemediaengine.h"
Harald Alvestrand056d8112018-07-16 19:18:58 +020017#include "p2p/client/basicportallocator.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020018#include "pc/mediasession.h"
19#include "pc/peerconnection.h"
20#include "pc/peerconnectionfactory.h"
21#include "pc/peerconnectionwrapper.h"
22#include "pc/sdputils.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020023#include "pc/test/fakesctptransport.h"
Harald Alvestrand056d8112018-07-16 19:18:58 +020024#include "rtc_base/fakenetwork.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020025#include "rtc_base/gunit.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020026#include "rtc_base/virtualsocketserver.h"
Qingsi Wang7fc821d2018-07-12 12:54:53 -070027#include "system_wrappers/include/metrics_default.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020028
29namespace webrtc {
30
31using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
32using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
33using ::testing::Values;
34
Harald Alvestrandc0e97252018-07-26 10:39:55 +020035static const char kUsagePatternMetric[] = "WebRTC.PeerConnection.UsagePattern";
Harald Alvestrand19793842018-06-25 12:03:50 +020036static constexpr int kDefaultTimeout = 10000;
Harald Alvestrand056d8112018-07-16 19:18:58 +020037static const rtc::SocketAddress kDefaultLocalAddress("1.1.1.1", 0);
38static const rtc::SocketAddress kPrivateLocalAddress("10.1.1.1", 0);
Harald Alvestrand19793842018-06-25 12:03:50 +020039
40int MakeUsageFingerprint(std::set<PeerConnection::UsageEvent> events) {
41 int signature = 0;
42 for (const auto it : events) {
43 signature |= static_cast<int>(it);
44 }
45 return signature;
46}
47
48class PeerConnectionFactoryForUsageHistogramTest
49 : public rtc::RefCountedObject<PeerConnectionFactory> {
50 public:
51 PeerConnectionFactoryForUsageHistogramTest()
52 : rtc::RefCountedObject<PeerConnectionFactory>(
53 rtc::Thread::Current(),
54 rtc::Thread::Current(),
55 rtc::Thread::Current(),
Karl Wiberg918f50c2018-07-05 11:40:33 +020056 absl::make_unique<cricket::FakeMediaEngine>(),
Harald Alvestrand19793842018-06-25 12:03:50 +020057 CreateCallFactory(),
58 nullptr) {}
59
60 void ActionsBeforeInitializeForTesting(PeerConnectionInterface* pc) override {
61 PeerConnection* internal_pc = static_cast<PeerConnection*>(pc);
62 if (return_histogram_very_quickly_) {
63 internal_pc->ReturnHistogramVeryQuicklyForTesting();
64 }
65 }
66
67 void ReturnHistogramVeryQuickly() { return_histogram_very_quickly_ = true; }
68
69 private:
Harald Alvestrand183e09d2018-06-28 12:04:41 +020070 bool return_histogram_very_quickly_ = false;
71};
72
73class PeerConnectionWrapperForUsageHistogramTest;
74typedef PeerConnectionWrapperForUsageHistogramTest* RawWrapperPtr;
75
76class ObserverForUsageHistogramTest : public MockPeerConnectionObserver {
77 public:
78 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override;
Harald Alvestrandc0e97252018-07-26 10:39:55 +020079
80 void OnInterestingUsage(int usage_pattern) override {
81 interesting_usage_detected_ = usage_pattern;
82 }
83
Harald Alvestrand183e09d2018-06-28 12:04:41 +020084 void PrepareToExchangeCandidates(RawWrapperPtr other) {
85 candidate_target_ = other;
86 }
Harald Alvestrandc0e97252018-07-26 10:39:55 +020087
Harald Alvestrand183e09d2018-06-28 12:04:41 +020088 bool HaveDataChannel() { return last_datachannel_; }
89
Harald Alvestrandc0e97252018-07-26 10:39:55 +020090 absl::optional<int> interesting_usage_detected() {
91 return interesting_usage_detected_;
92 }
93
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +020094 void ClearInterestingUsageDetector() {
95 interesting_usage_detected_ = absl::optional<int>();
96 }
97
Harald Alvestrand183e09d2018-06-28 12:04:41 +020098 private:
Harald Alvestrandc0e97252018-07-26 10:39:55 +020099 absl::optional<int> interesting_usage_detected_;
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200100 RawWrapperPtr candidate_target_; // Note: Not thread-safe against deletions.
Harald Alvestrand19793842018-06-25 12:03:50 +0200101};
102
103class PeerConnectionWrapperForUsageHistogramTest
104 : public PeerConnectionWrapper {
105 public:
106 using PeerConnectionWrapper::PeerConnectionWrapper;
107
108 PeerConnection* GetInternalPeerConnection() {
109 auto* pci =
110 static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
111 pc());
112 return static_cast<PeerConnection*>(pci->internal());
113 }
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200114
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200115 // Override with different return type
116 ObserverForUsageHistogramTest* observer() {
117 return static_cast<ObserverForUsageHistogramTest*>(
118 PeerConnectionWrapper::observer());
119 }
120
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200121 void PrepareToExchangeCandidates(
122 PeerConnectionWrapperForUsageHistogramTest* other) {
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200123 observer()->PrepareToExchangeCandidates(other);
124 other->observer()->PrepareToExchangeCandidates(this);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200125 }
126
127 bool IsConnected() {
128 return pc()->ice_connection_state() ==
129 PeerConnectionInterface::kIceConnectionConnected ||
130 pc()->ice_connection_state() ==
131 PeerConnectionInterface::kIceConnectionCompleted;
132 }
133
134 bool HaveDataChannel() {
135 return static_cast<ObserverForUsageHistogramTest*>(observer())
136 ->HaveDataChannel();
137 }
Harald Alvestrand42386282018-07-12 07:56:05 +0200138 void AddOrBufferIceCandidate(const webrtc::IceCandidateInterface* candidate) {
139 if (!pc()->AddIceCandidate(candidate)) {
140 std::string sdp;
141 EXPECT_TRUE(candidate->ToString(&sdp));
142 std::unique_ptr<webrtc::IceCandidateInterface> candidate_copy(
143 CreateIceCandidate(candidate->sdp_mid(), candidate->sdp_mline_index(),
144 sdp, nullptr));
145 buffered_candidates_.push_back(std::move(candidate_copy));
146 }
147 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200148
Harald Alvestrand42386282018-07-12 07:56:05 +0200149 void AddBufferedIceCandidates() {
150 for (const auto& candidate : buffered_candidates_) {
151 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
152 }
153 buffered_candidates_.clear();
154 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200155
Harald Alvestrand42386282018-07-12 07:56:05 +0200156 bool ConnectTo(PeerConnectionWrapperForUsageHistogramTest* callee) {
157 PrepareToExchangeCandidates(callee);
Harald Alvestrand056d8112018-07-16 19:18:58 +0200158 if (!ExchangeOfferAnswerWith(callee)) {
159 return false;
160 }
Harald Alvestrand42386282018-07-12 07:56:05 +0200161 AddBufferedIceCandidates();
162 callee->AddBufferedIceCandidates();
Harald Alvestrand056d8112018-07-16 19:18:58 +0200163 WAIT(IsConnected(), kDefaultTimeout);
164 WAIT(callee->IsConnected(), kDefaultTimeout);
Harald Alvestrand42386282018-07-12 07:56:05 +0200165 return IsConnected() && callee->IsConnected();
166 }
167
Harald Alvestrand056d8112018-07-16 19:18:58 +0200168 bool GenerateOfferAndCollectCandidates() {
169 auto offer = CreateOffer(RTCOfferAnswerOptions());
170 if (!offer) {
171 return false;
172 }
173 bool set_local_offer =
174 SetLocalDescription(CloneSessionDescription(offer.get()));
175 EXPECT_TRUE(set_local_offer);
176 if (!set_local_offer) {
177 return false;
178 }
179 EXPECT_TRUE_WAIT(observer()->ice_gathering_complete_, kDefaultTimeout);
180 return true;
181 }
182
Harald Alvestrand42386282018-07-12 07:56:05 +0200183 private:
184 // Candidates that have been sent but not yet configured
185 std::vector<std::unique_ptr<webrtc::IceCandidateInterface>>
186 buffered_candidates_;
Harald Alvestrand19793842018-06-25 12:03:50 +0200187};
188
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200189void ObserverForUsageHistogramTest::OnIceCandidate(
190 const webrtc::IceCandidateInterface* candidate) {
191 if (candidate_target_) {
Harald Alvestrand42386282018-07-12 07:56:05 +0200192 this->candidate_target_->AddOrBufferIceCandidate(candidate);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200193 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200194 // If target is not set, ignore. This happens in one-ended unit tests.
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200195}
196
Harald Alvestrand19793842018-06-25 12:03:50 +0200197class PeerConnectionUsageHistogramTest : public ::testing::Test {
198 protected:
199 typedef std::unique_ptr<PeerConnectionWrapperForUsageHistogramTest>
200 WrapperPtr;
201
202 PeerConnectionUsageHistogramTest()
203 : vss_(new rtc::VirtualSocketServer()), main_(vss_.get()) {
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700204 webrtc::metrics::Reset();
Harald Alvestrand19793842018-06-25 12:03:50 +0200205 }
206
207 WrapperPtr CreatePeerConnection() {
Harald Alvestrand056d8112018-07-16 19:18:58 +0200208 return CreatePeerConnection(RTCConfiguration(),
209 PeerConnectionFactoryInterface::Options(),
210 nullptr, false);
Harald Alvestrand19793842018-06-25 12:03:50 +0200211 }
212
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200213 WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
214 return CreatePeerConnection(
Harald Alvestrand056d8112018-07-16 19:18:58 +0200215 config, PeerConnectionFactoryInterface::Options(), nullptr, false);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200216 }
217
Harald Alvestrand19793842018-06-25 12:03:50 +0200218 WrapperPtr CreatePeerConnectionWithImmediateReport() {
Harald Alvestrand056d8112018-07-16 19:18:58 +0200219 return CreatePeerConnection(RTCConfiguration(),
220 PeerConnectionFactoryInterface::Options(),
221 nullptr, true);
222 }
223
224 WrapperPtr CreatePeerConnectionWithPrivateLocalAddresses() {
225 fake_network_manager_.reset(new rtc::FakeNetworkManager());
226 fake_network_manager_->AddInterface(kDefaultLocalAddress);
227 fake_network_manager_->AddInterface(kPrivateLocalAddress);
228 std::unique_ptr<cricket::BasicPortAllocator> port_allocator(
229 new cricket::BasicPortAllocator(fake_network_manager_.get()));
230 return CreatePeerConnection(RTCConfiguration(),
231 PeerConnectionFactoryInterface::Options(),
232 std::move(port_allocator), false);
Harald Alvestrand19793842018-06-25 12:03:50 +0200233 }
234
235 WrapperPtr CreatePeerConnection(
236 const RTCConfiguration& config,
237 const PeerConnectionFactoryInterface::Options factory_options,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200238 std::unique_ptr<cricket::PortAllocator> allocator,
Harald Alvestrand19793842018-06-25 12:03:50 +0200239 bool immediate_report) {
240 rtc::scoped_refptr<PeerConnectionFactoryForUsageHistogramTest> pc_factory(
241 new PeerConnectionFactoryForUsageHistogramTest());
242 pc_factory->SetOptions(factory_options);
243 RTC_CHECK(pc_factory->Initialize());
244 if (immediate_report) {
245 pc_factory->ReturnHistogramVeryQuickly();
246 }
Karl Wiberg918f50c2018-07-05 11:40:33 +0200247 auto observer = absl::make_unique<ObserverForUsageHistogramTest>();
Harald Alvestrand056d8112018-07-16 19:18:58 +0200248 auto pc = pc_factory->CreatePeerConnection(config, std::move(allocator),
249 nullptr, observer.get());
Harald Alvestrand19793842018-06-25 12:03:50 +0200250 if (!pc) {
251 return nullptr;
252 }
253
Karl Wiberg918f50c2018-07-05 11:40:33 +0200254 auto wrapper =
255 absl::make_unique<PeerConnectionWrapperForUsageHistogramTest>(
256 pc_factory, pc, std::move(observer));
Harald Alvestrand19793842018-06-25 12:03:50 +0200257 return wrapper;
258 }
259
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200260 int ObservedFingerprint() {
261 // This works correctly only if there is only one sample value
262 // that has been counted.
263 // Returns -1 for "not found".
264 return webrtc::metrics::MinSample(kUsagePatternMetric);
265 }
266
Harald Alvestrand056d8112018-07-16 19:18:58 +0200267 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
Harald Alvestrand19793842018-06-25 12:03:50 +0200268 std::unique_ptr<rtc::VirtualSocketServer> vss_;
269 rtc::AutoSocketServerThread main_;
270};
271
272TEST_F(PeerConnectionUsageHistogramTest, UsageFingerprintHistogramFromTimeout) {
273 auto pc = CreatePeerConnectionWithImmediateReport();
274
Harald Alvestrand19793842018-06-25 12:03:50 +0200275 int expected_fingerprint = MakeUsageFingerprint({});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200276 ASSERT_EQ_WAIT(1, webrtc::metrics::NumSamples(kUsagePatternMetric),
277 kDefaultTimeout);
278 EXPECT_EQ(
279 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrand19793842018-06-25 12:03:50 +0200280}
281
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200282#ifndef WEBRTC_ANDROID
283// These tests do not work on Android. Why is unclear.
284// https://bugs.webrtc.org/9461
285
286// Test getting the usage fingerprint for an audio/video connection.
287TEST_F(PeerConnectionUsageHistogramTest, FingerprintAudioVideo) {
288 auto caller = CreatePeerConnection();
289 auto callee = CreatePeerConnection();
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200290 caller->AddAudioTrack("audio");
291 caller->AddVideoTrack("video");
Harald Alvestrand42386282018-07-12 07:56:05 +0200292 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200293 caller->pc()->Close();
294 callee->pc()->Close();
295 int expected_fingerprint = MakeUsageFingerprint(
296 {PeerConnection::UsageEvent::AUDIO_ADDED,
297 PeerConnection::UsageEvent::VIDEO_ADDED,
298 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
299 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
300 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
301 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
302 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
303 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrand056d8112018-07-16 19:18:58 +0200304 // In this case, we may or may not have PRIVATE_CANDIDATE_COLLECTED,
305 // depending on the machine configuration.
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200306 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200307 EXPECT_TRUE(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200308 webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint) ==
309 2 ||
Harald Alvestrand056d8112018-07-16 19:18:58 +0200310 webrtc::metrics::NumEvents(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200311 kUsagePatternMetric,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200312 expected_fingerprint |
313 static_cast<int>(
314 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
315 2);
316}
317
318// Test getting the usage fingerprint when there are no host candidates.
319TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithNoHostCandidates) {
320 RTCConfiguration config;
321 config.type = PeerConnectionInterface::kNoHost;
322 auto caller = CreatePeerConnection(config);
323 auto callee = CreatePeerConnection(config);
324 caller->AddAudioTrack("audio");
325 caller->AddVideoTrack("video");
326 // Under some bot configurations, this will fail - presumably bots where
327 // no working non-host addresses exist.
328 if (!caller->ConnectTo(callee.get())) {
329 return;
330 }
331 // If we manage to connect, we should get this precise fingerprint.
332 caller->pc()->Close();
333 callee->pc()->Close();
334 int expected_fingerprint = MakeUsageFingerprint(
335 {PeerConnection::UsageEvent::AUDIO_ADDED,
336 PeerConnection::UsageEvent::VIDEO_ADDED,
337 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
338 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
339 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
340 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
341 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
342 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200343 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
344 EXPECT_EQ(
345 2, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200346}
347
348#ifdef HAVE_SCTP
349TEST_F(PeerConnectionUsageHistogramTest, FingerprintDataOnly) {
350 auto caller = CreatePeerConnection();
351 auto callee = CreatePeerConnection();
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200352 caller->CreateDataChannel("foodata");
Harald Alvestrand42386282018-07-12 07:56:05 +0200353 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200354 ASSERT_TRUE_WAIT(callee->HaveDataChannel(), kDefaultTimeout);
355 caller->pc()->Close();
356 callee->pc()->Close();
357 int expected_fingerprint = MakeUsageFingerprint(
358 {PeerConnection::UsageEvent::DATA_ADDED,
359 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
360 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
361 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
362 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
363 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
364 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200365 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200366 EXPECT_TRUE(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200367 webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint) ==
368 2 ||
Harald Alvestrand056d8112018-07-16 19:18:58 +0200369 webrtc::metrics::NumEvents(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200370 kUsagePatternMetric,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200371 expected_fingerprint |
372 static_cast<int>(
373 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
374 2);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200375}
376#endif // HAVE_SCTP
377#endif // WEBRTC_ANDROID
378
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200379TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurn) {
380 RTCConfiguration configuration;
381 PeerConnection::IceServer server;
382 server.urls = {"stun:dummy.stun.server/"};
383 configuration.servers.push_back(server);
384 server.urls = {"turn:dummy.turn.server/"};
385 server.username = "username";
386 server.password = "password";
387 configuration.servers.push_back(server);
388 auto caller = CreatePeerConnection(configuration);
389 ASSERT_TRUE(caller);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200390 caller->pc()->Close();
391 int expected_fingerprint =
392 MakeUsageFingerprint({PeerConnection::UsageEvent::STUN_SERVER_ADDED,
393 PeerConnection::UsageEvent::TURN_SERVER_ADDED,
394 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200395 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
396 EXPECT_EQ(
397 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200398}
399
400TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurnInReconfiguration) {
401 RTCConfiguration configuration;
402 PeerConnection::IceServer server;
403 server.urls = {"stun:dummy.stun.server/"};
404 configuration.servers.push_back(server);
405 server.urls = {"turn:dummy.turn.server/"};
406 server.username = "username";
407 server.password = "password";
408 configuration.servers.push_back(server);
409 auto caller = CreatePeerConnection();
410 ASSERT_TRUE(caller);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200411 RTCError error;
412 caller->pc()->SetConfiguration(configuration, &error);
413 ASSERT_TRUE(error.ok());
414 caller->pc()->Close();
415 int expected_fingerprint =
416 MakeUsageFingerprint({PeerConnection::UsageEvent::STUN_SERVER_ADDED,
417 PeerConnection::UsageEvent::TURN_SERVER_ADDED,
418 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200419 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
420 EXPECT_EQ(
421 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200422}
423
Harald Alvestrand056d8112018-07-16 19:18:58 +0200424TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIP) {
425 auto caller = CreatePeerConnectionWithPrivateLocalAddresses();
426 caller->AddAudioTrack("audio");
427 ASSERT_TRUE(caller->GenerateOfferAndCollectCandidates());
428 caller->pc()->Close();
429 int expected_fingerprint = MakeUsageFingerprint(
430 {PeerConnection::UsageEvent::AUDIO_ADDED,
431 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
432 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
433 PeerConnection::UsageEvent::CLOSE_CALLED,
434 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200435 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
436 EXPECT_EQ(
437 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200438}
439
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200440#ifndef WEBRTC_ANDROID
441#ifdef HAVE_SCTP
442TEST_F(PeerConnectionUsageHistogramTest, NotableUsageNoted) {
443 auto caller = CreatePeerConnection();
444 caller->CreateDataChannel("foo");
445 caller->GenerateOfferAndCollectCandidates();
446 caller->pc()->Close();
447 int expected_fingerprint = MakeUsageFingerprint(
448 {PeerConnection::UsageEvent::DATA_ADDED,
449 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
450 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
451 PeerConnection::UsageEvent::CLOSE_CALLED});
452 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
453 EXPECT_TRUE(expected_fingerprint == ObservedFingerprint() ||
454 (expected_fingerprint |
455 static_cast<int>(
456 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
457 ObservedFingerprint());
458 EXPECT_EQ(absl::make_optional(ObservedFingerprint()),
459 caller->observer()->interesting_usage_detected());
460}
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200461
462TEST_F(PeerConnectionUsageHistogramTest, NotableUsageOnEventFiring) {
463 auto caller = CreatePeerConnection();
464 caller->CreateDataChannel("foo");
465 caller->GenerateOfferAndCollectCandidates();
466 int expected_fingerprint = MakeUsageFingerprint(
467 {PeerConnection::UsageEvent::DATA_ADDED,
468 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
469 PeerConnection::UsageEvent::CANDIDATE_COLLECTED});
470 EXPECT_EQ(0, webrtc::metrics::NumSamples(kUsagePatternMetric));
471 caller->GetInternalPeerConnection()->RequestUsagePatternReportForTesting();
472 EXPECT_EQ_WAIT(1, webrtc::metrics::NumSamples(kUsagePatternMetric),
473 kDefaultTimeout);
474 EXPECT_TRUE(expected_fingerprint == ObservedFingerprint() ||
475 (expected_fingerprint |
476 static_cast<int>(
477 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
478 ObservedFingerprint());
479 EXPECT_EQ(absl::make_optional(ObservedFingerprint()),
480 caller->observer()->interesting_usage_detected());
481}
482
483TEST_F(PeerConnectionUsageHistogramTest,
484 NoNotableUsageOnEventFiringAfterClose) {
485 auto caller = CreatePeerConnection();
486 caller->CreateDataChannel("foo");
487 caller->GenerateOfferAndCollectCandidates();
488 int expected_fingerprint = MakeUsageFingerprint(
489 {PeerConnection::UsageEvent::DATA_ADDED,
490 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
491 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
492 PeerConnection::UsageEvent::CLOSE_CALLED});
493 EXPECT_EQ(0, webrtc::metrics::NumSamples(kUsagePatternMetric));
494 caller->pc()->Close();
495 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
496 caller->GetInternalPeerConnection()->RequestUsagePatternReportForTesting();
497 caller->observer()->ClearInterestingUsageDetector();
498 EXPECT_EQ_WAIT(2, webrtc::metrics::NumSamples(kUsagePatternMetric),
499 kDefaultTimeout);
500 EXPECT_TRUE(expected_fingerprint == ObservedFingerprint() ||
501 (expected_fingerprint |
502 static_cast<int>(
503 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
504 ObservedFingerprint());
505 // After close, the usage-detection callback should NOT have been called.
506 EXPECT_FALSE(caller->observer()->interesting_usage_detected());
507}
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200508#endif
509#endif
510
Harald Alvestrand19793842018-06-25 12:03:50 +0200511} // namespace webrtc