blob: bdf69942db9538b6d9d73e04e78f5990fbdbcde0 [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"
Qingsi Wang1ba5dec2019-08-19 11:57:17 -070021#include "api/jsep_session_description.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "api/peer_connection_interface.h"
23#include "api/peer_connection_proxy.h"
24#include "api/rtc_error.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010025#include "api/scoped_refptr.h"
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020026#include "api/task_queue/default_task_queue_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080027#include "media/base/fake_media_engine.h"
Jeroen de Borstaf242c82019-04-24 13:13:48 -070028#include "p2p/base/mock_async_resolver.h"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "p2p/base/port_allocator.h"
30#include "p2p/client/basic_port_allocator.h"
31#include "pc/peer_connection.h"
32#include "pc/peer_connection_factory.h"
33#include "pc/peer_connection_wrapper.h"
34#include "pc/sdp_utils.h"
35#include "pc/test/mock_peer_connection_observers.h"
Qingsi Wang1ba5dec2019-08-19 11:57:17 -070036#include "pc/webrtc_sdp.h"
Jeroen de Borstaf242c82019-04-24 13:13:48 -070037#include "rtc_base/arraysize.h"
Yves Gerey3e707812018-11-28 16:47:49 +010038#include "rtc_base/checks.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070039#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080040#include "rtc_base/fake_network.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020041#include "rtc_base/gunit.h"
Steve Anton10542f22019-01-11 09:11:00 -080042#include "rtc_base/ref_counted_object.h"
43#include "rtc_base/rtc_certificate_generator.h"
Steve Anton10542f22019-01-11 09:11:00 -080044#include "rtc_base/socket_address.h"
Yves Gerey3e707812018-11-28 16:47:49 +010045#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080046#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020047#include "system_wrappers/include/metrics.h"
Jeroen de Borstaf242c82019-04-24 13:13:48 -070048#include "test/gmock.h"
Harald Alvestrand19793842018-06-25 12:03:50 +020049
50namespace webrtc {
51
52using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
53using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
Jeroen de Borstaf242c82019-04-24 13:13:48 -070054using ::testing::NiceMock;
Harald Alvestrand19793842018-06-25 12:03:50 +020055using ::testing::Values;
56
Harald Alvestrandc0e97252018-07-26 10:39:55 +020057static const char kUsagePatternMetric[] = "WebRTC.PeerConnection.UsagePattern";
Harald Alvestrand19793842018-06-25 12:03:50 +020058static constexpr int kDefaultTimeout = 10000;
Jeroen de Borstaf242c82019-04-24 13:13:48 -070059static const rtc::SocketAddress kLocalAddrs[2] = {
60 rtc::SocketAddress("1.1.1.1", 0), rtc::SocketAddress("2.2.2.2", 0)};
Harald Alvestrand056d8112018-07-16 19:18:58 +020061static const rtc::SocketAddress kPrivateLocalAddress("10.1.1.1", 0);
Qingsi Wang1ba5dec2019-08-19 11:57:17 -070062static const rtc::SocketAddress kPrivateIpv6LocalAddress("fd12:3456:789a:1::1",
63 0);
Harald Alvestrand19793842018-06-25 12:03:50 +020064
65int MakeUsageFingerprint(std::set<PeerConnection::UsageEvent> events) {
66 int signature = 0;
67 for (const auto it : events) {
68 signature |= static_cast<int>(it);
69 }
70 return signature;
71}
72
73class PeerConnectionFactoryForUsageHistogramTest
74 : public rtc::RefCountedObject<PeerConnectionFactory> {
75 public:
76 PeerConnectionFactoryForUsageHistogramTest()
Danil Chapovalovf5258be2019-03-19 17:45:24 +010077 : rtc::RefCountedObject<PeerConnectionFactory>([] {
78 PeerConnectionFactoryDependencies dependencies;
79 dependencies.network_thread = rtc::Thread::Current();
80 dependencies.worker_thread = rtc::Thread::Current();
81 dependencies.signaling_thread = rtc::Thread::Current();
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020082 dependencies.task_queue_factory = CreateDefaultTaskQueueFactory();
Danil Chapovalovf5258be2019-03-19 17:45:24 +010083 dependencies.media_engine =
84 absl::make_unique<cricket::FakeMediaEngine>();
85 dependencies.call_factory = CreateCallFactory();
86 return dependencies;
87 }()) {}
Harald Alvestrand19793842018-06-25 12:03:50 +020088
89 void ActionsBeforeInitializeForTesting(PeerConnectionInterface* pc) override {
90 PeerConnection* internal_pc = static_cast<PeerConnection*>(pc);
91 if (return_histogram_very_quickly_) {
92 internal_pc->ReturnHistogramVeryQuicklyForTesting();
93 }
94 }
95
96 void ReturnHistogramVeryQuickly() { return_histogram_very_quickly_ = true; }
97
98 private:
Harald Alvestrand183e09d2018-06-28 12:04:41 +020099 bool return_histogram_very_quickly_ = false;
100};
101
102class PeerConnectionWrapperForUsageHistogramTest;
Yves Gerey3e707812018-11-28 16:47:49 +0100103
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200104typedef PeerConnectionWrapperForUsageHistogramTest* RawWrapperPtr;
105
106class ObserverForUsageHistogramTest : public MockPeerConnectionObserver {
107 public:
108 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override;
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200109
110 void OnInterestingUsage(int usage_pattern) override {
111 interesting_usage_detected_ = usage_pattern;
112 }
113
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200114 void PrepareToExchangeCandidates(RawWrapperPtr other) {
115 candidate_target_ = other;
116 }
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200117
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200118 bool HaveDataChannel() { return last_datachannel_; }
119
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200120 absl::optional<int> interesting_usage_detected() {
121 return interesting_usage_detected_;
122 }
123
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200124 void ClearInterestingUsageDetector() {
125 interesting_usage_detected_ = absl::optional<int>();
126 }
127
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700128 bool candidate_gathered() const { return candidate_gathered_; }
129
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200130 private:
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200131 absl::optional<int> interesting_usage_detected_;
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700132 bool candidate_gathered_ = false;
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200133 RawWrapperPtr candidate_target_; // Note: Not thread-safe against deletions.
Harald Alvestrand19793842018-06-25 12:03:50 +0200134};
135
136class PeerConnectionWrapperForUsageHistogramTest
137 : public PeerConnectionWrapper {
138 public:
139 using PeerConnectionWrapper::PeerConnectionWrapper;
140
141 PeerConnection* GetInternalPeerConnection() {
142 auto* pci =
143 static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
144 pc());
145 return static_cast<PeerConnection*>(pci->internal());
146 }
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200147
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200148 // Override with different return type
149 ObserverForUsageHistogramTest* observer() {
150 return static_cast<ObserverForUsageHistogramTest*>(
151 PeerConnectionWrapper::observer());
152 }
153
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200154 void PrepareToExchangeCandidates(
155 PeerConnectionWrapperForUsageHistogramTest* other) {
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200156 observer()->PrepareToExchangeCandidates(other);
157 other->observer()->PrepareToExchangeCandidates(this);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200158 }
159
160 bool IsConnected() {
161 return pc()->ice_connection_state() ==
162 PeerConnectionInterface::kIceConnectionConnected ||
163 pc()->ice_connection_state() ==
164 PeerConnectionInterface::kIceConnectionCompleted;
165 }
166
167 bool HaveDataChannel() {
168 return static_cast<ObserverForUsageHistogramTest*>(observer())
169 ->HaveDataChannel();
170 }
Harald Alvestrand42386282018-07-12 07:56:05 +0200171 void AddOrBufferIceCandidate(const webrtc::IceCandidateInterface* candidate) {
172 if (!pc()->AddIceCandidate(candidate)) {
173 std::string sdp;
174 EXPECT_TRUE(candidate->ToString(&sdp));
175 std::unique_ptr<webrtc::IceCandidateInterface> candidate_copy(
176 CreateIceCandidate(candidate->sdp_mid(), candidate->sdp_mline_index(),
177 sdp, nullptr));
178 buffered_candidates_.push_back(std::move(candidate_copy));
179 }
180 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200181
Harald Alvestrand42386282018-07-12 07:56:05 +0200182 void AddBufferedIceCandidates() {
183 for (const auto& candidate : buffered_candidates_) {
184 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
185 }
186 buffered_candidates_.clear();
187 }
Harald Alvestrand056d8112018-07-16 19:18:58 +0200188
Harald Alvestrand42386282018-07-12 07:56:05 +0200189 bool ConnectTo(PeerConnectionWrapperForUsageHistogramTest* callee) {
190 PrepareToExchangeCandidates(callee);
Harald Alvestrand056d8112018-07-16 19:18:58 +0200191 if (!ExchangeOfferAnswerWith(callee)) {
192 return false;
193 }
Harald Alvestrand42386282018-07-12 07:56:05 +0200194 AddBufferedIceCandidates();
195 callee->AddBufferedIceCandidates();
Harald Alvestrand056d8112018-07-16 19:18:58 +0200196 WAIT(IsConnected(), kDefaultTimeout);
197 WAIT(callee->IsConnected(), kDefaultTimeout);
Harald Alvestrand42386282018-07-12 07:56:05 +0200198 return IsConnected() && callee->IsConnected();
199 }
200
Harald Alvestrand056d8112018-07-16 19:18:58 +0200201 bool GenerateOfferAndCollectCandidates() {
202 auto offer = CreateOffer(RTCOfferAnswerOptions());
203 if (!offer) {
204 return false;
205 }
206 bool set_local_offer =
207 SetLocalDescription(CloneSessionDescription(offer.get()));
208 EXPECT_TRUE(set_local_offer);
209 if (!set_local_offer) {
210 return false;
211 }
212 EXPECT_TRUE_WAIT(observer()->ice_gathering_complete_, kDefaultTimeout);
213 return true;
214 }
215
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700216 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() {
217 return pc()->ice_gathering_state();
218 }
219
Harald Alvestrand42386282018-07-12 07:56:05 +0200220 private:
221 // Candidates that have been sent but not yet configured
222 std::vector<std::unique_ptr<webrtc::IceCandidateInterface>>
223 buffered_candidates_;
Harald Alvestrand19793842018-06-25 12:03:50 +0200224};
225
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200226void ObserverForUsageHistogramTest::OnIceCandidate(
227 const webrtc::IceCandidateInterface* candidate) {
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700228 // If target is not set, ignore. This happens in one-ended unit tests.
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200229 if (candidate_target_) {
Harald Alvestrand42386282018-07-12 07:56:05 +0200230 this->candidate_target_->AddOrBufferIceCandidate(candidate);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200231 }
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700232 candidate_gathered_ = true;
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200233}
234
Harald Alvestrand19793842018-06-25 12:03:50 +0200235class PeerConnectionUsageHistogramTest : public ::testing::Test {
236 protected:
237 typedef std::unique_ptr<PeerConnectionWrapperForUsageHistogramTest>
238 WrapperPtr;
239
240 PeerConnectionUsageHistogramTest()
241 : vss_(new rtc::VirtualSocketServer()), main_(vss_.get()) {
Qingsi Wang7fc821d2018-07-12 12:54:53 -0700242 webrtc::metrics::Reset();
Harald Alvestrand19793842018-06-25 12:03:50 +0200243 }
244
245 WrapperPtr CreatePeerConnection() {
Harald Alvestrand056d8112018-07-16 19:18:58 +0200246 return CreatePeerConnection(RTCConfiguration(),
247 PeerConnectionFactoryInterface::Options(),
248 nullptr, false);
Harald Alvestrand19793842018-06-25 12:03:50 +0200249 }
250
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200251 WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
252 return CreatePeerConnection(
Harald Alvestrand056d8112018-07-16 19:18:58 +0200253 config, PeerConnectionFactoryInterface::Options(), nullptr, false);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200254 }
255
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700256 WrapperPtr CreatePeerConnectionWithMdns(const RTCConfiguration& config) {
257 auto resolver_factory =
258 absl::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
259
260 webrtc::PeerConnectionDependencies deps(nullptr /* observer_in */);
261
262 auto fake_network = NewFakeNetwork();
Qingsi Wangecd30542019-05-22 14:34:56 -0700263 fake_network->set_mdns_responder(
264 absl::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()));
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700265 fake_network->AddInterface(NextLocalAddress());
266
267 std::unique_ptr<cricket::BasicPortAllocator> port_allocator(
268 new cricket::BasicPortAllocator(fake_network));
269
270 deps.async_resolver_factory = std::move(resolver_factory);
271 deps.allocator = std::move(port_allocator);
272
273 return CreatePeerConnection(config,
274 PeerConnectionFactoryInterface::Options(),
275 std::move(deps), false);
276 }
277
Harald Alvestrand19793842018-06-25 12:03:50 +0200278 WrapperPtr CreatePeerConnectionWithImmediateReport() {
Harald Alvestrand056d8112018-07-16 19:18:58 +0200279 return CreatePeerConnection(RTCConfiguration(),
280 PeerConnectionFactoryInterface::Options(),
281 nullptr, true);
282 }
283
284 WrapperPtr CreatePeerConnectionWithPrivateLocalAddresses() {
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700285 auto* fake_network = NewFakeNetwork();
286 fake_network->AddInterface(NextLocalAddress());
287 fake_network->AddInterface(kPrivateLocalAddress);
288
289 auto port_allocator =
290 absl::make_unique<cricket::BasicPortAllocator>(fake_network);
291
Harald Alvestrand056d8112018-07-16 19:18:58 +0200292 return CreatePeerConnection(RTCConfiguration(),
293 PeerConnectionFactoryInterface::Options(),
294 std::move(port_allocator), false);
Harald Alvestrand19793842018-06-25 12:03:50 +0200295 }
296
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700297 WrapperPtr CreatePeerConnectionWithPrivateIpv6LocalAddresses() {
298 auto* fake_network = NewFakeNetwork();
299 fake_network->AddInterface(NextLocalAddress());
300 fake_network->AddInterface(kPrivateIpv6LocalAddress);
301
302 auto port_allocator =
303 absl::make_unique<cricket::BasicPortAllocator>(fake_network);
304
305 return CreatePeerConnection(RTCConfiguration(),
306 PeerConnectionFactoryInterface::Options(),
307 std::move(port_allocator), false);
308 }
309
Harald Alvestrand19793842018-06-25 12:03:50 +0200310 WrapperPtr CreatePeerConnection(
311 const RTCConfiguration& config,
312 const PeerConnectionFactoryInterface::Options factory_options,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200313 std::unique_ptr<cricket::PortAllocator> allocator,
Harald Alvestrand19793842018-06-25 12:03:50 +0200314 bool immediate_report) {
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700315 PeerConnectionDependencies deps(nullptr);
316 deps.allocator = std::move(allocator);
317
318 return CreatePeerConnection(config, factory_options, std::move(deps),
319 immediate_report);
320 }
321
322 WrapperPtr CreatePeerConnection(
323 const RTCConfiguration& config,
324 const PeerConnectionFactoryInterface::Options factory_options,
325 PeerConnectionDependencies deps,
326 bool immediate_report) {
Harald Alvestrand19793842018-06-25 12:03:50 +0200327 rtc::scoped_refptr<PeerConnectionFactoryForUsageHistogramTest> pc_factory(
328 new PeerConnectionFactoryForUsageHistogramTest());
329 pc_factory->SetOptions(factory_options);
330 RTC_CHECK(pc_factory->Initialize());
331 if (immediate_report) {
332 pc_factory->ReturnHistogramVeryQuickly();
333 }
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700334
335 // If no allocator is provided, one will be created using a network manager
336 // that uses the host network. This doesn't work on all trybots.
337 if (!deps.allocator) {
338 auto fake_network = NewFakeNetwork();
339 fake_network->AddInterface(NextLocalAddress());
340 deps.allocator =
341 absl::make_unique<cricket::BasicPortAllocator>(fake_network);
342 }
343
Karl Wiberg918f50c2018-07-05 11:40:33 +0200344 auto observer = absl::make_unique<ObserverForUsageHistogramTest>();
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700345 deps.observer = observer.get();
346
347 auto pc = pc_factory->CreatePeerConnection(config, std::move(deps));
Harald Alvestrand19793842018-06-25 12:03:50 +0200348 if (!pc) {
349 return nullptr;
350 }
351
Yves Gerey4e933292018-10-31 15:36:05 +0100352 observer->SetPeerConnectionInterface(pc.get());
Karl Wiberg918f50c2018-07-05 11:40:33 +0200353 auto wrapper =
354 absl::make_unique<PeerConnectionWrapperForUsageHistogramTest>(
355 pc_factory, pc, std::move(observer));
Harald Alvestrand19793842018-06-25 12:03:50 +0200356 return wrapper;
357 }
358
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200359 int ObservedFingerprint() {
360 // This works correctly only if there is only one sample value
361 // that has been counted.
362 // Returns -1 for "not found".
363 return webrtc::metrics::MinSample(kUsagePatternMetric);
364 }
365
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700366 // The PeerConnection's port allocator is tied to the PeerConnection's
367 // lifetime and expects the underlying NetworkManager to outlive it. That
368 // prevents us from having the PeerConnectionWrapper own the fake network.
369 // Therefore, the test fixture will own all the fake networks even though
370 // tests should access the fake network through the PeerConnectionWrapper.
371 rtc::FakeNetworkManager* NewFakeNetwork() {
372 fake_networks_.emplace_back(absl::make_unique<rtc::FakeNetworkManager>());
373 return fake_networks_.back().get();
374 }
375
376 rtc::SocketAddress NextLocalAddress() {
377 RTC_DCHECK(next_local_address_ < (int)arraysize(kLocalAddrs));
378 return kLocalAddrs[next_local_address_++];
379 }
380
381 std::vector<std::unique_ptr<rtc::FakeNetworkManager>> fake_networks_;
382 int next_local_address_ = 0;
Harald Alvestrand19793842018-06-25 12:03:50 +0200383 std::unique_ptr<rtc::VirtualSocketServer> vss_;
384 rtc::AutoSocketServerThread main_;
385};
386
387TEST_F(PeerConnectionUsageHistogramTest, UsageFingerprintHistogramFromTimeout) {
388 auto pc = CreatePeerConnectionWithImmediateReport();
389
Harald Alvestrand19793842018-06-25 12:03:50 +0200390 int expected_fingerprint = MakeUsageFingerprint({});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200391 ASSERT_EQ_WAIT(1, webrtc::metrics::NumSamples(kUsagePatternMetric),
392 kDefaultTimeout);
393 EXPECT_EQ(
394 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrand19793842018-06-25 12:03:50 +0200395}
396
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200397#ifndef WEBRTC_ANDROID
398// These tests do not work on Android. Why is unclear.
399// https://bugs.webrtc.org/9461
400
401// Test getting the usage fingerprint for an audio/video connection.
402TEST_F(PeerConnectionUsageHistogramTest, FingerprintAudioVideo) {
403 auto caller = CreatePeerConnection();
404 auto callee = CreatePeerConnection();
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200405 caller->AddAudioTrack("audio");
406 caller->AddVideoTrack("video");
Harald Alvestrand42386282018-07-12 07:56:05 +0200407 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200408 caller->pc()->Close();
409 callee->pc()->Close();
410 int expected_fingerprint = MakeUsageFingerprint(
411 {PeerConnection::UsageEvent::AUDIO_ADDED,
412 PeerConnection::UsageEvent::VIDEO_ADDED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700413 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
414 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200415 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700416 PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200417 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700418 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200419 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrand056d8112018-07-16 19:18:58 +0200420 // In this case, we may or may not have PRIVATE_CANDIDATE_COLLECTED,
421 // depending on the machine configuration.
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200422 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200423 EXPECT_TRUE(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200424 webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint) ==
425 2 ||
Harald Alvestrand056d8112018-07-16 19:18:58 +0200426 webrtc::metrics::NumEvents(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200427 kUsagePatternMetric,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200428 expected_fingerprint |
429 static_cast<int>(
430 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
431 2);
432}
433
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700434// Test getting the usage fingerprint when the caller collects an mDNS
435// candidate.
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700436TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithMdnsCaller) {
437 RTCConfiguration config;
438
439 // Enable hostname candidates with mDNS names.
440 auto caller = CreatePeerConnectionWithMdns(config);
441 auto callee = CreatePeerConnection(config);
442
443 caller->AddAudioTrack("audio");
444 caller->AddVideoTrack("video");
445 ASSERT_TRUE(caller->ConnectTo(callee.get()));
446 caller->pc()->Close();
447 callee->pc()->Close();
448
449 int expected_fingerprint_caller = MakeUsageFingerprint(
450 {PeerConnection::UsageEvent::AUDIO_ADDED,
451 PeerConnection::UsageEvent::VIDEO_ADDED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700452 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
453 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700454 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
455 PeerConnection::UsageEvent::MDNS_CANDIDATE_COLLECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700456 PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700457 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700458 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700459 PeerConnection::UsageEvent::CLOSE_CALLED});
460
461 int expected_fingerprint_callee = MakeUsageFingerprint(
462 {PeerConnection::UsageEvent::AUDIO_ADDED,
463 PeerConnection::UsageEvent::VIDEO_ADDED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700464 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
465 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700466 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700467 PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700468 PeerConnection::UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED,
469 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700470 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700471 PeerConnection::UsageEvent::CLOSE_CALLED});
472
473 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
474 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
475 expected_fingerprint_caller));
476 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
477 expected_fingerprint_callee));
478}
479
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700480// Test getting the usage fingerprint when the callee collects an mDNS
481// candidate.
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700482TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithMdnsCallee) {
483 RTCConfiguration config;
484
485 // Enable hostname candidates with mDNS names.
486 auto caller = CreatePeerConnection(config);
487 auto callee = CreatePeerConnectionWithMdns(config);
488
489 caller->AddAudioTrack("audio");
490 caller->AddVideoTrack("video");
491 ASSERT_TRUE(caller->ConnectTo(callee.get()));
492 caller->pc()->Close();
493 callee->pc()->Close();
494
495 int expected_fingerprint_caller = MakeUsageFingerprint(
496 {PeerConnection::UsageEvent::AUDIO_ADDED,
497 PeerConnection::UsageEvent::VIDEO_ADDED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700498 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
499 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700500 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700501 PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700502 PeerConnection::UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED,
503 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700504 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700505 PeerConnection::UsageEvent::CLOSE_CALLED});
506
507 int expected_fingerprint_callee = MakeUsageFingerprint(
508 {PeerConnection::UsageEvent::AUDIO_ADDED,
509 PeerConnection::UsageEvent::VIDEO_ADDED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700510 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
511 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700512 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
513 PeerConnection::UsageEvent::MDNS_CANDIDATE_COLLECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700514 PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700515 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700516 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700517 PeerConnection::UsageEvent::CLOSE_CALLED});
518
519 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
520 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
521 expected_fingerprint_caller));
522 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
523 expected_fingerprint_callee));
524}
525
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200526#ifdef HAVE_SCTP
527TEST_F(PeerConnectionUsageHistogramTest, FingerprintDataOnly) {
528 auto caller = CreatePeerConnection();
529 auto callee = CreatePeerConnection();
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200530 caller->CreateDataChannel("foodata");
Harald Alvestrand42386282018-07-12 07:56:05 +0200531 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200532 ASSERT_TRUE_WAIT(callee->HaveDataChannel(), kDefaultTimeout);
533 caller->pc()->Close();
534 callee->pc()->Close();
535 int expected_fingerprint = MakeUsageFingerprint(
536 {PeerConnection::UsageEvent::DATA_ADDED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700537 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
538 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200539 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700540 PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200541 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700542 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200543 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200544 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200545 EXPECT_TRUE(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200546 webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint) ==
547 2 ||
Harald Alvestrand056d8112018-07-16 19:18:58 +0200548 webrtc::metrics::NumEvents(
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200549 kUsagePatternMetric,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200550 expected_fingerprint |
551 static_cast<int>(
552 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
553 2);
Harald Alvestrand183e09d2018-06-28 12:04:41 +0200554}
555#endif // HAVE_SCTP
556#endif // WEBRTC_ANDROID
557
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200558TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurn) {
559 RTCConfiguration configuration;
560 PeerConnection::IceServer server;
561 server.urls = {"stun:dummy.stun.server/"};
562 configuration.servers.push_back(server);
563 server.urls = {"turn:dummy.turn.server/"};
564 server.username = "username";
565 server.password = "password";
566 configuration.servers.push_back(server);
567 auto caller = CreatePeerConnection(configuration);
568 ASSERT_TRUE(caller);
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200569 caller->pc()->Close();
570 int expected_fingerprint =
571 MakeUsageFingerprint({PeerConnection::UsageEvent::STUN_SERVER_ADDED,
572 PeerConnection::UsageEvent::TURN_SERVER_ADDED,
573 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200574 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
575 EXPECT_EQ(
576 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200577}
578
579TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurnInReconfiguration) {
580 RTCConfiguration configuration;
581 PeerConnection::IceServer server;
582 server.urls = {"stun:dummy.stun.server/"};
583 configuration.servers.push_back(server);
584 server.urls = {"turn:dummy.turn.server/"};
585 server.username = "username";
586 server.password = "password";
587 configuration.servers.push_back(server);
588 auto caller = CreatePeerConnection();
589 ASSERT_TRUE(caller);
Niels Möller2579f0c2019-08-19 09:58:17 +0200590 ASSERT_TRUE(caller->pc()->SetConfiguration(configuration).ok());
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200591 caller->pc()->Close();
592 int expected_fingerprint =
593 MakeUsageFingerprint({PeerConnection::UsageEvent::STUN_SERVER_ADDED,
594 PeerConnection::UsageEvent::TURN_SERVER_ADDED,
595 PeerConnection::UsageEvent::CLOSE_CALLED});
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200596 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
597 EXPECT_EQ(
598 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200599}
600
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700601TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIPCaller) {
Harald Alvestrand056d8112018-07-16 19:18:58 +0200602 auto caller = CreatePeerConnectionWithPrivateLocalAddresses();
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700603 auto callee = CreatePeerConnection();
Harald Alvestrand056d8112018-07-16 19:18:58 +0200604 caller->AddAudioTrack("audio");
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700605 ASSERT_TRUE(caller->ConnectTo(callee.get()));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200606 caller->pc()->Close();
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700607 callee->pc()->Close();
608
609 int expected_fingerprint_caller = MakeUsageFingerprint(
Harald Alvestrand056d8112018-07-16 19:18:58 +0200610 {PeerConnection::UsageEvent::AUDIO_ADDED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700611 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
612 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
Harald Alvestrand056d8112018-07-16 19:18:58 +0200613 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700614 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700615 PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700616 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700617 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700618 PeerConnection::UsageEvent::CLOSE_CALLED});
619
620 int expected_fingerprint_callee = MakeUsageFingerprint(
621 {PeerConnection::UsageEvent::AUDIO_ADDED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700622 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
623 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700624 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700625 PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700626 PeerConnection::UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED,
627 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700628 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700629 PeerConnection::UsageEvent::CLOSE_CALLED});
630
631 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
632 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
633 expected_fingerprint_caller));
634 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
635 expected_fingerprint_callee));
636}
637
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700638TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIpv6Callee) {
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700639 auto caller = CreatePeerConnection();
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700640 auto callee = CreatePeerConnectionWithPrivateIpv6LocalAddresses();
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700641 caller->AddAudioTrack("audio");
642 ASSERT_TRUE(caller->ConnectTo(callee.get()));
643 caller->pc()->Close();
644 callee->pc()->Close();
645
646 int expected_fingerprint_caller = MakeUsageFingerprint(
647 {PeerConnection::UsageEvent::AUDIO_ADDED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700648 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
649 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700650 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700651 PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700652 PeerConnection::UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED,
653 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700654 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
655 PeerConnection::UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700656 PeerConnection::UsageEvent::CLOSE_CALLED});
657
658 int expected_fingerprint_callee = MakeUsageFingerprint(
659 {PeerConnection::UsageEvent::AUDIO_ADDED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700660 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
661 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700662 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
663 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700664 PeerConnection::UsageEvent::IPV6_CANDIDATE_COLLECTED,
665 PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
Jeroen de Borstaf242c82019-04-24 13:13:48 -0700666 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
667 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
668 PeerConnection::UsageEvent::CLOSE_CALLED});
669
670 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
671 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
672 expected_fingerprint_caller));
673 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
674 expected_fingerprint_callee));
Harald Alvestrand056d8112018-07-16 19:18:58 +0200675}
676
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200677#ifndef WEBRTC_ANDROID
678#ifdef HAVE_SCTP
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700679// Test that the usage pattern bits for adding remote (private IPv6) candidates
680// are set when the remote candidates are retrieved from the Offer SDP instead
681// of trickled ICE messages.
682TEST_F(PeerConnectionUsageHistogramTest,
683 AddRemoteCandidatesFromRemoteDescription) {
684 // We construct the following data-channel-only scenario. The caller collects
685 // IPv6 private local candidates and appends them in the Offer as in
686 // non-trickled sessions. The callee collects mDNS candidates that are not
687 // contained in the Answer as in Trickle ICE. Only the Offer and Answer are
688 // signaled and we expect a connection with prflx remote candidates at the
689 // caller side.
690 auto caller = CreatePeerConnectionWithPrivateIpv6LocalAddresses();
691 auto callee = CreatePeerConnectionWithMdns(RTCConfiguration());
692 caller->CreateDataChannel("test_channel");
693 ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
694 // Wait until the gathering completes so that the session description would
695 // have contained ICE candidates.
696 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
697 caller->ice_gathering_state(), kDefaultTimeout);
698 EXPECT_TRUE(caller->observer()->candidate_gathered());
699 // Get the current offer that contains candidates and pass it to the callee.
700 //
701 // Note that we cannot use CloneSessionDescription on |cur_offer| to obtain an
702 // SDP with candidates. The method above does not strictly copy everything, in
703 // particular, not copying the ICE candidates.
704 // TODO(qingsi): Technically, this is a bug. Fix it.
705 auto cur_offer = caller->pc()->local_description();
706 ASSERT_TRUE(cur_offer);
707 std::string sdp_with_candidates_str;
708 cur_offer->ToString(&sdp_with_candidates_str);
709 auto offer = absl::make_unique<JsepSessionDescription>(SdpType::kOffer);
710 ASSERT_TRUE(SdpDeserialize(sdp_with_candidates_str, offer.get(),
711 nullptr /* error */));
712 ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
713
714 // By default, the Answer created does not contain ICE candidates.
715 auto answer = callee->CreateAnswer();
716 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
717 caller->SetRemoteDescription(std::move(answer));
718 EXPECT_TRUE_WAIT(caller->IsConnected(), kDefaultTimeout);
719 EXPECT_TRUE_WAIT(callee->IsConnected(), kDefaultTimeout);
720 // The callee needs to process the open message to have the data channel open.
721 EXPECT_TRUE_WAIT(callee->observer()->last_datachannel_ != nullptr,
722 kDefaultTimeout);
723 caller->pc()->Close();
724 callee->pc()->Close();
725
726 // The caller should not have added any remote candidate either via
727 // AddIceCandidate or from the remote description.
728 int expected_fingerprint_caller = MakeUsageFingerprint(
729 {PeerConnection::UsageEvent::DATA_ADDED,
730 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
731 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
732 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
733 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED,
734 PeerConnection::UsageEvent::IPV6_CANDIDATE_COLLECTED,
735 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
736 PeerConnection::UsageEvent::CLOSE_CALLED});
737
738 int expected_fingerprint_callee = MakeUsageFingerprint(
739 {PeerConnection::UsageEvent::DATA_ADDED,
740 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
741 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED,
742 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
743 PeerConnection::UsageEvent::MDNS_CANDIDATE_COLLECTED,
744 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
745 PeerConnection::UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED,
746 PeerConnection::UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED,
747 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
748 PeerConnection::UsageEvent::CLOSE_CALLED});
749
750 EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
751 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
752 expected_fingerprint_caller));
753 EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
754 expected_fingerprint_callee));
755}
756
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200757TEST_F(PeerConnectionUsageHistogramTest, NotableUsageNoted) {
758 auto caller = CreatePeerConnection();
759 caller->CreateDataChannel("foo");
760 caller->GenerateOfferAndCollectCandidates();
761 caller->pc()->Close();
762 int expected_fingerprint = MakeUsageFingerprint(
763 {PeerConnection::UsageEvent::DATA_ADDED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700764 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200765 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
766 PeerConnection::UsageEvent::CLOSE_CALLED});
767 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
768 EXPECT_TRUE(expected_fingerprint == ObservedFingerprint() ||
769 (expected_fingerprint |
770 static_cast<int>(
771 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
772 ObservedFingerprint());
773 EXPECT_EQ(absl::make_optional(ObservedFingerprint()),
774 caller->observer()->interesting_usage_detected());
775}
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200776
777TEST_F(PeerConnectionUsageHistogramTest, NotableUsageOnEventFiring) {
778 auto caller = CreatePeerConnection();
779 caller->CreateDataChannel("foo");
780 caller->GenerateOfferAndCollectCandidates();
781 int expected_fingerprint = MakeUsageFingerprint(
782 {PeerConnection::UsageEvent::DATA_ADDED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700783 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200784 PeerConnection::UsageEvent::CANDIDATE_COLLECTED});
785 EXPECT_EQ(0, webrtc::metrics::NumSamples(kUsagePatternMetric));
786 caller->GetInternalPeerConnection()->RequestUsagePatternReportForTesting();
787 EXPECT_EQ_WAIT(1, webrtc::metrics::NumSamples(kUsagePatternMetric),
788 kDefaultTimeout);
789 EXPECT_TRUE(expected_fingerprint == ObservedFingerprint() ||
790 (expected_fingerprint |
791 static_cast<int>(
792 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
793 ObservedFingerprint());
794 EXPECT_EQ(absl::make_optional(ObservedFingerprint()),
795 caller->observer()->interesting_usage_detected());
796}
797
798TEST_F(PeerConnectionUsageHistogramTest,
799 NoNotableUsageOnEventFiringAfterClose) {
800 auto caller = CreatePeerConnection();
801 caller->CreateDataChannel("foo");
802 caller->GenerateOfferAndCollectCandidates();
803 int expected_fingerprint = MakeUsageFingerprint(
804 {PeerConnection::UsageEvent::DATA_ADDED,
Qingsi Wang1ba5dec2019-08-19 11:57:17 -0700805 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +0200806 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
807 PeerConnection::UsageEvent::CLOSE_CALLED});
808 EXPECT_EQ(0, webrtc::metrics::NumSamples(kUsagePatternMetric));
809 caller->pc()->Close();
810 EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
811 caller->GetInternalPeerConnection()->RequestUsagePatternReportForTesting();
812 caller->observer()->ClearInterestingUsageDetector();
813 EXPECT_EQ_WAIT(2, webrtc::metrics::NumSamples(kUsagePatternMetric),
814 kDefaultTimeout);
815 EXPECT_TRUE(expected_fingerprint == ObservedFingerprint() ||
816 (expected_fingerprint |
817 static_cast<int>(
818 PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
819 ObservedFingerprint());
820 // After close, the usage-detection callback should NOT have been called.
821 EXPECT_FALSE(caller->observer()->interesting_usage_detected());
822}
Harald Alvestrandc0e97252018-07-26 10:39:55 +0200823#endif
824#endif
825
Harald Alvestrand19793842018-06-25 12:03:50 +0200826} // namespace webrtc