blob: 1b8054f09aeb85a23e8568022b577b519a5473f4 [file] [log] [blame]
deadbeef1dcb1642017-03-29 21:08:16 -07001/*
2 * Copyright 2012 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// Disable for TSan v2, see
12// https://code.google.com/p/webrtc/issues/detail?id=1205 for details.
13#if !defined(THREAD_SANITIZER)
14
15#include <stdio.h>
16
17#include <algorithm>
18#include <functional>
19#include <list>
20#include <map>
21#include <memory>
22#include <utility>
23#include <vector>
24
Karl Wiberg1b0eae32017-10-17 14:48:54 +020025#include "api/audio_codecs/builtin_audio_decoder_factory.h"
26#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "api/mediastreaminterface.h"
28#include "api/peerconnectioninterface.h"
Steve Anton8c0f7a72017-10-03 10:03:10 -070029#include "api/peerconnectionproxy.h"
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +010030#include "api/rtpreceiverinterface.h"
Anders Carlsson67537952018-05-03 11:28:29 +020031#include "api/video_codecs/builtin_video_decoder_factory.h"
32#include "api/video_codecs/builtin_video_encoder_factory.h"
33#include "api/video_codecs/sdp_video_format.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070034#include "call/call.h"
35#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
36#include "logging/rtc_event_log/rtc_event_log_factory_interface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020037#include "media/engine/fakewebrtcvideoengine.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070038#include "media/engine/webrtcmediaengine.h"
39#include "modules/audio_processing/include/audio_processing.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020040#include "p2p/base/p2pconstants.h"
41#include "p2p/base/portinterface.h"
Steve Antonede9ca52017-10-16 13:04:27 -070042#include "p2p/base/teststunserver.h"
Jonas Orelandbdcee282017-10-10 14:01:40 +020043#include "p2p/base/testturncustomizer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020044#include "p2p/base/testturnserver.h"
45#include "p2p/client/basicportallocator.h"
46#include "pc/dtmfsender.h"
47#include "pc/localaudiosource.h"
48#include "pc/mediasession.h"
49#include "pc/peerconnection.h"
50#include "pc/peerconnectionfactory.h"
Seth Hampson2f0d7022018-02-20 11:54:42 -080051#include "pc/rtpmediautils.h"
Steve Anton4ab68ee2017-12-19 14:26:11 -080052#include "pc/sessiondescription.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020053#include "pc/test/fakeaudiocapturemodule.h"
Niels Möller0f405822018-05-17 09:16:41 +020054#include "pc/test/fakeperiodicvideotracksource.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020055#include "pc/test/fakertccertificategenerator.h"
56#include "pc/test/fakevideotrackrenderer.h"
57#include "pc/test/mockpeerconnectionobservers.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020058#include "rtc_base/fakenetwork.h"
Steve Antonede9ca52017-10-16 13:04:27 -070059#include "rtc_base/firewallsocketserver.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020060#include "rtc_base/gunit.h"
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +020061#include "rtc_base/numerics/safe_conversions.h"
Benjamin Wrightd6f86e82018-05-08 13:12:25 -070062#include "rtc_base/testcertificateverifier.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020063#include "rtc_base/virtualsocketserver.h"
Qingsi Wang7fc821d2018-07-12 12:54:53 -070064#include "system_wrappers/include/metrics_default.h"
Elad Alon99c3fe52017-10-13 16:29:40 +020065#include "test/gmock.h"
deadbeef1dcb1642017-03-29 21:08:16 -070066
67using cricket::ContentInfo;
68using cricket::FakeWebRtcVideoDecoder;
69using cricket::FakeWebRtcVideoDecoderFactory;
70using cricket::FakeWebRtcVideoEncoder;
71using cricket::FakeWebRtcVideoEncoderFactory;
72using cricket::MediaContentDescription;
Steve Antondf527fd2018-04-27 15:52:03 -070073using cricket::StreamParams;
Steve Antonede9ca52017-10-16 13:04:27 -070074using rtc::SocketAddress;
Seth Hampson2f0d7022018-02-20 11:54:42 -080075using ::testing::Combine;
Steve Antonede9ca52017-10-16 13:04:27 -070076using ::testing::ElementsAre;
77using ::testing::Values;
deadbeef1dcb1642017-03-29 21:08:16 -070078using webrtc::DataBuffer;
79using webrtc::DataChannelInterface;
80using webrtc::DtmfSender;
81using webrtc::DtmfSenderInterface;
82using webrtc::DtmfSenderObserverInterface;
Steve Anton15324772018-01-16 10:26:49 -080083using webrtc::FakeVideoTrackRenderer;
deadbeef1dcb1642017-03-29 21:08:16 -070084using webrtc::MediaConstraintsInterface;
85using webrtc::MediaStreamInterface;
86using webrtc::MediaStreamTrackInterface;
87using webrtc::MockCreateSessionDescriptionObserver;
88using webrtc::MockDataChannelObserver;
89using webrtc::MockSetSessionDescriptionObserver;
90using webrtc::MockStatsObserver;
91using webrtc::ObserverInterface;
Steve Anton8c0f7a72017-10-03 10:03:10 -070092using webrtc::PeerConnection;
deadbeef1dcb1642017-03-29 21:08:16 -070093using webrtc::PeerConnectionInterface;
Steve Anton74255ff2018-01-24 18:32:57 -080094using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
deadbeef1dcb1642017-03-29 21:08:16 -070095using webrtc::PeerConnectionFactory;
Steve Anton8c0f7a72017-10-03 10:03:10 -070096using webrtc::PeerConnectionProxy;
Steve Anton15324772018-01-16 10:26:49 -080097using webrtc::RTCErrorType;
Steve Anton7eca0932018-03-30 15:18:41 -070098using webrtc::RTCTransportStats;
Steve Anton74255ff2018-01-24 18:32:57 -080099using webrtc::RtpSenderInterface;
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100100using webrtc::RtpReceiverInterface;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800101using webrtc::RtpSenderInterface;
102using webrtc::RtpTransceiverDirection;
103using webrtc::RtpTransceiverInit;
104using webrtc::RtpTransceiverInterface;
Steve Antond3679212018-01-17 17:41:02 -0800105using webrtc::SdpSemantics;
Steve Antona3a92c22017-12-07 10:27:41 -0800106using webrtc::SdpType;
deadbeef1dcb1642017-03-29 21:08:16 -0700107using webrtc::SessionDescriptionInterface;
108using webrtc::StreamCollectionInterface;
Steve Anton15324772018-01-16 10:26:49 -0800109using webrtc::VideoTrackInterface;
deadbeef1dcb1642017-03-29 21:08:16 -0700110
111namespace {
112
113static const int kDefaultTimeout = 10000;
114static const int kMaxWaitForStatsMs = 3000;
115static const int kMaxWaitForActivationMs = 5000;
116static const int kMaxWaitForFramesMs = 10000;
117// Default number of audio/video frames to wait for before considering a test
118// successful.
119static const int kDefaultExpectedAudioFrameCount = 3;
120static const int kDefaultExpectedVideoFrameCount = 3;
121
deadbeef1dcb1642017-03-29 21:08:16 -0700122static const char kDataChannelLabel[] = "data_channel";
123
124// SRTP cipher name negotiated by the tests. This must be updated if the
125// default changes.
Taylor Brandstetterfd350d72018-04-03 16:29:26 -0700126static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_80;
deadbeef1dcb1642017-03-29 21:08:16 -0700127static const int kDefaultSrtpCryptoSuiteGcm = rtc::SRTP_AEAD_AES_256_GCM;
128
Steve Antonede9ca52017-10-16 13:04:27 -0700129static const SocketAddress kDefaultLocalAddress("192.168.1.1", 0);
130
deadbeef1dcb1642017-03-29 21:08:16 -0700131// Helper function for constructing offer/answer options to initiate an ICE
132// restart.
133PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions() {
134 PeerConnectionInterface::RTCOfferAnswerOptions options;
135 options.ice_restart = true;
136 return options;
137}
138
deadbeefd8ad7882017-04-18 16:01:17 -0700139// Remove all stream information (SSRCs, track IDs, etc.) and "msid-semantic"
140// attribute from received SDP, simulating a legacy endpoint.
141void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) {
142 for (ContentInfo& content : desc->contents()) {
Steve Antonb1c1de12017-12-21 15:14:30 -0800143 content.media_description()->mutable_streams().clear();
deadbeefd8ad7882017-04-18 16:01:17 -0700144 }
145 desc->set_msid_supported(false);
146}
147
Seth Hampson5897a6e2018-04-03 11:16:33 -0700148// Removes all stream information besides the stream ids, simulating an
149// endpoint that only signals a=msid lines to convey stream_ids.
150void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) {
151 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700152 std::string track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700153 std::vector<std::string> stream_ids;
154 if (!content.media_description()->streams().empty()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700155 const StreamParams& first_stream =
156 content.media_description()->streams()[0];
157 track_id = first_stream.id;
158 stream_ids = first_stream.stream_ids();
Seth Hampson5897a6e2018-04-03 11:16:33 -0700159 }
160 content.media_description()->mutable_streams().clear();
Steve Antondf527fd2018-04-27 15:52:03 -0700161 StreamParams new_stream;
162 new_stream.id = track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700163 new_stream.set_stream_ids(stream_ids);
164 content.media_description()->AddStream(new_stream);
165 }
166}
167
zhihuangf8164932017-05-19 13:09:47 -0700168int FindFirstMediaStatsIndexByKind(
169 const std::string& kind,
170 const std::vector<const webrtc::RTCMediaStreamTrackStats*>&
171 media_stats_vec) {
172 for (size_t i = 0; i < media_stats_vec.size(); i++) {
173 if (media_stats_vec[i]->kind.ValueToString() == kind) {
174 return i;
175 }
176 }
177 return -1;
178}
179
deadbeef1dcb1642017-03-29 21:08:16 -0700180class SignalingMessageReceiver {
181 public:
Steve Antona3a92c22017-12-07 10:27:41 -0800182 virtual void ReceiveSdpMessage(SdpType type, const std::string& msg) = 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700183 virtual void ReceiveIceMessage(const std::string& sdp_mid,
184 int sdp_mline_index,
185 const std::string& msg) = 0;
186
187 protected:
188 SignalingMessageReceiver() {}
189 virtual ~SignalingMessageReceiver() {}
190};
191
192class MockRtpReceiverObserver : public webrtc::RtpReceiverObserverInterface {
193 public:
194 explicit MockRtpReceiverObserver(cricket::MediaType media_type)
195 : expected_media_type_(media_type) {}
196
197 void OnFirstPacketReceived(cricket::MediaType media_type) override {
198 ASSERT_EQ(expected_media_type_, media_type);
199 first_packet_received_ = true;
200 }
201
202 bool first_packet_received() const { return first_packet_received_; }
203
204 virtual ~MockRtpReceiverObserver() {}
205
206 private:
207 bool first_packet_received_ = false;
208 cricket::MediaType expected_media_type_;
209};
210
211// Helper class that wraps a peer connection, observes it, and can accept
212// signaling messages from another wrapper.
213//
214// Uses a fake network, fake A/V capture, and optionally fake
215// encoders/decoders, though they aren't used by default since they don't
216// advertise support of any codecs.
Steve Anton94286cb2017-09-26 16:20:19 -0700217// TODO(steveanton): See how this could become a subclass of
Seth Hampson2f0d7022018-02-20 11:54:42 -0800218// PeerConnectionWrapper defined in peerconnectionwrapper.h.
deadbeef1dcb1642017-03-29 21:08:16 -0700219class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
Steve Anton15324772018-01-16 10:26:49 -0800220 public SignalingMessageReceiver {
deadbeef1dcb1642017-03-29 21:08:16 -0700221 public:
222 // Different factory methods for convenience.
223 // TODO(deadbeef): Could use the pattern of:
224 //
225 // PeerConnectionWrapper =
226 // WrapperBuilder.WithConfig(...).WithOptions(...).build();
227 //
228 // To reduce some code duplication.
229 static PeerConnectionWrapper* CreateWithDtlsIdentityStore(
230 const std::string& debug_name,
231 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
232 rtc::Thread* network_thread,
233 rtc::Thread* worker_thread) {
234 PeerConnectionWrapper* client(new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700235 webrtc::PeerConnectionDependencies dependencies(nullptr);
236 dependencies.cert_generator = std::move(cert_generator);
Niels Möllerf06f9232018-08-07 12:32:18 +0200237 if (!client->Init(nullptr, nullptr, std::move(dependencies), network_thread,
238 worker_thread, nullptr)) {
deadbeef1dcb1642017-03-29 21:08:16 -0700239 delete client;
240 return nullptr;
241 }
242 return client;
243 }
244
deadbeef2f425aa2017-04-14 10:41:32 -0700245 webrtc::PeerConnectionFactoryInterface* pc_factory() const {
246 return peer_connection_factory_.get();
247 }
248
deadbeef1dcb1642017-03-29 21:08:16 -0700249 webrtc::PeerConnectionInterface* pc() const { return peer_connection_.get(); }
250
251 // If a signaling message receiver is set (via ConnectFakeSignaling), this
252 // will set the whole offer/answer exchange in motion. Just need to wait for
253 // the signaling state to reach "stable".
254 void CreateAndSetAndSignalOffer() {
255 auto offer = CreateOffer();
256 ASSERT_NE(nullptr, offer);
257 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(offer)));
258 }
259
260 // Sets the options to be used when CreateAndSetAndSignalOffer is called, or
261 // when a remote offer is received (via fake signaling) and an answer is
262 // generated. By default, uses default options.
263 void SetOfferAnswerOptions(
264 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
265 offer_answer_options_ = options;
266 }
267
268 // Set a callback to be invoked when SDP is received via the fake signaling
269 // channel, which provides an opportunity to munge (modify) the SDP. This is
270 // used to test SDP being applied that a PeerConnection would normally not
271 // generate, but a non-JSEP endpoint might.
272 void SetReceivedSdpMunger(
273 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100274 received_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700275 }
276
deadbeefc964d0b2017-04-03 10:03:35 -0700277 // Similar to the above, but this is run on SDP immediately after it's
deadbeef1dcb1642017-03-29 21:08:16 -0700278 // generated.
279 void SetGeneratedSdpMunger(
280 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100281 generated_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700282 }
283
Seth Hampson2f0d7022018-02-20 11:54:42 -0800284 // Set a callback to be invoked when a remote offer is received via the fake
285 // signaling channel. This provides an opportunity to change the
286 // PeerConnection state before an answer is created and sent to the caller.
287 void SetRemoteOfferHandler(std::function<void()> handler) {
288 remote_offer_handler_ = std::move(handler);
289 }
290
Steve Antonede9ca52017-10-16 13:04:27 -0700291 // Every ICE connection state in order that has been seen by the observer.
292 std::vector<PeerConnectionInterface::IceConnectionState>
293 ice_connection_state_history() const {
294 return ice_connection_state_history_;
295 }
Steve Anton6f25b092017-10-23 09:39:20 -0700296 void clear_ice_connection_state_history() {
297 ice_connection_state_history_.clear();
298 }
Steve Antonede9ca52017-10-16 13:04:27 -0700299
300 // Every ICE gathering state in order that has been seen by the observer.
301 std::vector<PeerConnectionInterface::IceGatheringState>
302 ice_gathering_state_history() const {
303 return ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -0700304 }
305
Steve Anton15324772018-01-16 10:26:49 -0800306 void AddAudioVideoTracks() {
307 AddAudioTrack();
308 AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700309 }
310
Steve Anton74255ff2018-01-24 18:32:57 -0800311 rtc::scoped_refptr<RtpSenderInterface> AddAudioTrack() {
312 return AddTrack(CreateLocalAudioTrack());
313 }
deadbeef1dcb1642017-03-29 21:08:16 -0700314
Steve Anton74255ff2018-01-24 18:32:57 -0800315 rtc::scoped_refptr<RtpSenderInterface> AddVideoTrack() {
316 return AddTrack(CreateLocalVideoTrack());
317 }
deadbeef1dcb1642017-03-29 21:08:16 -0700318
319 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack() {
Niels Möller2d02e082018-05-21 11:23:35 +0200320 cricket::AudioOptions options;
deadbeef1dcb1642017-03-29 21:08:16 -0700321 // Disable highpass filter so that we can get all the test audio frames.
Niels Möller2d02e082018-05-21 11:23:35 +0200322 options.highpass_filter = false;
deadbeef1dcb1642017-03-29 21:08:16 -0700323 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
Niels Möller2d02e082018-05-21 11:23:35 +0200324 peer_connection_factory_->CreateAudioSource(options);
deadbeef1dcb1642017-03-29 21:08:16 -0700325 // TODO(perkj): Test audio source when it is implemented. Currently audio
326 // always use the default input.
deadbeefb1a15d72017-09-07 14:12:05 -0700327 return peer_connection_factory_->CreateAudioTrack(rtc::CreateRandomUuid(),
deadbeef1dcb1642017-03-29 21:08:16 -0700328 source);
329 }
330
331 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack() {
Niels Möller5c7efe72018-05-11 10:34:46 +0200332 return CreateLocalVideoTrackInternal(
333 webrtc::FakePeriodicVideoSource::Config());
deadbeef1dcb1642017-03-29 21:08:16 -0700334 }
335
336 rtc::scoped_refptr<webrtc::VideoTrackInterface>
Niels Möller5c7efe72018-05-11 10:34:46 +0200337 CreateLocalVideoTrackWithConfig(
338 webrtc::FakePeriodicVideoSource::Config config) {
339 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700340 }
341
342 rtc::scoped_refptr<webrtc::VideoTrackInterface>
343 CreateLocalVideoTrackWithRotation(webrtc::VideoRotation rotation) {
Niels Möller5c7efe72018-05-11 10:34:46 +0200344 webrtc::FakePeriodicVideoSource::Config config;
345 config.rotation = rotation;
346 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700347 }
348
Steve Anton74255ff2018-01-24 18:32:57 -0800349 rtc::scoped_refptr<RtpSenderInterface> AddTrack(
350 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800351 const std::vector<std::string>& stream_ids = {}) {
352 auto result = pc()->AddTrack(track, stream_ids);
Steve Anton15324772018-01-16 10:26:49 -0800353 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
Steve Anton74255ff2018-01-24 18:32:57 -0800354 return result.MoveValue();
355 }
356
357 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceiversOfType(
358 cricket::MediaType media_type) {
359 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
360 for (auto receiver : pc()->GetReceivers()) {
361 if (receiver->media_type() == media_type) {
362 receivers.push_back(receiver);
363 }
364 }
365 return receivers;
deadbeef1dcb1642017-03-29 21:08:16 -0700366 }
367
Seth Hampson2f0d7022018-02-20 11:54:42 -0800368 rtc::scoped_refptr<RtpTransceiverInterface> GetFirstTransceiverOfType(
369 cricket::MediaType media_type) {
370 for (auto transceiver : pc()->GetTransceivers()) {
371 if (transceiver->receiver()->media_type() == media_type) {
372 return transceiver;
373 }
374 }
375 return nullptr;
376 }
377
deadbeef1dcb1642017-03-29 21:08:16 -0700378 bool SignalingStateStable() {
379 return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable;
380 }
381
382 void CreateDataChannel() { CreateDataChannel(nullptr); }
383
384 void CreateDataChannel(const webrtc::DataChannelInit* init) {
Steve Antonda6c0952017-10-23 11:41:54 -0700385 CreateDataChannel(kDataChannelLabel, init);
386 }
387
388 void CreateDataChannel(const std::string& label,
389 const webrtc::DataChannelInit* init) {
390 data_channel_ = pc()->CreateDataChannel(label, init);
deadbeef1dcb1642017-03-29 21:08:16 -0700391 ASSERT_TRUE(data_channel_.get() != nullptr);
392 data_observer_.reset(new MockDataChannelObserver(data_channel_));
393 }
394
395 DataChannelInterface* data_channel() { return data_channel_; }
396 const MockDataChannelObserver* data_observer() const {
397 return data_observer_.get();
398 }
399
400 int audio_frames_received() const {
401 return fake_audio_capture_module_->frames_received();
402 }
403
404 // Takes minimum of video frames received for each track.
405 //
406 // Can be used like:
407 // EXPECT_GE(expected_frames, min_video_frames_received_per_track());
408 //
409 // To ensure that all video tracks received at least a certain number of
410 // frames.
411 int min_video_frames_received_per_track() const {
412 int min_frames = INT_MAX;
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200413 if (fake_video_renderers_.empty()) {
414 return 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700415 }
deadbeef1dcb1642017-03-29 21:08:16 -0700416
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200417 for (const auto& pair : fake_video_renderers_) {
418 min_frames = std::min(min_frames, pair.second->num_rendered_frames());
deadbeef1dcb1642017-03-29 21:08:16 -0700419 }
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200420 return min_frames;
deadbeef1dcb1642017-03-29 21:08:16 -0700421 }
422
423 // Returns a MockStatsObserver in a state after stats gathering finished,
424 // which can be used to access the gathered stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700425 rtc::scoped_refptr<MockStatsObserver> OldGetStatsForTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700426 webrtc::MediaStreamTrackInterface* track) {
427 rtc::scoped_refptr<MockStatsObserver> observer(
428 new rtc::RefCountedObject<MockStatsObserver>());
429 EXPECT_TRUE(peer_connection_->GetStats(
430 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard));
431 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
432 return observer;
433 }
434
435 // Version that doesn't take a track "filter", and gathers all stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700436 rtc::scoped_refptr<MockStatsObserver> OldGetStats() {
437 return OldGetStatsForTrack(nullptr);
438 }
439
440 // Synchronously gets stats and returns them. If it times out, fails the test
441 // and returns null.
442 rtc::scoped_refptr<const webrtc::RTCStatsReport> NewGetStats() {
443 rtc::scoped_refptr<webrtc::MockRTCStatsCollectorCallback> callback(
444 new rtc::RefCountedObject<webrtc::MockRTCStatsCollectorCallback>());
445 peer_connection_->GetStats(callback);
446 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
447 return callback->report();
deadbeef1dcb1642017-03-29 21:08:16 -0700448 }
449
450 int rendered_width() {
451 EXPECT_FALSE(fake_video_renderers_.empty());
452 return fake_video_renderers_.empty()
453 ? 0
454 : fake_video_renderers_.begin()->second->width();
455 }
456
457 int rendered_height() {
458 EXPECT_FALSE(fake_video_renderers_.empty());
459 return fake_video_renderers_.empty()
460 ? 0
461 : fake_video_renderers_.begin()->second->height();
462 }
463
464 double rendered_aspect_ratio() {
465 if (rendered_height() == 0) {
466 return 0.0;
467 }
468 return static_cast<double>(rendered_width()) / rendered_height();
469 }
470
471 webrtc::VideoRotation rendered_rotation() {
472 EXPECT_FALSE(fake_video_renderers_.empty());
473 return fake_video_renderers_.empty()
474 ? webrtc::kVideoRotation_0
475 : fake_video_renderers_.begin()->second->rotation();
476 }
477
478 int local_rendered_width() {
479 return local_video_renderer_ ? local_video_renderer_->width() : 0;
480 }
481
482 int local_rendered_height() {
483 return local_video_renderer_ ? local_video_renderer_->height() : 0;
484 }
485
486 double local_rendered_aspect_ratio() {
487 if (local_rendered_height() == 0) {
488 return 0.0;
489 }
490 return static_cast<double>(local_rendered_width()) /
491 local_rendered_height();
492 }
493
494 size_t number_of_remote_streams() {
495 if (!pc()) {
496 return 0;
497 }
498 return pc()->remote_streams()->count();
499 }
500
501 StreamCollectionInterface* remote_streams() const {
502 if (!pc()) {
503 ADD_FAILURE();
504 return nullptr;
505 }
506 return pc()->remote_streams();
507 }
508
509 StreamCollectionInterface* local_streams() {
510 if (!pc()) {
511 ADD_FAILURE();
512 return nullptr;
513 }
514 return pc()->local_streams();
515 }
516
517 webrtc::PeerConnectionInterface::SignalingState signaling_state() {
518 return pc()->signaling_state();
519 }
520
521 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() {
522 return pc()->ice_connection_state();
523 }
524
525 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() {
526 return pc()->ice_gathering_state();
527 }
528
529 // Returns a MockRtpReceiverObserver for each RtpReceiver returned by
530 // GetReceivers. They're updated automatically when a remote offer/answer
531 // from the fake signaling channel is applied, or when
532 // ResetRtpReceiverObservers below is called.
533 const std::vector<std::unique_ptr<MockRtpReceiverObserver>>&
534 rtp_receiver_observers() {
535 return rtp_receiver_observers_;
536 }
537
538 void ResetRtpReceiverObservers() {
539 rtp_receiver_observers_.clear();
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100540 for (const rtc::scoped_refptr<RtpReceiverInterface>& receiver :
541 pc()->GetReceivers()) {
deadbeef1dcb1642017-03-29 21:08:16 -0700542 std::unique_ptr<MockRtpReceiverObserver> observer(
543 new MockRtpReceiverObserver(receiver->media_type()));
544 receiver->SetObserver(observer.get());
545 rtp_receiver_observers_.push_back(std::move(observer));
546 }
547 }
548
Steve Antonede9ca52017-10-16 13:04:27 -0700549 rtc::FakeNetworkManager* network() const {
550 return fake_network_manager_.get();
551 }
552 cricket::PortAllocator* port_allocator() const { return port_allocator_; }
553
Qingsi Wang7685e862018-06-11 20:15:46 -0700554 webrtc::FakeRtcEventLogFactory* event_log_factory() const {
555 return event_log_factory_;
556 }
557
deadbeef1dcb1642017-03-29 21:08:16 -0700558 private:
559 explicit PeerConnectionWrapper(const std::string& debug_name)
560 : debug_name_(debug_name) {}
561
Niels Möllerf06f9232018-08-07 12:32:18 +0200562 bool Init(const PeerConnectionFactory::Options* options,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700563 const PeerConnectionInterface::RTCConfiguration* config,
564 webrtc::PeerConnectionDependencies dependencies,
565 rtc::Thread* network_thread,
Qingsi Wang7685e862018-06-11 20:15:46 -0700566 rtc::Thread* worker_thread,
567 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory) {
deadbeef1dcb1642017-03-29 21:08:16 -0700568 // There's an error in this test code if Init ends up being called twice.
569 RTC_DCHECK(!peer_connection_);
570 RTC_DCHECK(!peer_connection_factory_);
571
572 fake_network_manager_.reset(new rtc::FakeNetworkManager());
Steve Antonede9ca52017-10-16 13:04:27 -0700573 fake_network_manager_->AddInterface(kDefaultLocalAddress);
deadbeef1dcb1642017-03-29 21:08:16 -0700574
575 std::unique_ptr<cricket::PortAllocator> port_allocator(
576 new cricket::BasicPortAllocator(fake_network_manager_.get()));
Steve Antonede9ca52017-10-16 13:04:27 -0700577 port_allocator_ = port_allocator.get();
deadbeef1dcb1642017-03-29 21:08:16 -0700578 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
579 if (!fake_audio_capture_module_) {
580 return false;
581 }
deadbeef1dcb1642017-03-29 21:08:16 -0700582 rtc::Thread* const signaling_thread = rtc::Thread::Current();
Qingsi Wang7685e862018-06-11 20:15:46 -0700583
584 webrtc::PeerConnectionFactoryDependencies pc_factory_dependencies;
585 pc_factory_dependencies.network_thread = network_thread;
586 pc_factory_dependencies.worker_thread = worker_thread;
587 pc_factory_dependencies.signaling_thread = signaling_thread;
588 pc_factory_dependencies.media_engine =
589 cricket::WebRtcMediaEngineFactory::Create(
590 rtc::scoped_refptr<webrtc::AudioDeviceModule>(
591 fake_audio_capture_module_),
592 webrtc::CreateBuiltinAudioEncoderFactory(),
593 webrtc::CreateBuiltinAudioDecoderFactory(),
594 webrtc::CreateBuiltinVideoEncoderFactory(),
595 webrtc::CreateBuiltinVideoDecoderFactory(), nullptr,
596 webrtc::AudioProcessingBuilder().Create());
597 pc_factory_dependencies.call_factory = webrtc::CreateCallFactory();
598 if (event_log_factory) {
599 event_log_factory_ = event_log_factory.get();
600 pc_factory_dependencies.event_log_factory = std::move(event_log_factory);
601 } else {
602 pc_factory_dependencies.event_log_factory =
603 webrtc::CreateRtcEventLogFactory();
604 }
605 peer_connection_factory_ = webrtc::CreateModularPeerConnectionFactory(
606 std::move(pc_factory_dependencies));
607
deadbeef1dcb1642017-03-29 21:08:16 -0700608 if (!peer_connection_factory_) {
609 return false;
610 }
611 if (options) {
612 peer_connection_factory_->SetOptions(*options);
613 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800614 if (config) {
615 sdp_semantics_ = config->sdp_semantics;
616 }
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700617
618 dependencies.allocator = std::move(port_allocator);
Niels Möllerf06f9232018-08-07 12:32:18 +0200619 peer_connection_ = CreatePeerConnection(config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700620 return peer_connection_.get() != nullptr;
621 }
622
623 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(
deadbeef1dcb1642017-03-29 21:08:16 -0700624 const PeerConnectionInterface::RTCConfiguration* config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700625 webrtc::PeerConnectionDependencies dependencies) {
deadbeef1dcb1642017-03-29 21:08:16 -0700626 PeerConnectionInterface::RTCConfiguration modified_config;
627 // If |config| is null, this will result in a default configuration being
628 // used.
629 if (config) {
630 modified_config = *config;
631 }
632 // Disable resolution adaptation; we don't want it interfering with the
633 // test results.
634 // TODO(deadbeef): Do something more robust. Since we're testing for aspect
635 // ratios and not specific resolutions, is this even necessary?
636 modified_config.set_cpu_adaptation(false);
637
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700638 dependencies.observer = this;
deadbeef1dcb1642017-03-29 21:08:16 -0700639 return peer_connection_factory_->CreatePeerConnection(
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700640 modified_config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700641 }
642
643 void set_signaling_message_receiver(
644 SignalingMessageReceiver* signaling_message_receiver) {
645 signaling_message_receiver_ = signaling_message_receiver;
646 }
647
648 void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; }
649
Steve Antonede9ca52017-10-16 13:04:27 -0700650 void set_signal_ice_candidates(bool signal) {
651 signal_ice_candidates_ = signal;
652 }
653
deadbeef1dcb1642017-03-29 21:08:16 -0700654 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
Niels Möller5c7efe72018-05-11 10:34:46 +0200655 webrtc::FakePeriodicVideoSource::Config config) {
deadbeef1dcb1642017-03-29 21:08:16 -0700656 // Set max frame rate to 10fps to reduce the risk of test flakiness.
657 // TODO(deadbeef): Do something more robust.
Niels Möller5c7efe72018-05-11 10:34:46 +0200658 config.frame_interval_ms = 100;
deadbeef1dcb1642017-03-29 21:08:16 -0700659
Niels Möller5c7efe72018-05-11 10:34:46 +0200660 video_track_sources_.emplace_back(
Niels Möller0f405822018-05-17 09:16:41 +0200661 new rtc::RefCountedObject<webrtc::FakePeriodicVideoTrackSource>(
662 config, false /* remote */));
deadbeef1dcb1642017-03-29 21:08:16 -0700663 rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
Niels Möller5c7efe72018-05-11 10:34:46 +0200664 peer_connection_factory_->CreateVideoTrack(
665 rtc::CreateRandomUuid(), video_track_sources_.back()));
deadbeef1dcb1642017-03-29 21:08:16 -0700666 if (!local_video_renderer_) {
667 local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
668 }
669 return track;
670 }
671
672 void HandleIncomingOffer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100673 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer";
Steve Antona3a92c22017-12-07 10:27:41 -0800674 std::unique_ptr<SessionDescriptionInterface> desc =
675 webrtc::CreateSessionDescription(SdpType::kOffer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700676 if (received_sdp_munger_) {
677 received_sdp_munger_(desc->description());
678 }
679
680 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
681 // Setting a remote description may have changed the number of receivers,
682 // so reset the receiver observers.
683 ResetRtpReceiverObservers();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800684 if (remote_offer_handler_) {
685 remote_offer_handler_();
686 }
deadbeef1dcb1642017-03-29 21:08:16 -0700687 auto answer = CreateAnswer();
688 ASSERT_NE(nullptr, answer);
689 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
690 }
691
692 void HandleIncomingAnswer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100693 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
Steve Antona3a92c22017-12-07 10:27:41 -0800694 std::unique_ptr<SessionDescriptionInterface> desc =
695 webrtc::CreateSessionDescription(SdpType::kAnswer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700696 if (received_sdp_munger_) {
697 received_sdp_munger_(desc->description());
698 }
699
700 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
701 // Set the RtpReceiverObserver after receivers are created.
702 ResetRtpReceiverObservers();
703 }
704
705 // Returns null on failure.
706 std::unique_ptr<SessionDescriptionInterface> CreateOffer() {
707 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
708 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
709 pc()->CreateOffer(observer, offer_answer_options_);
710 return WaitForDescriptionFromObserver(observer);
711 }
712
713 // Returns null on failure.
714 std::unique_ptr<SessionDescriptionInterface> CreateAnswer() {
715 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
716 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
717 pc()->CreateAnswer(observer, offer_answer_options_);
718 return WaitForDescriptionFromObserver(observer);
719 }
720
721 std::unique_ptr<SessionDescriptionInterface> WaitForDescriptionFromObserver(
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100722 MockCreateSessionDescriptionObserver* observer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700723 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
724 if (!observer->result()) {
725 return nullptr;
726 }
727 auto description = observer->MoveDescription();
728 if (generated_sdp_munger_) {
729 generated_sdp_munger_(description->description());
730 }
731 return description;
732 }
733
734 // Setting the local description and sending the SDP message over the fake
735 // signaling channel are combined into the same method because the SDP
736 // message needs to be sent as soon as SetLocalDescription finishes, without
737 // waiting for the observer to be called. This ensures that ICE candidates
738 // don't outrace the description.
739 bool SetLocalDescriptionAndSendSdpMessage(
740 std::unique_ptr<SessionDescriptionInterface> desc) {
741 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
742 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100743 RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage";
Steve Antona3a92c22017-12-07 10:27:41 -0800744 SdpType type = desc->GetType();
deadbeef1dcb1642017-03-29 21:08:16 -0700745 std::string sdp;
746 EXPECT_TRUE(desc->ToString(&sdp));
747 pc()->SetLocalDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800748 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
749 RemoveUnusedVideoRenderers();
750 }
deadbeef1dcb1642017-03-29 21:08:16 -0700751 // As mentioned above, we need to send the message immediately after
752 // SetLocalDescription.
753 SendSdpMessage(type, sdp);
754 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
755 return true;
756 }
757
758 bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
759 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
760 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100761 RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription";
deadbeef1dcb1642017-03-29 21:08:16 -0700762 pc()->SetRemoteDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800763 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
764 RemoveUnusedVideoRenderers();
765 }
deadbeef1dcb1642017-03-29 21:08:16 -0700766 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
767 return observer->result();
768 }
769
Seth Hampson2f0d7022018-02-20 11:54:42 -0800770 // This is a work around to remove unused fake_video_renderers from
771 // transceivers that have either stopped or are no longer receiving.
772 void RemoveUnusedVideoRenderers() {
773 auto transceivers = pc()->GetTransceivers();
774 for (auto& transceiver : transceivers) {
775 if (transceiver->receiver()->media_type() != cricket::MEDIA_TYPE_VIDEO) {
776 continue;
777 }
778 // Remove fake video renderers from any stopped transceivers.
779 if (transceiver->stopped()) {
780 auto it =
781 fake_video_renderers_.find(transceiver->receiver()->track()->id());
782 if (it != fake_video_renderers_.end()) {
783 fake_video_renderers_.erase(it);
784 }
785 }
786 // Remove fake video renderers from any transceivers that are no longer
787 // receiving.
788 if ((transceiver->current_direction() &&
789 !webrtc::RtpTransceiverDirectionHasRecv(
790 *transceiver->current_direction()))) {
791 auto it =
792 fake_video_renderers_.find(transceiver->receiver()->track()->id());
793 if (it != fake_video_renderers_.end()) {
794 fake_video_renderers_.erase(it);
795 }
796 }
797 }
798 }
799
deadbeef1dcb1642017-03-29 21:08:16 -0700800 // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by
801 // default).
Steve Antona3a92c22017-12-07 10:27:41 -0800802 void SendSdpMessage(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700803 if (signaling_delay_ms_ == 0) {
804 RelaySdpMessageIfReceiverExists(type, msg);
805 } else {
806 invoker_.AsyncInvokeDelayed<void>(
807 RTC_FROM_HERE, rtc::Thread::Current(),
808 rtc::Bind(&PeerConnectionWrapper::RelaySdpMessageIfReceiverExists,
809 this, type, msg),
810 signaling_delay_ms_);
811 }
812 }
813
Steve Antona3a92c22017-12-07 10:27:41 -0800814 void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700815 if (signaling_message_receiver_) {
816 signaling_message_receiver_->ReceiveSdpMessage(type, msg);
817 }
818 }
819
820 // Simulate trickling an ICE candidate with delay |signaling_delay_ms_| (0 by
821 // default).
822 void SendIceMessage(const std::string& sdp_mid,
823 int sdp_mline_index,
824 const std::string& msg) {
825 if (signaling_delay_ms_ == 0) {
826 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
827 } else {
828 invoker_.AsyncInvokeDelayed<void>(
829 RTC_FROM_HERE, rtc::Thread::Current(),
830 rtc::Bind(&PeerConnectionWrapper::RelayIceMessageIfReceiverExists,
831 this, sdp_mid, sdp_mline_index, msg),
832 signaling_delay_ms_);
833 }
834 }
835
836 void RelayIceMessageIfReceiverExists(const std::string& sdp_mid,
837 int sdp_mline_index,
838 const std::string& msg) {
839 if (signaling_message_receiver_) {
840 signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index,
841 msg);
842 }
843 }
844
845 // SignalingMessageReceiver callbacks.
Steve Antona3a92c22017-12-07 10:27:41 -0800846 void ReceiveSdpMessage(SdpType type, const std::string& msg) override {
847 if (type == SdpType::kOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700848 HandleIncomingOffer(msg);
849 } else {
850 HandleIncomingAnswer(msg);
851 }
852 }
853
854 void ReceiveIceMessage(const std::string& sdp_mid,
855 int sdp_mline_index,
856 const std::string& msg) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100857 RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage";
deadbeef1dcb1642017-03-29 21:08:16 -0700858 std::unique_ptr<webrtc::IceCandidateInterface> candidate(
859 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr));
860 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
861 }
862
863 // PeerConnectionObserver callbacks.
864 void OnSignalingChange(
865 webrtc::PeerConnectionInterface::SignalingState new_state) override {
866 EXPECT_EQ(pc()->signaling_state(), new_state);
867 }
Steve Anton15324772018-01-16 10:26:49 -0800868 void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
869 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
870 streams) override {
871 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
872 rtc::scoped_refptr<VideoTrackInterface> video_track(
873 static_cast<VideoTrackInterface*>(receiver->track().get()));
874 ASSERT_TRUE(fake_video_renderers_.find(video_track->id()) ==
deadbeef1dcb1642017-03-29 21:08:16 -0700875 fake_video_renderers_.end());
Steve Anton15324772018-01-16 10:26:49 -0800876 fake_video_renderers_[video_track->id()] =
Karl Wiberg918f50c2018-07-05 11:40:33 +0200877 absl::make_unique<FakeVideoTrackRenderer>(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -0700878 }
879 }
Steve Anton15324772018-01-16 10:26:49 -0800880 void OnRemoveTrack(
881 rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
882 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
883 auto it = fake_video_renderers_.find(receiver->track()->id());
884 RTC_DCHECK(it != fake_video_renderers_.end());
885 fake_video_renderers_.erase(it);
886 }
887 }
deadbeef1dcb1642017-03-29 21:08:16 -0700888 void OnRenegotiationNeeded() override {}
889 void OnIceConnectionChange(
890 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
891 EXPECT_EQ(pc()->ice_connection_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700892 ice_connection_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700893 }
894 void OnIceGatheringChange(
895 webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
deadbeef1dcb1642017-03-29 21:08:16 -0700896 EXPECT_EQ(pc()->ice_gathering_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700897 ice_gathering_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700898 }
899 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100900 RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate";
deadbeef1dcb1642017-03-29 21:08:16 -0700901
902 std::string ice_sdp;
903 EXPECT_TRUE(candidate->ToString(&ice_sdp));
Steve Antonede9ca52017-10-16 13:04:27 -0700904 if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) {
deadbeef1dcb1642017-03-29 21:08:16 -0700905 // Remote party may be deleted.
906 return;
907 }
908 SendIceMessage(candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp);
909 }
910 void OnDataChannel(
911 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100912 RTC_LOG(LS_INFO) << debug_name_ << ": OnDataChannel";
deadbeef1dcb1642017-03-29 21:08:16 -0700913 data_channel_ = data_channel;
914 data_observer_.reset(new MockDataChannelObserver(data_channel));
915 }
916
deadbeef1dcb1642017-03-29 21:08:16 -0700917 std::string debug_name_;
918
919 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
920
921 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
922 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
923 peer_connection_factory_;
924
Steve Antonede9ca52017-10-16 13:04:27 -0700925 cricket::PortAllocator* port_allocator_;
deadbeef1dcb1642017-03-29 21:08:16 -0700926 // Needed to keep track of number of frames sent.
927 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
928 // Needed to keep track of number of frames received.
929 std::map<std::string, std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
930 fake_video_renderers_;
931 // Needed to ensure frames aren't received for removed tracks.
932 std::vector<std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
933 removed_fake_video_renderers_;
deadbeef1dcb1642017-03-29 21:08:16 -0700934
935 // For remote peer communication.
936 SignalingMessageReceiver* signaling_message_receiver_ = nullptr;
937 int signaling_delay_ms_ = 0;
Steve Antonede9ca52017-10-16 13:04:27 -0700938 bool signal_ice_candidates_ = true;
deadbeef1dcb1642017-03-29 21:08:16 -0700939
Niels Möller5c7efe72018-05-11 10:34:46 +0200940 // Store references to the video sources we've created, so that we can stop
deadbeef1dcb1642017-03-29 21:08:16 -0700941 // them, if required.
Niels Möller5c7efe72018-05-11 10:34:46 +0200942 std::vector<rtc::scoped_refptr<webrtc::VideoTrackSource>>
943 video_track_sources_;
deadbeef1dcb1642017-03-29 21:08:16 -0700944 // |local_video_renderer_| attached to the first created local video track.
945 std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
946
Seth Hampson2f0d7022018-02-20 11:54:42 -0800947 SdpSemantics sdp_semantics_;
deadbeef1dcb1642017-03-29 21:08:16 -0700948 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_;
949 std::function<void(cricket::SessionDescription*)> received_sdp_munger_;
950 std::function<void(cricket::SessionDescription*)> generated_sdp_munger_;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800951 std::function<void()> remote_offer_handler_;
deadbeef1dcb1642017-03-29 21:08:16 -0700952
953 rtc::scoped_refptr<DataChannelInterface> data_channel_;
954 std::unique_ptr<MockDataChannelObserver> data_observer_;
955
956 std::vector<std::unique_ptr<MockRtpReceiverObserver>> rtp_receiver_observers_;
957
Steve Antonede9ca52017-10-16 13:04:27 -0700958 std::vector<PeerConnectionInterface::IceConnectionState>
959 ice_connection_state_history_;
960 std::vector<PeerConnectionInterface::IceGatheringState>
961 ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -0700962
Qingsi Wang7685e862018-06-11 20:15:46 -0700963 webrtc::FakeRtcEventLogFactory* event_log_factory_;
964
deadbeef1dcb1642017-03-29 21:08:16 -0700965 rtc::AsyncInvoker invoker_;
966
Seth Hampson2f0d7022018-02-20 11:54:42 -0800967 friend class PeerConnectionIntegrationBaseTest;
deadbeef1dcb1642017-03-29 21:08:16 -0700968};
969
Elad Alon99c3fe52017-10-13 16:29:40 +0200970class MockRtcEventLogOutput : public webrtc::RtcEventLogOutput {
971 public:
972 virtual ~MockRtcEventLogOutput() = default;
973 MOCK_CONST_METHOD0(IsActive, bool());
974 MOCK_METHOD1(Write, bool(const std::string&));
975};
976
Seth Hampson2f0d7022018-02-20 11:54:42 -0800977// This helper object is used for both specifying how many audio/video frames
978// are expected to be received for a caller/callee. It provides helper functions
979// to specify these expectations. The object initially starts in a state of no
980// expectations.
981class MediaExpectations {
982 public:
983 enum ExpectFrames {
984 kExpectSomeFrames,
985 kExpectNoFrames,
986 kNoExpectation,
987 };
988
989 void ExpectBidirectionalAudioAndVideo() {
990 ExpectBidirectionalAudio();
991 ExpectBidirectionalVideo();
992 }
993
994 void ExpectBidirectionalAudio() {
995 CallerExpectsSomeAudio();
996 CalleeExpectsSomeAudio();
997 }
998
999 void ExpectNoAudio() {
1000 CallerExpectsNoAudio();
1001 CalleeExpectsNoAudio();
1002 }
1003
1004 void ExpectBidirectionalVideo() {
1005 CallerExpectsSomeVideo();
1006 CalleeExpectsSomeVideo();
1007 }
1008
1009 void ExpectNoVideo() {
1010 CallerExpectsNoVideo();
1011 CalleeExpectsNoVideo();
1012 }
1013
1014 void CallerExpectsSomeAudioAndVideo() {
1015 CallerExpectsSomeAudio();
1016 CallerExpectsSomeVideo();
1017 }
1018
1019 void CalleeExpectsSomeAudioAndVideo() {
1020 CalleeExpectsSomeAudio();
1021 CalleeExpectsSomeVideo();
1022 }
1023
1024 // Caller's audio functions.
1025 void CallerExpectsSomeAudio(
1026 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1027 caller_audio_expectation_ = kExpectSomeFrames;
1028 caller_audio_frames_expected_ = expected_audio_frames;
1029 }
1030
1031 void CallerExpectsNoAudio() {
1032 caller_audio_expectation_ = kExpectNoFrames;
1033 caller_audio_frames_expected_ = 0;
1034 }
1035
1036 // Caller's video functions.
1037 void CallerExpectsSomeVideo(
1038 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1039 caller_video_expectation_ = kExpectSomeFrames;
1040 caller_video_frames_expected_ = expected_video_frames;
1041 }
1042
1043 void CallerExpectsNoVideo() {
1044 caller_video_expectation_ = kExpectNoFrames;
1045 caller_video_frames_expected_ = 0;
1046 }
1047
1048 // Callee's audio functions.
1049 void CalleeExpectsSomeAudio(
1050 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1051 callee_audio_expectation_ = kExpectSomeFrames;
1052 callee_audio_frames_expected_ = expected_audio_frames;
1053 }
1054
1055 void CalleeExpectsNoAudio() {
1056 callee_audio_expectation_ = kExpectNoFrames;
1057 callee_audio_frames_expected_ = 0;
1058 }
1059
1060 // Callee's video functions.
1061 void CalleeExpectsSomeVideo(
1062 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1063 callee_video_expectation_ = kExpectSomeFrames;
1064 callee_video_frames_expected_ = expected_video_frames;
1065 }
1066
1067 void CalleeExpectsNoVideo() {
1068 callee_video_expectation_ = kExpectNoFrames;
1069 callee_video_frames_expected_ = 0;
1070 }
1071
1072 ExpectFrames caller_audio_expectation_ = kNoExpectation;
1073 ExpectFrames caller_video_expectation_ = kNoExpectation;
1074 ExpectFrames callee_audio_expectation_ = kNoExpectation;
1075 ExpectFrames callee_video_expectation_ = kNoExpectation;
1076 int caller_audio_frames_expected_ = 0;
1077 int caller_video_frames_expected_ = 0;
1078 int callee_audio_frames_expected_ = 0;
1079 int callee_video_frames_expected_ = 0;
1080};
1081
deadbeef1dcb1642017-03-29 21:08:16 -07001082// Tests two PeerConnections connecting to each other end-to-end, using a
1083// virtual network, fake A/V capture and fake encoder/decoders. The
1084// PeerConnections share the threads/socket servers, but use separate versions
1085// of everything else (including "PeerConnectionFactory"s).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001086class PeerConnectionIntegrationBaseTest : public testing::Test {
deadbeef1dcb1642017-03-29 21:08:16 -07001087 public:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001088 explicit PeerConnectionIntegrationBaseTest(SdpSemantics sdp_semantics)
1089 : sdp_semantics_(sdp_semantics),
1090 ss_(new rtc::VirtualSocketServer()),
Steve Antonede9ca52017-10-16 13:04:27 -07001091 fss_(new rtc::FirewallSocketServer(ss_.get())),
1092 network_thread_(new rtc::Thread(fss_.get())),
deadbeef1dcb1642017-03-29 21:08:16 -07001093 worker_thread_(rtc::Thread::Create()) {
Sebastian Jansson8a793a02018-03-13 15:21:48 +01001094 network_thread_->SetName("PCNetworkThread", this);
1095 worker_thread_->SetName("PCWorkerThread", this);
deadbeef1dcb1642017-03-29 21:08:16 -07001096 RTC_CHECK(network_thread_->Start());
1097 RTC_CHECK(worker_thread_->Start());
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001098 webrtc::metrics::Reset();
deadbeef1dcb1642017-03-29 21:08:16 -07001099 }
1100
Seth Hampson2f0d7022018-02-20 11:54:42 -08001101 ~PeerConnectionIntegrationBaseTest() {
Seth Hampsonaed71642018-06-11 07:41:32 -07001102 // The PeerConnections should deleted before the TurnCustomizers.
1103 // A TurnPort is created with a raw pointer to a TurnCustomizer. The
1104 // TurnPort has the same lifetime as the PeerConnection, so it's expected
1105 // that the TurnCustomizer outlives the life of the PeerConnection or else
1106 // when Send() is called it will hit a seg fault.
deadbeef1dcb1642017-03-29 21:08:16 -07001107 if (caller_) {
1108 caller_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001109 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001110 }
1111 if (callee_) {
1112 callee_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001113 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001114 }
Seth Hampsonaed71642018-06-11 07:41:32 -07001115
1116 // If turn servers were created for the test they need to be destroyed on
1117 // the network thread.
1118 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
1119 turn_servers_.clear();
1120 turn_customizers_.clear();
1121 });
deadbeef1dcb1642017-03-29 21:08:16 -07001122 }
1123
1124 bool SignalingStateStable() {
1125 return caller_->SignalingStateStable() && callee_->SignalingStateStable();
1126 }
1127
deadbeef71452802017-05-07 17:21:01 -07001128 bool DtlsConnected() {
1129 // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS
1130 // are connected. This is an important distinction. Once we have separate
1131 // ICE and DTLS state, this check needs to use the DTLS state.
1132 return (callee()->ice_connection_state() ==
1133 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1134 callee()->ice_connection_state() ==
1135 webrtc::PeerConnectionInterface::kIceConnectionCompleted) &&
1136 (caller()->ice_connection_state() ==
1137 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1138 caller()->ice_connection_state() ==
1139 webrtc::PeerConnectionInterface::kIceConnectionCompleted);
1140 }
1141
Qingsi Wang7685e862018-06-11 20:15:46 -07001142 // When |event_log_factory| is null, the default implementation of the event
1143 // log factory will be used.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001144 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWrapper(
1145 const std::string& debug_name,
Seth Hampson2f0d7022018-02-20 11:54:42 -08001146 const PeerConnectionFactory::Options* options,
1147 const RTCConfiguration* config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001148 webrtc::PeerConnectionDependencies dependencies,
1149 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001150 RTCConfiguration modified_config;
1151 if (config) {
1152 modified_config = *config;
1153 }
Steve Anton3acffc32018-04-12 17:21:03 -07001154 modified_config.sdp_semantics = sdp_semantics_;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001155 if (!dependencies.cert_generator) {
1156 dependencies.cert_generator =
Karl Wiberg918f50c2018-07-05 11:40:33 +02001157 absl::make_unique<FakeRTCCertificateGenerator>();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001158 }
1159 std::unique_ptr<PeerConnectionWrapper> client(
1160 new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001161
Niels Möllerf06f9232018-08-07 12:32:18 +02001162 if (!client->Init(options, &modified_config, std::move(dependencies),
1163 network_thread_.get(), worker_thread_.get(),
1164 std::move(event_log_factory))) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001165 return nullptr;
1166 }
1167 return client;
1168 }
1169
Qingsi Wang7685e862018-06-11 20:15:46 -07001170 std::unique_ptr<PeerConnectionWrapper>
1171 CreatePeerConnectionWrapperWithFakeRtcEventLog(
1172 const std::string& debug_name,
Qingsi Wang7685e862018-06-11 20:15:46 -07001173 const PeerConnectionFactory::Options* options,
1174 const RTCConfiguration* config,
1175 webrtc::PeerConnectionDependencies dependencies) {
1176 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory(
1177 new webrtc::FakeRtcEventLogFactory(rtc::Thread::Current()));
Niels Möllerf06f9232018-08-07 12:32:18 +02001178 return CreatePeerConnectionWrapper(debug_name, options, config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001179 std::move(dependencies),
1180 std::move(event_log_factory));
1181 }
1182
deadbeef1dcb1642017-03-29 21:08:16 -07001183 bool CreatePeerConnectionWrappers() {
1184 return CreatePeerConnectionWrappersWithConfig(
1185 PeerConnectionInterface::RTCConfiguration(),
1186 PeerConnectionInterface::RTCConfiguration());
1187 }
1188
Steve Anton3acffc32018-04-12 17:21:03 -07001189 bool CreatePeerConnectionWrappersWithSdpSemantics(
1190 SdpSemantics caller_semantics,
1191 SdpSemantics callee_semantics) {
1192 // Can't specify the sdp_semantics in the passed-in configuration since it
1193 // will be overwritten by CreatePeerConnectionWrapper with whatever is
1194 // stored in sdp_semantics_. So get around this by modifying the instance
1195 // variable before calling CreatePeerConnectionWrapper for the caller and
1196 // callee PeerConnections.
1197 SdpSemantics original_semantics = sdp_semantics_;
1198 sdp_semantics_ = caller_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001199 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001200 "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
1201 nullptr);
Steve Anton3acffc32018-04-12 17:21:03 -07001202 sdp_semantics_ = callee_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001203 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001204 "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
1205 nullptr);
Steve Anton3acffc32018-04-12 17:21:03 -07001206 sdp_semantics_ = original_semantics;
1207 return caller_ && callee_;
1208 }
1209
deadbeef1dcb1642017-03-29 21:08:16 -07001210 bool CreatePeerConnectionWrappersWithConfig(
1211 const PeerConnectionInterface::RTCConfiguration& caller_config,
1212 const PeerConnectionInterface::RTCConfiguration& callee_config) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001213 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001214 "Caller", nullptr, &caller_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001215 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001216 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001217 "Callee", nullptr, &callee_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001218 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001219 return caller_ && callee_;
1220 }
1221
1222 bool CreatePeerConnectionWrappersWithConfigAndDeps(
1223 const PeerConnectionInterface::RTCConfiguration& caller_config,
1224 webrtc::PeerConnectionDependencies caller_dependencies,
1225 const PeerConnectionInterface::RTCConfiguration& callee_config,
1226 webrtc::PeerConnectionDependencies callee_dependencies) {
1227 caller_ =
Niels Möllerf06f9232018-08-07 12:32:18 +02001228 CreatePeerConnectionWrapper("Caller", nullptr, &caller_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001229 std::move(caller_dependencies), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001230 callee_ =
Niels Möllerf06f9232018-08-07 12:32:18 +02001231 CreatePeerConnectionWrapper("Callee", nullptr, &callee_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001232 std::move(callee_dependencies), nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001233 return caller_ && callee_;
1234 }
1235
1236 bool CreatePeerConnectionWrappersWithOptions(
1237 const PeerConnectionFactory::Options& caller_options,
1238 const PeerConnectionFactory::Options& callee_options) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001239 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001240 "Caller", &caller_options, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001241 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001242 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001243 "Callee", &callee_options, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001244 webrtc::PeerConnectionDependencies(nullptr), nullptr);
1245 return caller_ && callee_;
1246 }
1247
1248 bool CreatePeerConnectionWrappersWithFakeRtcEventLog() {
1249 PeerConnectionInterface::RTCConfiguration default_config;
1250 caller_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001251 "Caller", nullptr, &default_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001252 webrtc::PeerConnectionDependencies(nullptr));
1253 callee_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001254 "Callee", nullptr, &default_config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001255 webrtc::PeerConnectionDependencies(nullptr));
deadbeef1dcb1642017-03-29 21:08:16 -07001256 return caller_ && callee_;
1257 }
1258
Seth Hampson2f0d7022018-02-20 11:54:42 -08001259 std::unique_ptr<PeerConnectionWrapper>
1260 CreatePeerConnectionWrapperWithAlternateKey() {
deadbeef1dcb1642017-03-29 21:08:16 -07001261 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
1262 new FakeRTCCertificateGenerator());
1263 cert_generator->use_alternate_key();
1264
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001265 webrtc::PeerConnectionDependencies dependencies(nullptr);
1266 dependencies.cert_generator = std::move(cert_generator);
Niels Möllerf06f9232018-08-07 12:32:18 +02001267 return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001268 std::move(dependencies), nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001269 }
1270
Seth Hampsonaed71642018-06-11 07:41:32 -07001271 cricket::TestTurnServer* CreateTurnServer(
1272 rtc::SocketAddress internal_address,
1273 rtc::SocketAddress external_address,
1274 cricket::ProtocolType type = cricket::ProtocolType::PROTO_UDP,
1275 const std::string& common_name = "test turn server") {
1276 rtc::Thread* thread = network_thread();
1277 std::unique_ptr<cricket::TestTurnServer> turn_server =
1278 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnServer>>(
1279 RTC_FROM_HERE,
1280 [thread, internal_address, external_address, type, common_name] {
Karl Wiberg918f50c2018-07-05 11:40:33 +02001281 return absl::make_unique<cricket::TestTurnServer>(
Seth Hampsonaed71642018-06-11 07:41:32 -07001282 thread, internal_address, external_address, type,
1283 /*ignore_bad_certs=*/true, common_name);
1284 });
1285 turn_servers_.push_back(std::move(turn_server));
1286 // Interactions with the turn server should be done on the network thread.
1287 return turn_servers_.back().get();
1288 }
1289
1290 cricket::TestTurnCustomizer* CreateTurnCustomizer() {
1291 std::unique_ptr<cricket::TestTurnCustomizer> turn_customizer =
1292 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnCustomizer>>(
1293 RTC_FROM_HERE,
Karl Wiberg918f50c2018-07-05 11:40:33 +02001294 [] { return absl::make_unique<cricket::TestTurnCustomizer>(); });
Seth Hampsonaed71642018-06-11 07:41:32 -07001295 turn_customizers_.push_back(std::move(turn_customizer));
1296 // Interactions with the turn customizer should be done on the network
1297 // thread.
1298 return turn_customizers_.back().get();
1299 }
1300
1301 // Checks that the function counters for a TestTurnCustomizer are greater than
1302 // 0.
1303 void ExpectTurnCustomizerCountersIncremented(
1304 cricket::TestTurnCustomizer* turn_customizer) {
1305 unsigned int allow_channel_data_counter =
1306 network_thread()->Invoke<unsigned int>(
1307 RTC_FROM_HERE, [turn_customizer] {
1308 return turn_customizer->allow_channel_data_cnt_;
1309 });
1310 EXPECT_GT(allow_channel_data_counter, 0u);
1311 unsigned int modify_counter = network_thread()->Invoke<unsigned int>(
1312 RTC_FROM_HERE,
1313 [turn_customizer] { return turn_customizer->modify_cnt_; });
1314 EXPECT_GT(modify_counter, 0u);
1315 }
1316
deadbeef1dcb1642017-03-29 21:08:16 -07001317 // Once called, SDP blobs and ICE candidates will be automatically signaled
1318 // between PeerConnections.
1319 void ConnectFakeSignaling() {
1320 caller_->set_signaling_message_receiver(callee_.get());
1321 callee_->set_signaling_message_receiver(caller_.get());
1322 }
1323
Steve Antonede9ca52017-10-16 13:04:27 -07001324 // Once called, SDP blobs will be automatically signaled between
1325 // PeerConnections. Note that ICE candidates will not be signaled unless they
1326 // are in the exchanged SDP blobs.
1327 void ConnectFakeSignalingForSdpOnly() {
1328 ConnectFakeSignaling();
1329 SetSignalIceCandidates(false);
1330 }
1331
deadbeef1dcb1642017-03-29 21:08:16 -07001332 void SetSignalingDelayMs(int delay_ms) {
1333 caller_->set_signaling_delay_ms(delay_ms);
1334 callee_->set_signaling_delay_ms(delay_ms);
1335 }
1336
Steve Antonede9ca52017-10-16 13:04:27 -07001337 void SetSignalIceCandidates(bool signal) {
1338 caller_->set_signal_ice_candidates(signal);
1339 callee_->set_signal_ice_candidates(signal);
1340 }
1341
deadbeef1dcb1642017-03-29 21:08:16 -07001342 // Messages may get lost on the unreliable DataChannel, so we send multiple
1343 // times to avoid test flakiness.
1344 void SendRtpDataWithRetries(webrtc::DataChannelInterface* dc,
1345 const std::string& data,
1346 int retries) {
1347 for (int i = 0; i < retries; ++i) {
1348 dc->Send(DataBuffer(data));
1349 }
1350 }
1351
1352 rtc::Thread* network_thread() { return network_thread_.get(); }
1353
1354 rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); }
1355
1356 PeerConnectionWrapper* caller() { return caller_.get(); }
1357
1358 // Set the |caller_| to the |wrapper| passed in and return the
1359 // original |caller_|.
1360 PeerConnectionWrapper* SetCallerPcWrapperAndReturnCurrent(
1361 PeerConnectionWrapper* wrapper) {
1362 PeerConnectionWrapper* old = caller_.release();
1363 caller_.reset(wrapper);
1364 return old;
1365 }
1366
1367 PeerConnectionWrapper* callee() { return callee_.get(); }
1368
1369 // Set the |callee_| to the |wrapper| passed in and return the
1370 // original |callee_|.
1371 PeerConnectionWrapper* SetCalleePcWrapperAndReturnCurrent(
1372 PeerConnectionWrapper* wrapper) {
1373 PeerConnectionWrapper* old = callee_.release();
1374 callee_.reset(wrapper);
1375 return old;
1376 }
1377
Steve Antonede9ca52017-10-16 13:04:27 -07001378 rtc::FirewallSocketServer* firewall() const { return fss_.get(); }
1379
Seth Hampson2f0d7022018-02-20 11:54:42 -08001380 // Expects the provided number of new frames to be received within
1381 // kMaxWaitForFramesMs. The new expected frames are specified in
1382 // |media_expectations|. Returns false if any of the expectations were
1383 // not met.
1384 bool ExpectNewFrames(const MediaExpectations& media_expectations) {
1385 // First initialize the expected frame counts based upon the current
1386 // frame count.
1387 int total_caller_audio_frames_expected = caller()->audio_frames_received();
1388 if (media_expectations.caller_audio_expectation_ ==
1389 MediaExpectations::kExpectSomeFrames) {
1390 total_caller_audio_frames_expected +=
1391 media_expectations.caller_audio_frames_expected_;
1392 }
1393 int total_caller_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001394 caller()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001395 if (media_expectations.caller_video_expectation_ ==
1396 MediaExpectations::kExpectSomeFrames) {
1397 total_caller_video_frames_expected +=
1398 media_expectations.caller_video_frames_expected_;
1399 }
1400 int total_callee_audio_frames_expected = callee()->audio_frames_received();
1401 if (media_expectations.callee_audio_expectation_ ==
1402 MediaExpectations::kExpectSomeFrames) {
1403 total_callee_audio_frames_expected +=
1404 media_expectations.callee_audio_frames_expected_;
1405 }
1406 int total_callee_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001407 callee()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001408 if (media_expectations.callee_video_expectation_ ==
1409 MediaExpectations::kExpectSomeFrames) {
1410 total_callee_video_frames_expected +=
1411 media_expectations.callee_video_frames_expected_;
1412 }
deadbeef1dcb1642017-03-29 21:08:16 -07001413
Seth Hampson2f0d7022018-02-20 11:54:42 -08001414 // Wait for the expected frames.
deadbeef1dcb1642017-03-29 21:08:16 -07001415 EXPECT_TRUE_WAIT(caller()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001416 total_caller_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001417 caller()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001418 total_caller_video_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001419 callee()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001420 total_callee_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001421 callee()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001422 total_callee_video_frames_expected,
1423 kMaxWaitForFramesMs);
1424 bool expectations_correct =
1425 caller()->audio_frames_received() >=
1426 total_caller_audio_frames_expected &&
1427 caller()->min_video_frames_received_per_track() >=
1428 total_caller_video_frames_expected &&
1429 callee()->audio_frames_received() >=
1430 total_callee_audio_frames_expected &&
1431 callee()->min_video_frames_received_per_track() >=
1432 total_callee_video_frames_expected;
deadbeef1dcb1642017-03-29 21:08:16 -07001433
Seth Hampson2f0d7022018-02-20 11:54:42 -08001434 // After the combined wait, print out a more detailed message upon
1435 // failure.
deadbeef1dcb1642017-03-29 21:08:16 -07001436 EXPECT_GE(caller()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001437 total_caller_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001438 EXPECT_GE(caller()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001439 total_caller_video_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001440 EXPECT_GE(callee()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001441 total_callee_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001442 EXPECT_GE(callee()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001443 total_callee_video_frames_expected);
1444
1445 // We want to make sure nothing unexpected was received.
1446 if (media_expectations.caller_audio_expectation_ ==
1447 MediaExpectations::kExpectNoFrames) {
1448 EXPECT_EQ(caller()->audio_frames_received(),
1449 total_caller_audio_frames_expected);
1450 if (caller()->audio_frames_received() !=
1451 total_caller_audio_frames_expected) {
1452 expectations_correct = false;
1453 }
1454 }
1455 if (media_expectations.caller_video_expectation_ ==
1456 MediaExpectations::kExpectNoFrames) {
1457 EXPECT_EQ(caller()->min_video_frames_received_per_track(),
1458 total_caller_video_frames_expected);
1459 if (caller()->min_video_frames_received_per_track() !=
1460 total_caller_video_frames_expected) {
1461 expectations_correct = false;
1462 }
1463 }
1464 if (media_expectations.callee_audio_expectation_ ==
1465 MediaExpectations::kExpectNoFrames) {
1466 EXPECT_EQ(callee()->audio_frames_received(),
1467 total_callee_audio_frames_expected);
1468 if (callee()->audio_frames_received() !=
1469 total_callee_audio_frames_expected) {
1470 expectations_correct = false;
1471 }
1472 }
1473 if (media_expectations.callee_video_expectation_ ==
1474 MediaExpectations::kExpectNoFrames) {
1475 EXPECT_EQ(callee()->min_video_frames_received_per_track(),
1476 total_callee_video_frames_expected);
1477 if (callee()->min_video_frames_received_per_track() !=
1478 total_callee_video_frames_expected) {
1479 expectations_correct = false;
1480 }
1481 }
1482 return expectations_correct;
deadbeef1dcb1642017-03-29 21:08:16 -07001483 }
1484
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001485 void TestNegotiatedCipherSuite(
1486 const PeerConnectionFactory::Options& caller_options,
1487 const PeerConnectionFactory::Options& callee_options,
1488 int expected_cipher_suite) {
deadbeef1dcb1642017-03-29 21:08:16 -07001489 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options,
1490 callee_options));
deadbeef1dcb1642017-03-29 21:08:16 -07001491 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001492 caller()->AddAudioVideoTracks();
1493 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001494 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001495 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001496 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite),
deadbeefd8ad7882017-04-18 16:01:17 -07001497 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001498 // TODO(bugs.webrtc.org/9456): Fix it.
1499 EXPECT_EQ(1, webrtc::metrics::NumEvents(
1500 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1501 expected_cipher_suite));
deadbeef1dcb1642017-03-29 21:08:16 -07001502 }
1503
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001504 void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
1505 bool remote_gcm_enabled,
1506 int expected_cipher_suite) {
1507 PeerConnectionFactory::Options caller_options;
1508 caller_options.crypto_options.enable_gcm_crypto_suites = local_gcm_enabled;
1509 PeerConnectionFactory::Options callee_options;
1510 callee_options.crypto_options.enable_gcm_crypto_suites = remote_gcm_enabled;
1511 TestNegotiatedCipherSuite(caller_options, callee_options,
1512 expected_cipher_suite);
1513 }
1514
Seth Hampson2f0d7022018-02-20 11:54:42 -08001515 protected:
Steve Anton3acffc32018-04-12 17:21:03 -07001516 SdpSemantics sdp_semantics_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001517
deadbeef1dcb1642017-03-29 21:08:16 -07001518 private:
1519 // |ss_| is used by |network_thread_| so it must be destroyed later.
deadbeef1dcb1642017-03-29 21:08:16 -07001520 std::unique_ptr<rtc::VirtualSocketServer> ss_;
Steve Antonede9ca52017-10-16 13:04:27 -07001521 std::unique_ptr<rtc::FirewallSocketServer> fss_;
deadbeef1dcb1642017-03-29 21:08:16 -07001522 // |network_thread_| and |worker_thread_| are used by both
1523 // |caller_| and |callee_| so they must be destroyed
1524 // later.
1525 std::unique_ptr<rtc::Thread> network_thread_;
1526 std::unique_ptr<rtc::Thread> worker_thread_;
Seth Hampsonaed71642018-06-11 07:41:32 -07001527 // The turn servers and turn customizers should be accessed & deleted on the
1528 // network thread to avoid a race with the socket read/write that occurs
1529 // on the network thread.
1530 std::vector<std::unique_ptr<cricket::TestTurnServer>> turn_servers_;
1531 std::vector<std::unique_ptr<cricket::TestTurnCustomizer>> turn_customizers_;
deadbeef1dcb1642017-03-29 21:08:16 -07001532 std::unique_ptr<PeerConnectionWrapper> caller_;
1533 std::unique_ptr<PeerConnectionWrapper> callee_;
1534};
1535
Seth Hampson2f0d7022018-02-20 11:54:42 -08001536class PeerConnectionIntegrationTest
1537 : public PeerConnectionIntegrationBaseTest,
1538 public ::testing::WithParamInterface<SdpSemantics> {
1539 protected:
1540 PeerConnectionIntegrationTest()
1541 : PeerConnectionIntegrationBaseTest(GetParam()) {}
1542};
1543
1544class PeerConnectionIntegrationTestPlanB
1545 : public PeerConnectionIntegrationBaseTest {
1546 protected:
1547 PeerConnectionIntegrationTestPlanB()
1548 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
1549};
1550
1551class PeerConnectionIntegrationTestUnifiedPlan
1552 : public PeerConnectionIntegrationBaseTest {
1553 protected:
1554 PeerConnectionIntegrationTestUnifiedPlan()
1555 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
1556};
1557
deadbeef1dcb1642017-03-29 21:08:16 -07001558// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
1559// includes testing that the callback is invoked if an observer is connected
1560// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001561TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001562 RtpReceiverObserverOnFirstPacketReceived) {
1563 ASSERT_TRUE(CreatePeerConnectionWrappers());
1564 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001565 caller()->AddAudioVideoTracks();
1566 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001567 // Start offer/answer exchange and wait for it to complete.
1568 caller()->CreateAndSetAndSignalOffer();
1569 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1570 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001571 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1572 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001573 // Wait for all "first packet received" callbacks to be fired.
1574 EXPECT_TRUE_WAIT(
1575 std::all_of(caller()->rtp_receiver_observers().begin(),
1576 caller()->rtp_receiver_observers().end(),
1577 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1578 return o->first_packet_received();
1579 }),
1580 kMaxWaitForFramesMs);
1581 EXPECT_TRUE_WAIT(
1582 std::all_of(callee()->rtp_receiver_observers().begin(),
1583 callee()->rtp_receiver_observers().end(),
1584 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1585 return o->first_packet_received();
1586 }),
1587 kMaxWaitForFramesMs);
1588 // If new observers are set after the first packet was already received, the
1589 // callback should still be invoked.
1590 caller()->ResetRtpReceiverObservers();
1591 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001592 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1593 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001594 EXPECT_TRUE(
1595 std::all_of(caller()->rtp_receiver_observers().begin(),
1596 caller()->rtp_receiver_observers().end(),
1597 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1598 return o->first_packet_received();
1599 }));
1600 EXPECT_TRUE(
1601 std::all_of(callee()->rtp_receiver_observers().begin(),
1602 callee()->rtp_receiver_observers().end(),
1603 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1604 return o->first_packet_received();
1605 }));
1606}
1607
1608class DummyDtmfObserver : public DtmfSenderObserverInterface {
1609 public:
1610 DummyDtmfObserver() : completed_(false) {}
1611
1612 // Implements DtmfSenderObserverInterface.
1613 void OnToneChange(const std::string& tone) override {
1614 tones_.push_back(tone);
1615 if (tone.empty()) {
1616 completed_ = true;
1617 }
1618 }
1619
1620 const std::vector<std::string>& tones() const { return tones_; }
1621 bool completed() const { return completed_; }
1622
1623 private:
1624 bool completed_;
1625 std::vector<std::string> tones_;
1626};
1627
1628// Assumes |sender| already has an audio track added and the offer/answer
1629// exchange is done.
1630void TestDtmfFromSenderToReceiver(PeerConnectionWrapper* sender,
1631 PeerConnectionWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -08001632 // We should be able to get a DTMF sender from the local sender.
1633 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
1634 sender->pc()->GetSenders().at(0)->GetDtmfSender();
1635 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -07001636 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -07001637 dtmf_sender->RegisterObserver(&observer);
1638
1639 // Test the DtmfSender object just created.
1640 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
1641 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
1642
1643 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
1644 std::vector<std::string> tones = {"1", "a", ""};
1645 EXPECT_EQ(tones, observer.tones());
1646 dtmf_sender->UnregisterObserver();
1647 // TODO(deadbeef): Verify the tones were actually received end-to-end.
1648}
1649
1650// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
1651// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001652TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -07001653 ASSERT_TRUE(CreatePeerConnectionWrappers());
1654 ConnectFakeSignaling();
1655 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -08001656 caller()->AddAudioTrack();
1657 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001658 caller()->CreateAndSetAndSignalOffer();
1659 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -07001660 // DTLS must finish before the DTMF sender can be used reliably.
1661 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001662 TestDtmfFromSenderToReceiver(caller(), callee());
1663 TestDtmfFromSenderToReceiver(callee(), caller());
1664}
1665
1666// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
1667// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001668TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -07001669 ASSERT_TRUE(CreatePeerConnectionWrappers());
1670 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +01001671
deadbeef1dcb1642017-03-29 21:08:16 -07001672 // Do normal offer/answer and wait for some frames to be received in each
1673 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001674 caller()->AddAudioVideoTracks();
1675 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001676 caller()->CreateAndSetAndSignalOffer();
1677 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001678 MediaExpectations media_expectations;
1679 media_expectations.ExpectBidirectionalAudioAndVideo();
1680 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001681 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1682 webrtc::kEnumCounterKeyProtocolDtls));
1683 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1684 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -07001685}
1686
1687// Uses SDES instead of DTLS for key agreement.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001688TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
deadbeef1dcb1642017-03-29 21:08:16 -07001689 PeerConnectionInterface::RTCConfiguration sdes_config;
1690 sdes_config.enable_dtls_srtp.emplace(false);
1691 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
1692 ConnectFakeSignaling();
1693
1694 // Do normal offer/answer and wait for some frames to be received in each
1695 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001696 caller()->AddAudioVideoTracks();
1697 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001698 caller()->CreateAndSetAndSignalOffer();
1699 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001700 MediaExpectations media_expectations;
1701 media_expectations.ExpectBidirectionalAudioAndVideo();
1702 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001703 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1704 webrtc::kEnumCounterKeyProtocolSdes));
1705 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1706 webrtc::kEnumCounterKeyProtocolDtls));
deadbeef1dcb1642017-03-29 21:08:16 -07001707}
1708
Steve Anton8c0f7a72017-10-03 10:03:10 -07001709// Tests that the GetRemoteAudioSSLCertificate method returns the remote DTLS
1710// certificate once the DTLS handshake has finished.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001711TEST_P(PeerConnectionIntegrationTest,
Steve Anton8c0f7a72017-10-03 10:03:10 -07001712 GetRemoteAudioSSLCertificateReturnsExchangedCertificate) {
1713 auto GetRemoteAudioSSLCertificate = [](PeerConnectionWrapper* wrapper) {
1714 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1715 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1716 return pc->GetRemoteAudioSSLCertificate();
1717 };
Zhi Huang70b820f2018-01-27 14:16:15 -08001718 auto GetRemoteAudioSSLCertChain = [](PeerConnectionWrapper* wrapper) {
1719 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1720 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1721 return pc->GetRemoteAudioSSLCertChain();
1722 };
Steve Anton8c0f7a72017-10-03 10:03:10 -07001723
1724 auto caller_cert = rtc::RTCCertificate::FromPEM(kRsaPems[0]);
1725 auto callee_cert = rtc::RTCCertificate::FromPEM(kRsaPems[1]);
1726
1727 // Configure each side with a known certificate so they can be compared later.
1728 PeerConnectionInterface::RTCConfiguration caller_config;
1729 caller_config.enable_dtls_srtp.emplace(true);
1730 caller_config.certificates.push_back(caller_cert);
1731 PeerConnectionInterface::RTCConfiguration callee_config;
1732 callee_config.enable_dtls_srtp.emplace(true);
1733 callee_config.certificates.push_back(callee_cert);
1734 ASSERT_TRUE(
1735 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
1736 ConnectFakeSignaling();
1737
1738 // When first initialized, there should not be a remote SSL certificate (and
1739 // calling this method should not crash).
1740 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(caller()));
1741 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(callee()));
Zhi Huang70b820f2018-01-27 14:16:15 -08001742 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(caller()));
1743 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(callee()));
Steve Anton8c0f7a72017-10-03 10:03:10 -07001744
Steve Anton15324772018-01-16 10:26:49 -08001745 caller()->AddAudioTrack();
1746 callee()->AddAudioTrack();
Steve Anton8c0f7a72017-10-03 10:03:10 -07001747 caller()->CreateAndSetAndSignalOffer();
1748 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1749 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
1750
1751 // Once DTLS has been connected, each side should return the other's SSL
1752 // certificate when calling GetRemoteAudioSSLCertificate.
1753
1754 auto caller_remote_cert = GetRemoteAudioSSLCertificate(caller());
1755 ASSERT_TRUE(caller_remote_cert);
1756 EXPECT_EQ(callee_cert->ssl_certificate().ToPEMString(),
1757 caller_remote_cert->ToPEMString());
1758
1759 auto callee_remote_cert = GetRemoteAudioSSLCertificate(callee());
1760 ASSERT_TRUE(callee_remote_cert);
1761 EXPECT_EQ(caller_cert->ssl_certificate().ToPEMString(),
1762 callee_remote_cert->ToPEMString());
Zhi Huang70b820f2018-01-27 14:16:15 -08001763
1764 auto caller_remote_cert_chain = GetRemoteAudioSSLCertChain(caller());
1765 ASSERT_TRUE(caller_remote_cert_chain);
1766 ASSERT_EQ(1U, caller_remote_cert_chain->GetSize());
1767 auto remote_cert = &caller_remote_cert_chain->Get(0);
1768 EXPECT_EQ(callee_cert->ssl_certificate().ToPEMString(),
1769 remote_cert->ToPEMString());
1770
1771 auto callee_remote_cert_chain = GetRemoteAudioSSLCertChain(callee());
1772 ASSERT_TRUE(callee_remote_cert_chain);
1773 ASSERT_EQ(1U, callee_remote_cert_chain->GetSize());
1774 remote_cert = &callee_remote_cert_chain->Get(0);
1775 EXPECT_EQ(caller_cert->ssl_certificate().ToPEMString(),
1776 remote_cert->ToPEMString());
Steve Anton8c0f7a72017-10-03 10:03:10 -07001777}
1778
deadbeef1dcb1642017-03-29 21:08:16 -07001779// This test sets up a call between two parties with a source resolution of
1780// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001781TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001782 Send1280By720ResolutionAndReceive16To9AspectRatio) {
1783 ASSERT_TRUE(CreatePeerConnectionWrappers());
1784 ConnectFakeSignaling();
1785
Niels Möller5c7efe72018-05-11 10:34:46 +02001786 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
1787 webrtc::FakePeriodicVideoSource::Config config;
1788 config.width = 1280;
1789 config.height = 720;
1790 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
1791 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -07001792
1793 // Do normal offer/answer and wait for at least one frame to be received in
1794 // each direction.
1795 caller()->CreateAndSetAndSignalOffer();
1796 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
1797 callee()->min_video_frames_received_per_track() > 0,
1798 kMaxWaitForFramesMs);
1799
1800 // Check rendered aspect ratio.
1801 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
1802 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
1803 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
1804 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
1805}
1806
1807// This test sets up an one-way call, with media only from caller to
1808// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001809TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -07001810 ASSERT_TRUE(CreatePeerConnectionWrappers());
1811 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001812 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001813 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001814 MediaExpectations media_expectations;
1815 media_expectations.CalleeExpectsSomeAudioAndVideo();
1816 media_expectations.CallerExpectsNoAudio();
1817 media_expectations.CallerExpectsNoVideo();
1818 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001819}
1820
1821// This test sets up a audio call initially, with the callee rejecting video
1822// initially. Then later the callee decides to upgrade to audio/video, and
1823// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001824TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -07001825 ASSERT_TRUE(CreatePeerConnectionWrappers());
1826 ConnectFakeSignaling();
1827 // Initially, offer an audio/video stream from the caller, but refuse to
1828 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -08001829 caller()->AddAudioVideoTracks();
1830 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001831 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1832 PeerConnectionInterface::RTCOfferAnswerOptions options;
1833 options.offer_to_receive_video = 0;
1834 callee()->SetOfferAnswerOptions(options);
1835 } else {
1836 callee()->SetRemoteOfferHandler([this] {
1837 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
1838 });
1839 }
deadbeef1dcb1642017-03-29 21:08:16 -07001840 // Do offer/answer and make sure audio is still received end-to-end.
1841 caller()->CreateAndSetAndSignalOffer();
1842 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001843 {
1844 MediaExpectations media_expectations;
1845 media_expectations.ExpectBidirectionalAudio();
1846 media_expectations.ExpectNoVideo();
1847 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1848 }
deadbeef1dcb1642017-03-29 21:08:16 -07001849 // Sanity check that the callee's description has a rejected video section.
1850 ASSERT_NE(nullptr, callee()->pc()->local_description());
1851 const ContentInfo* callee_video_content =
1852 GetFirstVideoContent(callee()->pc()->local_description()->description());
1853 ASSERT_NE(nullptr, callee_video_content);
1854 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001855
deadbeef1dcb1642017-03-29 21:08:16 -07001856 // Now negotiate with video and ensure negotiation succeeds, with video
1857 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -08001858 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001859 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1860 PeerConnectionInterface::RTCOfferAnswerOptions options;
1861 options.offer_to_receive_video = 1;
1862 callee()->SetOfferAnswerOptions(options);
1863 } else {
1864 callee()->SetRemoteOfferHandler(nullptr);
1865 caller()->SetRemoteOfferHandler([this] {
1866 // The caller creates a new transceiver to receive video on when receiving
1867 // the offer, but by default it is send only.
1868 auto transceivers = caller()->pc()->GetTransceivers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001869 ASSERT_EQ(3U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08001870 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
1871 transceivers[2]->receiver()->media_type());
1872 transceivers[2]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
1873 transceivers[2]->SetDirection(RtpTransceiverDirection::kSendRecv);
1874 });
1875 }
deadbeef1dcb1642017-03-29 21:08:16 -07001876 callee()->CreateAndSetAndSignalOffer();
1877 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001878 {
1879 // Expect additional audio frames to be received after the upgrade.
1880 MediaExpectations media_expectations;
1881 media_expectations.ExpectBidirectionalAudioAndVideo();
1882 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1883 }
deadbeef1dcb1642017-03-29 21:08:16 -07001884}
1885
deadbeef4389b4d2017-09-07 09:07:36 -07001886// Simpler than the above test; just add an audio track to an established
1887// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001888TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -07001889 ASSERT_TRUE(CreatePeerConnectionWrappers());
1890 ConnectFakeSignaling();
1891 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -08001892 caller()->AddVideoTrack();
1893 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07001894 caller()->CreateAndSetAndSignalOffer();
1895 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1896 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001897 caller()->AddAudioTrack();
1898 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07001899 caller()->CreateAndSetAndSignalOffer();
1900 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1901 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001902 MediaExpectations media_expectations;
1903 media_expectations.ExpectBidirectionalAudioAndVideo();
1904 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -07001905}
1906
deadbeef1dcb1642017-03-29 21:08:16 -07001907// This test sets up a call that's transferred to a new caller with a different
1908// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001909TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -07001910 ASSERT_TRUE(CreatePeerConnectionWrappers());
1911 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001912 caller()->AddAudioVideoTracks();
1913 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001914 caller()->CreateAndSetAndSignalOffer();
1915 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1916
1917 // Keep the original peer around which will still send packets to the
1918 // receiving client. These SRTP packets will be dropped.
1919 std::unique_ptr<PeerConnectionWrapper> original_peer(
1920 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08001921 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07001922 // TODO(deadbeef): Why do we call Close here? That goes against the comment
1923 // directly above.
1924 original_peer->pc()->Close();
1925
1926 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001927 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001928 caller()->CreateAndSetAndSignalOffer();
1929 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1930 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001931 MediaExpectations media_expectations;
1932 media_expectations.ExpectBidirectionalAudioAndVideo();
1933 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001934}
1935
1936// This test sets up a call that's transferred to a new callee with a different
1937// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001938TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -07001939 ASSERT_TRUE(CreatePeerConnectionWrappers());
1940 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001941 caller()->AddAudioVideoTracks();
1942 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001943 caller()->CreateAndSetAndSignalOffer();
1944 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1945
1946 // Keep the original peer around which will still send packets to the
1947 // receiving client. These SRTP packets will be dropped.
1948 std::unique_ptr<PeerConnectionWrapper> original_peer(
1949 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08001950 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07001951 // TODO(deadbeef): Why do we call Close here? That goes against the comment
1952 // directly above.
1953 original_peer->pc()->Close();
1954
1955 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001956 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001957 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
1958 caller()->CreateAndSetAndSignalOffer();
1959 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1960 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001961 MediaExpectations media_expectations;
1962 media_expectations.ExpectBidirectionalAudioAndVideo();
1963 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001964}
1965
1966// This test sets up a non-bundled call and negotiates bundling at the same
1967// time as starting an ICE restart. When bundling is in effect in the restart,
1968// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001969TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -07001970 ASSERT_TRUE(CreatePeerConnectionWrappers());
1971 ConnectFakeSignaling();
1972
Steve Anton15324772018-01-16 10:26:49 -08001973 caller()->AddAudioVideoTracks();
1974 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001975 // Remove the bundle group from the SDP received by the callee.
1976 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
1977 desc->RemoveGroupByName("BUNDLE");
1978 });
1979 caller()->CreateAndSetAndSignalOffer();
1980 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001981 {
1982 MediaExpectations media_expectations;
1983 media_expectations.ExpectBidirectionalAudioAndVideo();
1984 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1985 }
deadbeef1dcb1642017-03-29 21:08:16 -07001986 // Now stop removing the BUNDLE group, and trigger an ICE restart.
1987 callee()->SetReceivedSdpMunger(nullptr);
1988 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
1989 caller()->CreateAndSetAndSignalOffer();
1990 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1991
1992 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001993 {
1994 MediaExpectations media_expectations;
1995 media_expectations.ExpectBidirectionalAudioAndVideo();
1996 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1997 }
deadbeef1dcb1642017-03-29 21:08:16 -07001998}
1999
2000// Test CVO (Coordination of Video Orientation). If a video source is rotated
2001// and both peers support the CVO RTP header extension, the actual video frames
2002// don't need to be encoded in different resolutions, since the rotation is
2003// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002004TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002005 ASSERT_TRUE(CreatePeerConnectionWrappers());
2006 ConnectFakeSignaling();
2007 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002008 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002009 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002010 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002011 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2012
2013 // Wait for video frames to be received by both sides.
2014 caller()->CreateAndSetAndSignalOffer();
2015 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2016 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2017 callee()->min_video_frames_received_per_track() > 0,
2018 kMaxWaitForFramesMs);
2019
2020 // Ensure that the aspect ratio is unmodified.
2021 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2022 // not just assumed.
2023 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
2024 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
2025 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
2026 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
2027 // Ensure that the CVO bits were surfaced to the renderer.
2028 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
2029 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
2030}
2031
2032// Test that when the CVO extension isn't supported, video is rotated the
2033// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002034TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002035 ASSERT_TRUE(CreatePeerConnectionWrappers());
2036 ConnectFakeSignaling();
2037 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002038 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002039 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002040 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002041 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2042
2043 // Remove the CVO extension from the offered SDP.
2044 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2045 cricket::VideoContentDescription* video =
2046 GetFirstVideoContentDescription(desc);
2047 video->ClearRtpHeaderExtensions();
2048 });
2049 // Wait for video frames to be received by both sides.
2050 caller()->CreateAndSetAndSignalOffer();
2051 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2052 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2053 callee()->min_video_frames_received_per_track() > 0,
2054 kMaxWaitForFramesMs);
2055
2056 // Expect that the aspect ratio is inversed to account for the 90/270 degree
2057 // rotation.
2058 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2059 // not just assumed.
2060 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
2061 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
2062 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
2063 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
2064 // Expect that each endpoint is unaware of the rotation of the other endpoint.
2065 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
2066 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
2067}
2068
deadbeef1dcb1642017-03-29 21:08:16 -07002069// Test that if the answerer rejects the audio m= section, no audio is sent or
2070// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002071TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002072 ASSERT_TRUE(CreatePeerConnectionWrappers());
2073 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002074 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002075 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2076 // Only add video track for callee, and set offer_to_receive_audio to 0, so
2077 // it will reject the audio m= section completely.
2078 PeerConnectionInterface::RTCOfferAnswerOptions options;
2079 options.offer_to_receive_audio = 0;
2080 callee()->SetOfferAnswerOptions(options);
2081 } else {
2082 // Stopping the audio RtpTransceiver will cause the media section to be
2083 // rejected in the answer.
2084 callee()->SetRemoteOfferHandler([this] {
2085 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)->Stop();
2086 });
2087 }
Steve Anton15324772018-01-16 10:26:49 -08002088 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002089 // Do offer/answer and wait for successful end-to-end video frames.
2090 caller()->CreateAndSetAndSignalOffer();
2091 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002092 MediaExpectations media_expectations;
2093 media_expectations.ExpectBidirectionalVideo();
2094 media_expectations.ExpectNoAudio();
2095 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2096
deadbeef1dcb1642017-03-29 21:08:16 -07002097 // Sanity check that the callee's description has a rejected audio section.
2098 ASSERT_NE(nullptr, callee()->pc()->local_description());
2099 const ContentInfo* callee_audio_content =
2100 GetFirstAudioContent(callee()->pc()->local_description()->description());
2101 ASSERT_NE(nullptr, callee_audio_content);
2102 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002103 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2104 // The caller's transceiver should have stopped after receiving the answer.
2105 EXPECT_TRUE(caller()
2106 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
2107 ->stopped());
2108 }
deadbeef1dcb1642017-03-29 21:08:16 -07002109}
2110
2111// Test that if the answerer rejects the video m= section, no video is sent or
2112// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002113TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002114 ASSERT_TRUE(CreatePeerConnectionWrappers());
2115 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002116 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002117 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2118 // Only add audio track for callee, and set offer_to_receive_video to 0, so
2119 // it will reject the video m= section completely.
2120 PeerConnectionInterface::RTCOfferAnswerOptions options;
2121 options.offer_to_receive_video = 0;
2122 callee()->SetOfferAnswerOptions(options);
2123 } else {
2124 // Stopping the video RtpTransceiver will cause the media section to be
2125 // rejected in the answer.
2126 callee()->SetRemoteOfferHandler([this] {
2127 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2128 });
2129 }
Steve Anton15324772018-01-16 10:26:49 -08002130 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002131 // Do offer/answer and wait for successful end-to-end audio frames.
2132 caller()->CreateAndSetAndSignalOffer();
2133 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002134 MediaExpectations media_expectations;
2135 media_expectations.ExpectBidirectionalAudio();
2136 media_expectations.ExpectNoVideo();
2137 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2138
deadbeef1dcb1642017-03-29 21:08:16 -07002139 // Sanity check that the callee's description has a rejected video section.
2140 ASSERT_NE(nullptr, callee()->pc()->local_description());
2141 const ContentInfo* callee_video_content =
2142 GetFirstVideoContent(callee()->pc()->local_description()->description());
2143 ASSERT_NE(nullptr, callee_video_content);
2144 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002145 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2146 // The caller's transceiver should have stopped after receiving the answer.
2147 EXPECT_TRUE(caller()
2148 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2149 ->stopped());
2150 }
deadbeef1dcb1642017-03-29 21:08:16 -07002151}
2152
2153// Test that if the answerer rejects both audio and video m= sections, nothing
2154// bad happens.
2155// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
2156// test anything but the fact that negotiation succeeds, which doesn't mean
2157// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002158TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -07002159 ASSERT_TRUE(CreatePeerConnectionWrappers());
2160 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002161 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002162 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2163 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
2164 // will reject both audio and video m= sections.
2165 PeerConnectionInterface::RTCOfferAnswerOptions options;
2166 options.offer_to_receive_audio = 0;
2167 options.offer_to_receive_video = 0;
2168 callee()->SetOfferAnswerOptions(options);
2169 } else {
2170 callee()->SetRemoteOfferHandler([this] {
2171 // Stopping all transceivers will cause all media sections to be rejected.
2172 for (auto transceiver : callee()->pc()->GetTransceivers()) {
2173 transceiver->Stop();
2174 }
2175 });
2176 }
deadbeef1dcb1642017-03-29 21:08:16 -07002177 // Do offer/answer and wait for stable signaling state.
2178 caller()->CreateAndSetAndSignalOffer();
2179 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002180
deadbeef1dcb1642017-03-29 21:08:16 -07002181 // Sanity check that the callee's description has rejected m= sections.
2182 ASSERT_NE(nullptr, callee()->pc()->local_description());
2183 const ContentInfo* callee_audio_content =
2184 GetFirstAudioContent(callee()->pc()->local_description()->description());
2185 ASSERT_NE(nullptr, callee_audio_content);
2186 EXPECT_TRUE(callee_audio_content->rejected);
2187 const ContentInfo* callee_video_content =
2188 GetFirstVideoContent(callee()->pc()->local_description()->description());
2189 ASSERT_NE(nullptr, callee_video_content);
2190 EXPECT_TRUE(callee_video_content->rejected);
2191}
2192
2193// This test sets up an audio and video call between two parties. After the
2194// call runs for a while, the caller sends an updated offer with video being
2195// rejected. Once the re-negotiation is done, the video flow should stop and
2196// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002197TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07002198 ASSERT_TRUE(CreatePeerConnectionWrappers());
2199 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002200 caller()->AddAudioVideoTracks();
2201 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002202 caller()->CreateAndSetAndSignalOffer();
2203 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002204 {
2205 MediaExpectations media_expectations;
2206 media_expectations.ExpectBidirectionalAudioAndVideo();
2207 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2208 }
deadbeef1dcb1642017-03-29 21:08:16 -07002209 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002210 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2211 caller()->SetGeneratedSdpMunger(
2212 [](cricket::SessionDescription* description) {
2213 for (cricket::ContentInfo& content : description->contents()) {
2214 if (cricket::IsVideoContent(&content)) {
2215 content.rejected = true;
2216 }
2217 }
2218 });
2219 } else {
2220 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2221 }
deadbeef1dcb1642017-03-29 21:08:16 -07002222 caller()->CreateAndSetAndSignalOffer();
2223 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2224
2225 // Sanity check that the caller's description has a rejected video section.
2226 ASSERT_NE(nullptr, caller()->pc()->local_description());
2227 const ContentInfo* caller_video_content =
2228 GetFirstVideoContent(caller()->pc()->local_description()->description());
2229 ASSERT_NE(nullptr, caller_video_content);
2230 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -07002231 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002232 {
2233 MediaExpectations media_expectations;
2234 media_expectations.ExpectBidirectionalAudio();
2235 media_expectations.ExpectNoVideo();
2236 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2237 }
deadbeef1dcb1642017-03-29 21:08:16 -07002238}
2239
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -07002240// Do one offer/answer with audio, another that disables it (rejecting the m=
2241// section), and another that re-enables it. Regression test for:
2242// bugs.webrtc.org/6023
2243TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
2244 ASSERT_TRUE(CreatePeerConnectionWrappers());
2245 ConnectFakeSignaling();
2246
2247 // Add audio track, do normal offer/answer.
2248 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2249 caller()->CreateLocalAudioTrack();
2250 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2251 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2252 caller()->CreateAndSetAndSignalOffer();
2253 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2254
2255 // Remove audio track, and set offer_to_receive_audio to false to cause the
2256 // m= section to be completely disabled, not just "recvonly".
2257 caller()->pc()->RemoveTrack(sender);
2258 PeerConnectionInterface::RTCOfferAnswerOptions options;
2259 options.offer_to_receive_audio = 0;
2260 caller()->SetOfferAnswerOptions(options);
2261 caller()->CreateAndSetAndSignalOffer();
2262 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2263
2264 // Add the audio track again, expecting negotiation to succeed and frames to
2265 // flow.
2266 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2267 options.offer_to_receive_audio = 1;
2268 caller()->SetOfferAnswerOptions(options);
2269 caller()->CreateAndSetAndSignalOffer();
2270 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2271
2272 MediaExpectations media_expectations;
2273 media_expectations.CalleeExpectsSomeAudio();
2274 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2275}
2276
deadbeef1dcb1642017-03-29 21:08:16 -07002277// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
2278// is needed to support legacy endpoints.
2279// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
2280// add a test for an end-to-end test without MID signaling either (basically,
2281// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002282TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -07002283 ASSERT_TRUE(CreatePeerConnectionWrappers());
2284 ConnectFakeSignaling();
2285 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08002286 caller()->AddAudioVideoTracks();
2287 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07002288 // Remove SSRCs and MSIDs from the received offer SDP.
2289 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07002290 caller()->CreateAndSetAndSignalOffer();
2291 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002292 MediaExpectations media_expectations;
2293 media_expectations.ExpectBidirectionalAudioAndVideo();
2294 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002295}
2296
Seth Hampson5897a6e2018-04-03 11:16:33 -07002297// Basic end-to-end test, without SSRC signaling. This means that the track
2298// was created properly and frames are delivered when the MSIDs are communicated
2299// with a=msid lines and no a=ssrc lines.
2300TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2301 EndToEndCallWithoutSsrcSignaling) {
2302 const char kStreamId[] = "streamId";
2303 ASSERT_TRUE(CreatePeerConnectionWrappers());
2304 ConnectFakeSignaling();
2305 // Add just audio tracks.
2306 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
2307 callee()->AddAudioTrack();
2308
2309 // Remove SSRCs from the received offer SDP.
2310 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
2311 caller()->CreateAndSetAndSignalOffer();
2312 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2313 MediaExpectations media_expectations;
2314 media_expectations.ExpectBidirectionalAudio();
2315 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2316}
2317
Steve Antondf527fd2018-04-27 15:52:03 -07002318// Tests that video flows between multiple video tracks when SSRCs are not
2319// signaled. This exercises the MID RTP header extension which is needed to
2320// demux the incoming video tracks.
2321TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2322 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
2323 ASSERT_TRUE(CreatePeerConnectionWrappers());
2324 ConnectFakeSignaling();
2325 caller()->AddVideoTrack();
2326 caller()->AddVideoTrack();
2327 callee()->AddVideoTrack();
2328 callee()->AddVideoTrack();
2329
2330 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2331 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2332 caller()->CreateAndSetAndSignalOffer();
2333 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2334 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2335 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2336
2337 // Expect video to be received in both directions on both tracks.
2338 MediaExpectations media_expectations;
2339 media_expectations.ExpectBidirectionalVideo();
2340 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2341}
2342
deadbeef1dcb1642017-03-29 21:08:16 -07002343// Test that if two video tracks are sent (from caller to callee, in this test),
2344// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002345TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07002346 ASSERT_TRUE(CreatePeerConnectionWrappers());
2347 ConnectFakeSignaling();
2348 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08002349 caller()->AddAudioVideoTracks();
2350 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002351 caller()->CreateAndSetAndSignalOffer();
2352 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08002353 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002354
2355 MediaExpectations media_expectations;
2356 media_expectations.CalleeExpectsSomeAudioAndVideo();
2357 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002358}
2359
2360static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
2361 bool first = true;
2362 for (cricket::ContentInfo& content : desc->contents()) {
2363 if (first) {
2364 first = false;
2365 continue;
2366 }
2367 content.bundle_only = true;
2368 }
2369 first = true;
2370 for (cricket::TransportInfo& transport : desc->transport_infos()) {
2371 if (first) {
2372 first = false;
2373 continue;
2374 }
2375 transport.description.ice_ufrag.clear();
2376 transport.description.ice_pwd.clear();
2377 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
2378 transport.description.identity_fingerprint.reset(nullptr);
2379 }
2380}
2381
2382// Test that if applying a true "max bundle" offer, which uses ports of 0,
2383// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
2384// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
2385// successfully and media flows.
2386// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
2387// TODO(deadbeef): Won't need this test once we start generating actual
2388// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002389TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002390 EndToEndCallWithSpecCompliantMaxBundleOffer) {
2391 ASSERT_TRUE(CreatePeerConnectionWrappers());
2392 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002393 caller()->AddAudioVideoTracks();
2394 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002395 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
2396 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
2397 // but the first m= section.
2398 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
2399 caller()->CreateAndSetAndSignalOffer();
2400 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002401 MediaExpectations media_expectations;
2402 media_expectations.ExpectBidirectionalAudioAndVideo();
2403 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002404}
2405
2406// Test that we can receive the audio output level from a remote audio track.
2407// TODO(deadbeef): Use a fake audio source and verify that the output level is
2408// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002409TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002410 ASSERT_TRUE(CreatePeerConnectionWrappers());
2411 ConnectFakeSignaling();
2412 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002413 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002414 caller()->CreateAndSetAndSignalOffer();
2415 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2416
2417 // Get the audio output level stats. Note that the level is not available
2418 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07002419 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002420 kMaxWaitForFramesMs);
2421}
2422
2423// Test that an audio input level is reported.
2424// TODO(deadbeef): Use a fake audio source and verify that the input level is
2425// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002426TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002427 ASSERT_TRUE(CreatePeerConnectionWrappers());
2428 ConnectFakeSignaling();
2429 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002430 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002431 caller()->CreateAndSetAndSignalOffer();
2432 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2433
2434 // Get the audio input level stats. The level should be available very
2435 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07002436 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002437 kMaxWaitForStatsMs);
2438}
2439
2440// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002441TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002442 ASSERT_TRUE(CreatePeerConnectionWrappers());
2443 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002444 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002445 // Do offer/answer, wait for the callee to receive some frames.
2446 caller()->CreateAndSetAndSignalOffer();
2447 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002448
2449 MediaExpectations media_expectations;
2450 media_expectations.CalleeExpectsSomeAudioAndVideo();
2451 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002452
2453 // Get a handle to the remote tracks created, so they can be used as GetStats
2454 // filters.
Steve Anton15324772018-01-16 10:26:49 -08002455 for (auto receiver : callee()->pc()->GetReceivers()) {
2456 // We received frames, so we definitely should have nonzero "received bytes"
2457 // stats at this point.
2458 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
2459 0);
2460 }
deadbeef1dcb1642017-03-29 21:08:16 -07002461}
2462
2463// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002464TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002465 ASSERT_TRUE(CreatePeerConnectionWrappers());
2466 ConnectFakeSignaling();
2467 auto audio_track = caller()->CreateLocalAudioTrack();
2468 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08002469 caller()->AddTrack(audio_track);
2470 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07002471 // Do offer/answer, wait for the callee to receive some frames.
2472 caller()->CreateAndSetAndSignalOffer();
2473 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002474 MediaExpectations media_expectations;
2475 media_expectations.CalleeExpectsSomeAudioAndVideo();
2476 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002477
2478 // The callee received frames, so we definitely should have nonzero "sent
2479 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07002480 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
2481 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
2482}
2483
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002484// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002485TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002486 ASSERT_TRUE(CreatePeerConnectionWrappers());
2487 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002488 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002489
Steve Anton15324772018-01-16 10:26:49 -08002490 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002491
2492 // Do offer/answer, wait for the callee to receive some frames.
2493 caller()->CreateAndSetAndSignalOffer();
2494 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2495
2496 // Get the remote audio track created on the receiver, so they can be used as
2497 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08002498 auto receivers = callee()->pc()->GetReceivers();
2499 ASSERT_EQ(1u, receivers.size());
2500 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002501
2502 // Get the audio output level stats. Note that the level is not available
2503 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07002504 EXPECT_TRUE_WAIT(
2505 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
2506 0,
2507 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002508}
2509
deadbeefd8ad7882017-04-18 16:01:17 -07002510// Test that we can get stats (using the new stats implemnetation) for
2511// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
2512// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002513TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07002514 GetStatsForUnsignaledStreamWithNewStatsApi) {
2515 ASSERT_TRUE(CreatePeerConnectionWrappers());
2516 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002517 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07002518 // Remove SSRCs and MSIDs from the received offer SDP.
2519 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2520 caller()->CreateAndSetAndSignalOffer();
2521 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002522 MediaExpectations media_expectations;
2523 media_expectations.CalleeExpectsSomeAudio(1);
2524 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07002525
2526 // We received a frame, so we should have nonzero "bytes received" stats for
2527 // the unsignaled stream, if stats are working for it.
2528 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2529 callee()->NewGetStats();
2530 ASSERT_NE(nullptr, report);
2531 auto inbound_stream_stats =
2532 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2533 ASSERT_EQ(1U, inbound_stream_stats.size());
2534 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
2535 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07002536 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
2537}
2538
Taylor Brandstettera4653442018-06-19 09:44:26 -07002539// Same as above but for the legacy stats implementation.
2540TEST_P(PeerConnectionIntegrationTest,
2541 GetStatsForUnsignaledStreamWithOldStatsApi) {
2542 ASSERT_TRUE(CreatePeerConnectionWrappers());
2543 ConnectFakeSignaling();
2544 caller()->AddAudioTrack();
2545 // Remove SSRCs and MSIDs from the received offer SDP.
2546 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2547 caller()->CreateAndSetAndSignalOffer();
2548 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2549
2550 // Note that, since the old stats implementation associates SSRCs with tracks
2551 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
2552 // associated track ID. So we can't use the track "selector" argument.
2553 //
2554 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
2555 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002556 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07002557 kDefaultTimeout);
2558}
2559
zhihuangf8164932017-05-19 13:09:47 -07002560// Test that we can successfully get the media related stats (audio level
2561// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002562TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07002563 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
2564 ASSERT_TRUE(CreatePeerConnectionWrappers());
2565 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002566 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07002567 // Remove SSRCs and MSIDs from the received offer SDP.
2568 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2569 caller()->CreateAndSetAndSignalOffer();
2570 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002571 MediaExpectations media_expectations;
2572 media_expectations.CalleeExpectsSomeAudio(1);
2573 media_expectations.CalleeExpectsSomeVideo(1);
2574 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07002575
2576 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2577 callee()->NewGetStats();
2578 ASSERT_NE(nullptr, report);
2579
2580 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2581 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
2582 ASSERT_GE(audio_index, 0);
2583 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07002584}
2585
deadbeef4e2deab2017-09-20 13:56:21 -07002586// Helper for test below.
2587void ModifySsrcs(cricket::SessionDescription* desc) {
2588 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07002589 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08002590 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07002591 for (uint32_t& ssrc : stream.ssrcs) {
2592 ssrc = rtc::CreateRandomId();
2593 }
2594 }
2595 }
2596}
2597
2598// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
2599// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
2600// This should result in two "RTCInboundRTPStreamStats", but only one
2601// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
2602// being reset to 0 once the SSRC change occurs.
2603//
2604// Regression test for this bug:
2605// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
2606//
2607// The bug causes the track stats to only represent one of the two streams:
2608// whichever one has the higher SSRC. So with this bug, there was a 50% chance
2609// that the track stat counters would reset to 0 when the new stream is
2610// received, and a 50% chance that they'll stop updating (while
2611// "concealed_samples" continues increasing, due to silence being generated for
2612// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002613TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08002614 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07002615 ASSERT_TRUE(CreatePeerConnectionWrappers());
2616 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002617 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07002618 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
2619 // that doesn't signal SSRCs (from the callee's perspective).
2620 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2621 caller()->CreateAndSetAndSignalOffer();
2622 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2623 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002624 {
2625 MediaExpectations media_expectations;
2626 media_expectations.CalleeExpectsSomeAudio(50);
2627 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2628 }
deadbeef4e2deab2017-09-20 13:56:21 -07002629 // Some audio frames were received, so we should have nonzero "samples
2630 // received" for the track.
2631 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2632 callee()->NewGetStats();
2633 ASSERT_NE(nullptr, report);
2634 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2635 ASSERT_EQ(1U, track_stats.size());
2636 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2637 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
2638 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
2639
2640 // Create a new offer and munge it to cause the caller to use a new SSRC.
2641 caller()->SetGeneratedSdpMunger(ModifySsrcs);
2642 caller()->CreateAndSetAndSignalOffer();
2643 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2644 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
2645 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002646 {
2647 MediaExpectations media_expectations;
2648 media_expectations.CalleeExpectsSomeAudio(25);
2649 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2650 }
deadbeef4e2deab2017-09-20 13:56:21 -07002651
2652 report = callee()->NewGetStats();
2653 ASSERT_NE(nullptr, report);
2654 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2655 ASSERT_EQ(1U, track_stats.size());
2656 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2657 // The "total samples received" stat should only be greater than it was
2658 // before.
2659 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
2660 // Right now, the new SSRC will cause the counters to reset to 0.
2661 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
2662
2663 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08002664 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07002665 // good sign that we're seeing stats from the old stream that's no longer
2666 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08002667 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07002668 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
2669 EXPECT_LT(*track_stats[0]->concealed_samples,
2670 *track_stats[0]->total_samples_received *
2671 kAcceptableConcealedSamplesPercentage);
2672
2673 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
2674 // sanity check that the SSRC really changed.
2675 // TODO(deadbeef): This isn't working right now, because we're not returning
2676 // *any* stats for the inactive stream. Uncomment when the bug is completely
2677 // fixed.
2678 // auto inbound_stream_stats =
2679 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2680 // ASSERT_EQ(2U, inbound_stream_stats.size());
2681}
2682
deadbeef1dcb1642017-03-29 21:08:16 -07002683// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002684TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002685 PeerConnectionFactory::Options dtls_10_options;
2686 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2687 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2688 dtls_10_options));
2689 ConnectFakeSignaling();
2690 // Do normal offer/answer and wait for some frames to be received in each
2691 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002692 caller()->AddAudioVideoTracks();
2693 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002694 caller()->CreateAndSetAndSignalOffer();
2695 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002696 MediaExpectations media_expectations;
2697 media_expectations.ExpectBidirectionalAudioAndVideo();
2698 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002699}
2700
2701// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002702TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002703 PeerConnectionFactory::Options dtls_10_options;
2704 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2705 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2706 dtls_10_options));
2707 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002708 caller()->AddAudioVideoTracks();
2709 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002710 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002711 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002712 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002713 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002714 kDefaultTimeout);
2715 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002716 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002717 // TODO(bugs.webrtc.org/9456): Fix it.
2718 EXPECT_EQ(1, webrtc::metrics::NumEvents(
2719 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2720 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07002721}
2722
2723// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002724TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002725 PeerConnectionFactory::Options dtls_12_options;
2726 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2727 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
2728 dtls_12_options));
2729 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002730 caller()->AddAudioVideoTracks();
2731 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002732 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002733 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002734 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002735 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002736 kDefaultTimeout);
2737 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002738 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002739 // TODO(bugs.webrtc.org/9456): Fix it.
2740 EXPECT_EQ(1, webrtc::metrics::NumEvents(
2741 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2742 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07002743}
2744
2745// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
2746// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002747TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002748 PeerConnectionFactory::Options caller_options;
2749 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2750 PeerConnectionFactory::Options callee_options;
2751 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2752 ASSERT_TRUE(
2753 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2754 ConnectFakeSignaling();
2755 // Do normal offer/answer and wait for some frames to be received in each
2756 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002757 caller()->AddAudioVideoTracks();
2758 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002759 caller()->CreateAndSetAndSignalOffer();
2760 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002761 MediaExpectations media_expectations;
2762 media_expectations.ExpectBidirectionalAudioAndVideo();
2763 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002764}
2765
2766// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
2767// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002768TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07002769 PeerConnectionFactory::Options caller_options;
2770 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2771 PeerConnectionFactory::Options callee_options;
2772 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2773 ASSERT_TRUE(
2774 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2775 ConnectFakeSignaling();
2776 // Do normal offer/answer and wait for some frames to be received in each
2777 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002778 caller()->AddAudioVideoTracks();
2779 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002780 caller()->CreateAndSetAndSignalOffer();
2781 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002782 MediaExpectations media_expectations;
2783 media_expectations.ExpectBidirectionalAudioAndVideo();
2784 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002785}
2786
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07002787// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
2788// works as expected; the cipher should only be used if enabled by both sides.
2789TEST_P(PeerConnectionIntegrationTest,
2790 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
2791 PeerConnectionFactory::Options caller_options;
2792 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2793 PeerConnectionFactory::Options callee_options;
2794 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
2795 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2796 TestNegotiatedCipherSuite(caller_options, callee_options,
2797 expected_cipher_suite);
2798}
2799
2800TEST_P(PeerConnectionIntegrationTest,
2801 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
2802 PeerConnectionFactory::Options caller_options;
2803 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
2804 PeerConnectionFactory::Options callee_options;
2805 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2806 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2807 TestNegotiatedCipherSuite(caller_options, callee_options,
2808 expected_cipher_suite);
2809}
2810
2811TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
2812 PeerConnectionFactory::Options caller_options;
2813 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2814 PeerConnectionFactory::Options callee_options;
2815 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2816 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
2817 TestNegotiatedCipherSuite(caller_options, callee_options,
2818 expected_cipher_suite);
2819}
2820
deadbeef1dcb1642017-03-29 21:08:16 -07002821// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002822TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07002823 bool local_gcm_enabled = false;
2824 bool remote_gcm_enabled = false;
2825 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2826 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2827 expected_cipher_suite);
2828}
2829
2830// Test that a GCM cipher is used if both ends support it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002831TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07002832 bool local_gcm_enabled = true;
2833 bool remote_gcm_enabled = true;
2834 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
2835 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2836 expected_cipher_suite);
2837}
2838
2839// Test that GCM isn't used if only the offerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002840TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002841 NonGcmCipherUsedWhenOnlyCallerSupportsGcm) {
2842 bool local_gcm_enabled = true;
2843 bool remote_gcm_enabled = false;
2844 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2845 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2846 expected_cipher_suite);
2847}
2848
2849// Test that GCM isn't used if only the answerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002850TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002851 NonGcmCipherUsedWhenOnlyCalleeSupportsGcm) {
2852 bool local_gcm_enabled = false;
2853 bool remote_gcm_enabled = true;
2854 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2855 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2856 expected_cipher_suite);
2857}
2858
deadbeef7914b8c2017-04-21 03:23:33 -07002859// Verify that media can be transmitted end-to-end when GCM crypto suites are
2860// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
2861// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
2862// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002863TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07002864 PeerConnectionFactory::Options gcm_options;
2865 gcm_options.crypto_options.enable_gcm_crypto_suites = true;
2866 ASSERT_TRUE(
2867 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
2868 ConnectFakeSignaling();
2869 // Do normal offer/answer and wait for some frames to be received in each
2870 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002871 caller()->AddAudioVideoTracks();
2872 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07002873 caller()->CreateAndSetAndSignalOffer();
2874 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002875 MediaExpectations media_expectations;
2876 media_expectations.ExpectBidirectionalAudioAndVideo();
2877 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07002878}
2879
deadbeef1dcb1642017-03-29 21:08:16 -07002880// This test sets up a call between two parties with audio, video and an RTP
2881// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002882TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002883 PeerConnectionInterface::RTCConfiguration rtc_config;
2884 rtc_config.enable_rtp_data_channel = true;
2885 rtc_config.enable_dtls_srtp = false;
2886 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07002887 ConnectFakeSignaling();
2888 // Expect that data channel created on caller side will show up for callee as
2889 // well.
2890 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08002891 caller()->AddAudioVideoTracks();
2892 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002893 caller()->CreateAndSetAndSignalOffer();
2894 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2895 // Ensure the existence of the RTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002896 MediaExpectations media_expectations;
2897 media_expectations.ExpectBidirectionalAudioAndVideo();
2898 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002899 ASSERT_NE(nullptr, caller()->data_channel());
2900 ASSERT_NE(nullptr, callee()->data_channel());
2901 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2902 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2903
2904 // Ensure data can be sent in both directions.
2905 std::string data = "hello world";
2906 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
2907 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
2908 kDefaultTimeout);
2909 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
2910 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
2911 kDefaultTimeout);
2912}
2913
2914// Ensure that an RTP data channel is signaled as closed for the caller when
2915// the callee rejects it in a subsequent offer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002916TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002917 RtpDataChannelSignaledClosedInCalleeOffer) {
2918 // Same procedure as above test.
Niels Möllerf06f9232018-08-07 12:32:18 +02002919 PeerConnectionInterface::RTCConfiguration rtc_config;
2920 rtc_config.enable_rtp_data_channel = true;
2921 rtc_config.enable_dtls_srtp = false;
2922 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07002923 ConnectFakeSignaling();
2924 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08002925 caller()->AddAudioVideoTracks();
2926 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002927 caller()->CreateAndSetAndSignalOffer();
2928 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2929 ASSERT_NE(nullptr, caller()->data_channel());
2930 ASSERT_NE(nullptr, callee()->data_channel());
2931 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2932 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2933
2934 // Close the data channel on the callee, and do an updated offer/answer.
2935 callee()->data_channel()->Close();
2936 callee()->CreateAndSetAndSignalOffer();
2937 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2938 EXPECT_FALSE(caller()->data_observer()->IsOpen());
2939 EXPECT_FALSE(callee()->data_observer()->IsOpen());
2940}
2941
2942// Tests that data is buffered in an RTP data channel until an observer is
2943// registered for it.
2944//
2945// NOTE: RTP data channels can receive data before the underlying
2946// transport has detected that a channel is writable and thus data can be
2947// received before the data channel state changes to open. That is hard to test
2948// but the same buffering is expected to be used in that case.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002949TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002950 DataBufferedUntilRtpDataChannelObserverRegistered) {
2951 // Use fake clock and simulated network delay so that we predictably can wait
2952 // until an SCTP message has been delivered without "sleep()"ing.
2953 rtc::ScopedFakeClock fake_clock;
2954 // Some things use a time of "0" as a special value, so we need to start out
2955 // the fake clock at a nonzero time.
2956 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02002957 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-29 21:08:16 -07002958 virtual_socket_server()->set_delay_mean(5); // 5 ms per hop.
2959 virtual_socket_server()->UpdateDelayDistribution();
2960
Niels Möllerf06f9232018-08-07 12:32:18 +02002961 PeerConnectionInterface::RTCConfiguration rtc_config;
2962 rtc_config.enable_rtp_data_channel = true;
2963 rtc_config.enable_dtls_srtp = false;
2964 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07002965 ConnectFakeSignaling();
2966 caller()->CreateDataChannel();
2967 caller()->CreateAndSetAndSignalOffer();
2968 ASSERT_TRUE(caller()->data_channel() != nullptr);
2969 ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr,
2970 kDefaultTimeout, fake_clock);
2971 ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(),
2972 kDefaultTimeout, fake_clock);
2973 ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen,
2974 callee()->data_channel()->state(), kDefaultTimeout,
2975 fake_clock);
2976
2977 // Unregister the observer which is normally automatically registered.
2978 callee()->data_channel()->UnregisterObserver();
2979 // Send data and advance fake clock until it should have been received.
2980 std::string data = "hello world";
2981 caller()->data_channel()->Send(DataBuffer(data));
2982 SIMULATED_WAIT(false, 50, fake_clock);
2983
2984 // Attach data channel and expect data to be received immediately. Note that
2985 // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any
2986 // further, but data can be received even if the callback is asynchronous.
2987 MockDataChannelObserver new_observer(callee()->data_channel());
2988 EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout,
2989 fake_clock);
Seth Hampson1d4a76d2018-06-19 14:31:41 -07002990 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
2991 // If this is not done a DCHECK can be hit in ports.cc, because a large
2992 // negative number is calculated for the rtt due to the global clock changing.
2993 caller()->pc()->Close();
2994 callee()->pc()->Close();
deadbeef1dcb1642017-03-29 21:08:16 -07002995}
2996
2997// This test sets up a call between two parties with audio, video and but only
2998// the caller client supports RTP data channels.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002999TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003000 PeerConnectionInterface::RTCConfiguration rtc_config_1;
3001 rtc_config_1.enable_rtp_data_channel = true;
deadbeef1dcb1642017-03-29 21:08:16 -07003002 // Must disable DTLS to make negotiation succeed.
Niels Möllerf06f9232018-08-07 12:32:18 +02003003 rtc_config_1.enable_dtls_srtp = false;
3004 PeerConnectionInterface::RTCConfiguration rtc_config_2;
3005 rtc_config_2.enable_dtls_srtp = false;
3006 rtc_config_2.enable_dtls_srtp = false;
3007 ASSERT_TRUE(
3008 CreatePeerConnectionWrappersWithConfig(rtc_config_1, rtc_config_2));
deadbeef1dcb1642017-03-29 21:08:16 -07003009 ConnectFakeSignaling();
3010 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003011 caller()->AddAudioVideoTracks();
3012 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003013 caller()->CreateAndSetAndSignalOffer();
3014 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3015 // The caller should still have a data channel, but it should be closed, and
3016 // one should ever have been created for the callee.
3017 EXPECT_TRUE(caller()->data_channel() != nullptr);
3018 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3019 EXPECT_EQ(nullptr, callee()->data_channel());
3020}
3021
3022// This test sets up a call between two parties with audio, and video. When
3023// audio and video is setup and flowing, an RTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003024TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003025 PeerConnectionInterface::RTCConfiguration rtc_config;
3026 rtc_config.enable_rtp_data_channel = true;
3027 rtc_config.enable_dtls_srtp = false;
3028 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003029 ConnectFakeSignaling();
3030 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003031 caller()->AddAudioVideoTracks();
3032 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003033 caller()->CreateAndSetAndSignalOffer();
3034 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3035 // Create data channel and do new offer and answer.
3036 caller()->CreateDataChannel();
3037 caller()->CreateAndSetAndSignalOffer();
3038 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3039 ASSERT_NE(nullptr, caller()->data_channel());
3040 ASSERT_NE(nullptr, callee()->data_channel());
3041 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3042 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3043 // Ensure data can be sent in both directions.
3044 std::string data = "hello world";
3045 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3046 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3047 kDefaultTimeout);
3048 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3049 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3050 kDefaultTimeout);
3051}
3052
3053#ifdef HAVE_SCTP
3054
3055// This test sets up a call between two parties with audio, video and an SCTP
3056// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003057TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003058 ASSERT_TRUE(CreatePeerConnectionWrappers());
3059 ConnectFakeSignaling();
3060 // Expect that data channel created on caller side will show up for callee as
3061 // well.
3062 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003063 caller()->AddAudioVideoTracks();
3064 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003065 caller()->CreateAndSetAndSignalOffer();
3066 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3067 // Ensure the existence of the SCTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003068 MediaExpectations media_expectations;
3069 media_expectations.ExpectBidirectionalAudioAndVideo();
3070 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003071 // Caller data channel should already exist (it created one). Callee data
3072 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3073 ASSERT_NE(nullptr, caller()->data_channel());
3074 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3075 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3076 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3077
3078 // Ensure data can be sent in both directions.
3079 std::string data = "hello world";
3080 caller()->data_channel()->Send(DataBuffer(data));
3081 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3082 kDefaultTimeout);
3083 callee()->data_channel()->Send(DataBuffer(data));
3084 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3085 kDefaultTimeout);
3086}
3087
3088// Ensure that when the callee closes an SCTP data channel, the closing
3089// procedure results in the data channel being closed for the caller as well.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003090TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003091 // Same procedure as above test.
3092 ASSERT_TRUE(CreatePeerConnectionWrappers());
3093 ConnectFakeSignaling();
3094 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003095 caller()->AddAudioVideoTracks();
3096 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003097 caller()->CreateAndSetAndSignalOffer();
3098 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3099 ASSERT_NE(nullptr, caller()->data_channel());
3100 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3101 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3102 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3103
3104 // Close the data channel on the callee side, and wait for it to reach the
3105 // "closed" state on both sides.
3106 callee()->data_channel()->Close();
3107 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3108 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3109}
3110
Seth Hampson2f0d7022018-02-20 11:54:42 -08003111TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
Steve Antonda6c0952017-10-23 11:41:54 -07003112 ASSERT_TRUE(CreatePeerConnectionWrappers());
3113 ConnectFakeSignaling();
3114 webrtc::DataChannelInit init;
3115 init.id = 53;
3116 init.maxRetransmits = 52;
3117 caller()->CreateDataChannel("data-channel", &init);
Steve Anton15324772018-01-16 10:26:49 -08003118 caller()->AddAudioVideoTracks();
3119 callee()->AddAudioVideoTracks();
Steve Antonda6c0952017-10-23 11:41:54 -07003120 caller()->CreateAndSetAndSignalOffer();
3121 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton074dece2017-10-24 13:04:12 -07003122 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3123 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Steve Antonda6c0952017-10-23 11:41:54 -07003124 EXPECT_EQ(init.id, callee()->data_channel()->id());
3125 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3126 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3127 EXPECT_FALSE(callee()->data_channel()->negotiated());
3128}
3129
deadbeef1dcb1642017-03-29 21:08:16 -07003130// Test usrsctp's ability to process unordered data stream, where data actually
3131// arrives out of order using simulated delays. Previously there have been some
3132// bugs in this area.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003133TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003134 // Introduce random network delays.
3135 // Otherwise it's not a true "unordered" test.
3136 virtual_socket_server()->set_delay_mean(20);
3137 virtual_socket_server()->set_delay_stddev(5);
3138 virtual_socket_server()->UpdateDelayDistribution();
3139 // Normal procedure, but with unordered data channel config.
3140 ASSERT_TRUE(CreatePeerConnectionWrappers());
3141 ConnectFakeSignaling();
3142 webrtc::DataChannelInit init;
3143 init.ordered = false;
3144 caller()->CreateDataChannel(&init);
3145 caller()->CreateAndSetAndSignalOffer();
3146 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3147 ASSERT_NE(nullptr, caller()->data_channel());
3148 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3149 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3150 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3151
3152 static constexpr int kNumMessages = 100;
3153 // Deliberately chosen to be larger than the MTU so messages get fragmented.
3154 static constexpr size_t kMaxMessageSize = 4096;
3155 // Create and send random messages.
3156 std::vector<std::string> sent_messages;
3157 for (int i = 0; i < kNumMessages; ++i) {
3158 size_t length =
3159 (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand)
3160 std::string message;
3161 ASSERT_TRUE(rtc::CreateRandomString(length, &message));
3162 caller()->data_channel()->Send(DataBuffer(message));
3163 callee()->data_channel()->Send(DataBuffer(message));
3164 sent_messages.push_back(message);
3165 }
3166
3167 // Wait for all messages to be received.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003168 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003169 caller()->data_observer()->received_message_count(),
3170 kDefaultTimeout);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003171 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003172 callee()->data_observer()->received_message_count(),
3173 kDefaultTimeout);
3174
3175 // Sort and compare to make sure none of the messages were corrupted.
3176 std::vector<std::string> caller_received_messages =
3177 caller()->data_observer()->messages();
3178 std::vector<std::string> callee_received_messages =
3179 callee()->data_observer()->messages();
3180 std::sort(sent_messages.begin(), sent_messages.end());
3181 std::sort(caller_received_messages.begin(), caller_received_messages.end());
3182 std::sort(callee_received_messages.begin(), callee_received_messages.end());
3183 EXPECT_EQ(sent_messages, caller_received_messages);
3184 EXPECT_EQ(sent_messages, callee_received_messages);
3185}
3186
3187// This test sets up a call between two parties with audio, and video. When
3188// audio and video are setup and flowing, an SCTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003189TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07003190 ASSERT_TRUE(CreatePeerConnectionWrappers());
3191 ConnectFakeSignaling();
3192 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003193 caller()->AddAudioVideoTracks();
3194 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003195 caller()->CreateAndSetAndSignalOffer();
3196 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3197 // Create data channel and do new offer and answer.
3198 caller()->CreateDataChannel();
3199 caller()->CreateAndSetAndSignalOffer();
3200 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3201 // Caller data channel should already exist (it created one). Callee data
3202 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3203 ASSERT_NE(nullptr, caller()->data_channel());
3204 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3205 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3206 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3207 // Ensure data can be sent in both directions.
3208 std::string data = "hello world";
3209 caller()->data_channel()->Send(DataBuffer(data));
3210 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3211 kDefaultTimeout);
3212 callee()->data_channel()->Send(DataBuffer(data));
3213 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3214 kDefaultTimeout);
3215}
3216
deadbeef7914b8c2017-04-21 03:23:33 -07003217// Set up a connection initially just using SCTP data channels, later upgrading
3218// to audio/video, ensuring frames are received end-to-end. Effectively the
3219// inverse of the test above.
3220// This was broken in M57; see https://crbug.com/711243
Seth Hampson2f0d7022018-02-20 11:54:42 -08003221TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
deadbeef7914b8c2017-04-21 03:23:33 -07003222 ASSERT_TRUE(CreatePeerConnectionWrappers());
3223 ConnectFakeSignaling();
3224 // Do initial offer/answer with just data channel.
3225 caller()->CreateDataChannel();
3226 caller()->CreateAndSetAndSignalOffer();
3227 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3228 // Wait until data can be sent over the data channel.
3229 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3230 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3231 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3232
3233 // Do subsequent offer/answer with two-way audio and video. Audio and video
3234 // should end up bundled on the DTLS/ICE transport already used for data.
Steve Anton15324772018-01-16 10:26:49 -08003235 caller()->AddAudioVideoTracks();
3236 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003237 caller()->CreateAndSetAndSignalOffer();
3238 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003239 MediaExpectations media_expectations;
3240 media_expectations.ExpectBidirectionalAudioAndVideo();
3241 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003242}
3243
deadbeef8b7e9ad2017-05-25 09:38:55 -07003244static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
deadbeef8b7e9ad2017-05-25 09:38:55 -07003245 cricket::DataContentDescription* dcd_offer =
Steve Antonb1c1de12017-12-21 15:14:30 -08003246 GetFirstDataContentDescription(desc);
3247 ASSERT_TRUE(dcd_offer);
deadbeef8b7e9ad2017-05-25 09:38:55 -07003248 dcd_offer->set_use_sctpmap(false);
3249 dcd_offer->set_protocol("UDP/DTLS/SCTP");
3250}
3251
3252// Test that the data channel works when a spec-compliant SCTP m= section is
3253// offered (using "a=sctp-port" instead of "a=sctpmap", and using
3254// "UDP/DTLS/SCTP" as the protocol).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003255TEST_P(PeerConnectionIntegrationTest,
deadbeef8b7e9ad2017-05-25 09:38:55 -07003256 DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
3257 ASSERT_TRUE(CreatePeerConnectionWrappers());
3258 ConnectFakeSignaling();
3259 caller()->CreateDataChannel();
3260 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
3261 caller()->CreateAndSetAndSignalOffer();
3262 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3263 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3264 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3265 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3266
3267 // Ensure data can be sent in both directions.
3268 std::string data = "hello world";
3269 caller()->data_channel()->Send(DataBuffer(data));
3270 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3271 kDefaultTimeout);
3272 callee()->data_channel()->Send(DataBuffer(data));
3273 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3274 kDefaultTimeout);
3275}
3276
deadbeef1dcb1642017-03-29 21:08:16 -07003277#endif // HAVE_SCTP
3278
3279// Test that the ICE connection and gathering states eventually reach
3280// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08003281TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07003282 ASSERT_TRUE(CreatePeerConnectionWrappers());
3283 ConnectFakeSignaling();
3284 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08003285 caller()->AddAudioVideoTracks();
3286 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003287 caller()->CreateAndSetAndSignalOffer();
3288 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3289 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3290 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
3291 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3292 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
3293 // After the best candidate pair is selected and all candidates are signaled,
3294 // the ICE connection state should reach "complete".
3295 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
3296 // answerer/"callee" by default) only reaches "connected". When this is
3297 // fixed, this test should be updated.
3298 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3299 caller()->ice_connection_state(), kDefaultTimeout);
3300 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3301 callee()->ice_connection_state(), kDefaultTimeout);
3302}
3303
Steve Antonede9ca52017-10-16 13:04:27 -07003304// Test that firewalling the ICE connection causes the clients to identify the
3305// disconnected state and then removing the firewall causes them to reconnect.
3306class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003307 : public PeerConnectionIntegrationBaseTest,
3308 public ::testing::WithParamInterface<
3309 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07003310 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003311 PeerConnectionIntegrationIceStatesTest()
3312 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
3313 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07003314 }
3315
3316 void StartStunServer(const SocketAddress& server_address) {
3317 stun_server_.reset(
3318 cricket::TestStunServer::Create(network_thread(), server_address));
3319 }
3320
3321 bool TestIPv6() {
3322 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
3323 }
3324
3325 void SetPortAllocatorFlags() {
Qingsi Wanga2d60672018-04-11 16:57:45 -07003326 network_thread()->Invoke<void>(
3327 RTC_FROM_HERE,
3328 rtc::Bind(&cricket::PortAllocator::set_flags,
3329 caller()->port_allocator(), port_allocator_flags_));
3330 network_thread()->Invoke<void>(
3331 RTC_FROM_HERE,
3332 rtc::Bind(&cricket::PortAllocator::set_flags,
3333 callee()->port_allocator(), port_allocator_flags_));
Steve Antonede9ca52017-10-16 13:04:27 -07003334 }
3335
3336 std::vector<SocketAddress> CallerAddresses() {
3337 std::vector<SocketAddress> addresses;
3338 addresses.push_back(SocketAddress("1.1.1.1", 0));
3339 if (TestIPv6()) {
3340 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
3341 }
3342 return addresses;
3343 }
3344
3345 std::vector<SocketAddress> CalleeAddresses() {
3346 std::vector<SocketAddress> addresses;
3347 addresses.push_back(SocketAddress("2.2.2.2", 0));
3348 if (TestIPv6()) {
3349 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
3350 }
3351 return addresses;
3352 }
3353
3354 void SetUpNetworkInterfaces() {
3355 // Remove the default interfaces added by the test infrastructure.
3356 caller()->network()->RemoveInterface(kDefaultLocalAddress);
3357 callee()->network()->RemoveInterface(kDefaultLocalAddress);
3358
3359 // Add network addresses for test.
3360 for (const auto& caller_address : CallerAddresses()) {
3361 caller()->network()->AddInterface(caller_address);
3362 }
3363 for (const auto& callee_address : CalleeAddresses()) {
3364 callee()->network()->AddInterface(callee_address);
3365 }
3366 }
3367
3368 private:
3369 uint32_t port_allocator_flags_;
3370 std::unique_ptr<cricket::TestStunServer> stun_server_;
3371};
3372
3373// Tests that the PeerConnection goes through all the ICE gathering/connection
3374// states over the duration of the call. This includes Disconnected and Failed
3375// states, induced by putting a firewall between the peers and waiting for them
3376// to time out.
Steve Anton83119dd2017-11-10 16:19:52 -08003377TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyIceStates) {
3378 // TODO(bugs.webrtc.org/8295): When using a ScopedFakeClock, this test will
3379 // sometimes hit a DCHECK in platform_thread.cc about the PacerThread being
3380 // too busy. For now, revert to running without a fake clock.
Steve Antonede9ca52017-10-16 13:04:27 -07003381
3382 const SocketAddress kStunServerAddress =
3383 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
3384 StartStunServer(kStunServerAddress);
3385
3386 PeerConnectionInterface::RTCConfiguration config;
3387 PeerConnectionInterface::IceServer ice_stun_server;
3388 ice_stun_server.urls.push_back(
3389 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
3390 kStunServerAddress.PortAsString());
3391 config.servers.push_back(ice_stun_server);
3392
3393 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3394 ConnectFakeSignaling();
3395 SetPortAllocatorFlags();
3396 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08003397 caller()->AddAudioVideoTracks();
3398 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003399
3400 // Initial state before anything happens.
3401 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
3402 caller()->ice_gathering_state());
3403 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
3404 caller()->ice_connection_state());
3405
3406 // Start the call by creating the offer, setting it as the local description,
3407 // then sending it to the peer who will respond with an answer. This happens
3408 // asynchronously so that we can watch the states as it runs in the
3409 // background.
3410 caller()->CreateAndSetAndSignalOffer();
3411
Steve Anton83119dd2017-11-10 16:19:52 -08003412 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3413 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003414
3415 // Verify that the observer was notified of the intermediate transitions.
3416 EXPECT_THAT(caller()->ice_connection_state_history(),
3417 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
3418 PeerConnectionInterface::kIceConnectionConnected,
3419 PeerConnectionInterface::kIceConnectionCompleted));
3420 EXPECT_THAT(caller()->ice_gathering_state_history(),
3421 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3422 PeerConnectionInterface::kIceGatheringComplete));
3423
3424 // Block connections to/from the caller and wait for ICE to become
3425 // disconnected.
3426 for (const auto& caller_address : CallerAddresses()) {
3427 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3428 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01003429 RTC_LOG(LS_INFO) << "Firewall rules applied";
Steve Anton83119dd2017-11-10 16:19:52 -08003430 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
3431 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003432
3433 // Let ICE re-establish by removing the firewall rules.
3434 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01003435 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Steve Anton83119dd2017-11-10 16:19:52 -08003436 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3437 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003438
3439 // According to RFC7675, if there is no response within 30 seconds then the
3440 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08003441 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07003442 constexpr int kConsentTimeout = 30000;
3443 for (const auto& caller_address : CallerAddresses()) {
3444 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3445 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01003446 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Steve Anton83119dd2017-11-10 16:19:52 -08003447 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionFailed,
3448 caller()->ice_connection_state(), kConsentTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003449}
3450
3451// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
3452// and that the statistics in the metric observers are updated correctly.
3453TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) {
3454 ASSERT_TRUE(CreatePeerConnectionWrappers());
3455 ConnectFakeSignaling();
3456 SetPortAllocatorFlags();
3457 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08003458 caller()->AddAudioVideoTracks();
3459 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003460 caller()->CreateAndSetAndSignalOffer();
3461
3462 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3463
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003464 // TODO(bugs.webrtc.org/9456): Fix it.
3465 const int num_best_ipv4 = webrtc::metrics::NumEvents(
3466 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
3467 const int num_best_ipv6 = webrtc::metrics::NumEvents(
3468 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07003469 if (TestIPv6()) {
3470 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
3471 // connection.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003472 EXPECT_EQ(0, num_best_ipv4);
3473 EXPECT_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07003474 } else {
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003475 EXPECT_EQ(1, num_best_ipv4);
3476 EXPECT_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07003477 }
3478
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003479 EXPECT_EQ(0, webrtc::metrics::NumEvents(
3480 "WebRTC.PeerConnection.CandidatePairType_UDP",
3481 webrtc::kIceCandidatePairHostHost));
3482 EXPECT_EQ(1, webrtc::metrics::NumEvents(
3483 "WebRTC.PeerConnection.CandidatePairType_UDP",
3484 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07003485}
3486
3487constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
3488 cricket::PORTALLOCATOR_DISABLE_STUN |
3489 cricket::PORTALLOCATOR_DISABLE_RELAY;
3490constexpr uint32_t kFlagsIPv6NoStun =
3491 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
3492 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
3493constexpr uint32_t kFlagsIPv4Stun =
3494 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
3495
Seth Hampson2f0d7022018-02-20 11:54:42 -08003496INSTANTIATE_TEST_CASE_P(
3497 PeerConnectionIntegrationTest,
3498 PeerConnectionIntegrationIceStatesTest,
3499 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3500 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
3501 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
3502 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07003503
deadbeef1dcb1642017-03-29 21:08:16 -07003504// This test sets up a call between two parties with audio and video.
3505// During the call, the caller restarts ICE and the test verifies that
3506// new ICE candidates are generated and audio and video still can flow, and the
3507// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003508TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07003509 ASSERT_TRUE(CreatePeerConnectionWrappers());
3510 ConnectFakeSignaling();
3511 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08003512 caller()->AddAudioVideoTracks();
3513 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003514 caller()->CreateAndSetAndSignalOffer();
3515 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3516 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3517 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3518 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3519 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3520
3521 // To verify that the ICE restart actually occurs, get
3522 // ufrag/password/candidates before and after restart.
3523 // Create an SDP string of the first audio candidate for both clients.
3524 const webrtc::IceCandidateCollection* audio_candidates_caller =
3525 caller()->pc()->local_description()->candidates(0);
3526 const webrtc::IceCandidateCollection* audio_candidates_callee =
3527 callee()->pc()->local_description()->candidates(0);
3528 ASSERT_GT(audio_candidates_caller->count(), 0u);
3529 ASSERT_GT(audio_candidates_callee->count(), 0u);
3530 std::string caller_candidate_pre_restart;
3531 ASSERT_TRUE(
3532 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
3533 std::string callee_candidate_pre_restart;
3534 ASSERT_TRUE(
3535 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
3536 const cricket::SessionDescription* desc =
3537 caller()->pc()->local_description()->description();
3538 std::string caller_ufrag_pre_restart =
3539 desc->transport_infos()[0].description.ice_ufrag;
3540 desc = callee()->pc()->local_description()->description();
3541 std::string callee_ufrag_pre_restart =
3542 desc->transport_infos()[0].description.ice_ufrag;
3543
3544 // Have the caller initiate an ICE restart.
3545 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
3546 caller()->CreateAndSetAndSignalOffer();
3547 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3548 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3549 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3550 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3551 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3552
3553 // Grab the ufrags/candidates again.
3554 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
3555 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
3556 ASSERT_GT(audio_candidates_caller->count(), 0u);
3557 ASSERT_GT(audio_candidates_callee->count(), 0u);
3558 std::string caller_candidate_post_restart;
3559 ASSERT_TRUE(
3560 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
3561 std::string callee_candidate_post_restart;
3562 ASSERT_TRUE(
3563 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
3564 desc = caller()->pc()->local_description()->description();
3565 std::string caller_ufrag_post_restart =
3566 desc->transport_infos()[0].description.ice_ufrag;
3567 desc = callee()->pc()->local_description()->description();
3568 std::string callee_ufrag_post_restart =
3569 desc->transport_infos()[0].description.ice_ufrag;
3570 // Sanity check that an ICE restart was actually negotiated in SDP.
3571 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
3572 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
3573 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
3574 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
3575
3576 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003577 MediaExpectations media_expectations;
3578 media_expectations.ExpectBidirectionalAudioAndVideo();
3579 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003580}
3581
3582// Verify that audio/video can be received end-to-end when ICE renomination is
3583// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003584TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07003585 PeerConnectionInterface::RTCConfiguration config;
3586 config.enable_ice_renomination = true;
3587 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3588 ConnectFakeSignaling();
3589 // Do normal offer/answer and wait for some frames to be received in each
3590 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003591 caller()->AddAudioVideoTracks();
3592 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003593 caller()->CreateAndSetAndSignalOffer();
3594 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3595 // Sanity check that ICE renomination was actually negotiated.
3596 const cricket::SessionDescription* desc =
3597 caller()->pc()->local_description()->description();
3598 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 02:41:29 -07003599 ASSERT_NE(
3600 info.description.transport_options.end(),
3601 std::find(info.description.transport_options.begin(),
3602 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07003603 }
3604 desc = callee()->pc()->local_description()->description();
3605 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 02:41:29 -07003606 ASSERT_NE(
3607 info.description.transport_options.end(),
3608 std::find(info.description.transport_options.begin(),
3609 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07003610 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08003611 MediaExpectations media_expectations;
3612 media_expectations.ExpectBidirectionalAudioAndVideo();
3613 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003614}
3615
Steve Anton6f25b092017-10-23 09:39:20 -07003616// With a max bundle policy and RTCP muxing, adding a new media description to
3617// the connection should not affect ICE at all because the new media will use
3618// the existing connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003619TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08003620 AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07003621 PeerConnectionInterface::RTCConfiguration config;
3622 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3623 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3624 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
3625 config, PeerConnectionInterface::RTCConfiguration()));
3626 ConnectFakeSignaling();
3627
Steve Anton15324772018-01-16 10:26:49 -08003628 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07003629 caller()->CreateAndSetAndSignalOffer();
3630 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07003631 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3632 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07003633
3634 caller()->clear_ice_connection_state_history();
3635
Steve Anton15324772018-01-16 10:26:49 -08003636 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07003637 caller()->CreateAndSetAndSignalOffer();
3638 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3639
3640 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
3641}
3642
deadbeef1dcb1642017-03-29 21:08:16 -07003643// This test sets up a call between two parties with audio and video. It then
3644// renegotiates setting the video m-line to "port 0", then later renegotiates
3645// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003646TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003647 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
3648 ASSERT_TRUE(CreatePeerConnectionWrappers());
3649 ConnectFakeSignaling();
3650
3651 // Do initial negotiation, only sending media from the caller. Will result in
3652 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08003653 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003654 caller()->CreateAndSetAndSignalOffer();
3655 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3656
3657 // Negotiate again, disabling the video "m=" section (the callee will set the
3658 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003659 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3660 PeerConnectionInterface::RTCOfferAnswerOptions options;
3661 options.offer_to_receive_video = 0;
3662 callee()->SetOfferAnswerOptions(options);
3663 } else {
3664 callee()->SetRemoteOfferHandler([this] {
3665 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
3666 });
3667 }
deadbeef1dcb1642017-03-29 21:08:16 -07003668 caller()->CreateAndSetAndSignalOffer();
3669 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3670 // Sanity check that video "m=" section was actually rejected.
3671 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
3672 callee()->pc()->local_description()->description());
3673 ASSERT_NE(nullptr, answer_video_content);
3674 ASSERT_TRUE(answer_video_content->rejected);
3675
3676 // Enable video and do negotiation again, making sure video is received
3677 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003678 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3679 PeerConnectionInterface::RTCOfferAnswerOptions options;
3680 options.offer_to_receive_video = 1;
3681 callee()->SetOfferAnswerOptions(options);
3682 } else {
3683 // The caller's transceiver is stopped, so we need to add another track.
3684 auto caller_transceiver =
3685 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
3686 EXPECT_TRUE(caller_transceiver->stopped());
3687 caller()->AddVideoTrack();
3688 }
3689 callee()->AddVideoTrack();
3690 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07003691 caller()->CreateAndSetAndSignalOffer();
3692 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003693
deadbeef1dcb1642017-03-29 21:08:16 -07003694 // Verify the caller receives frames from the newly added stream, and the
3695 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003696 MediaExpectations media_expectations;
3697 media_expectations.CalleeExpectsSomeAudio();
3698 media_expectations.ExpectBidirectionalVideo();
3699 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003700}
3701
deadbeef1dcb1642017-03-29 21:08:16 -07003702// This tests that if we negotiate after calling CreateSender but before we
3703// have a track, then set a track later, frames from the newly-set track are
3704// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003705TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07003706 MediaFlowsAfterEarlyWarmupWithCreateSender) {
3707 ASSERT_TRUE(CreatePeerConnectionWrappers());
3708 ConnectFakeSignaling();
3709 auto caller_audio_sender =
3710 caller()->pc()->CreateSender("audio", "caller_stream");
3711 auto caller_video_sender =
3712 caller()->pc()->CreateSender("video", "caller_stream");
3713 auto callee_audio_sender =
3714 callee()->pc()->CreateSender("audio", "callee_stream");
3715 auto callee_video_sender =
3716 callee()->pc()->CreateSender("video", "callee_stream");
3717 caller()->CreateAndSetAndSignalOffer();
3718 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3719 // Wait for ICE to complete, without any tracks being set.
3720 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3721 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3722 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3723 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3724 // Now set the tracks, and expect frames to immediately start flowing.
3725 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3726 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3727 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3728 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08003729 MediaExpectations media_expectations;
3730 media_expectations.ExpectBidirectionalAudioAndVideo();
3731 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3732}
3733
3734// This tests that if we negotiate after calling AddTransceiver but before we
3735// have a track, then set a track later, frames from the newly-set tracks are
3736// received end-to-end.
3737TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3738 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
3739 ASSERT_TRUE(CreatePeerConnectionWrappers());
3740 ConnectFakeSignaling();
3741 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3742 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
3743 auto caller_audio_sender = audio_result.MoveValue()->sender();
3744 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3745 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
3746 auto caller_video_sender = video_result.MoveValue()->sender();
3747 callee()->SetRemoteOfferHandler([this] {
3748 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
3749 callee()->pc()->GetTransceivers()[0]->SetDirection(
3750 RtpTransceiverDirection::kSendRecv);
3751 callee()->pc()->GetTransceivers()[1]->SetDirection(
3752 RtpTransceiverDirection::kSendRecv);
3753 });
3754 caller()->CreateAndSetAndSignalOffer();
3755 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3756 // Wait for ICE to complete, without any tracks being set.
3757 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3758 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3759 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3760 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3761 // Now set the tracks, and expect frames to immediately start flowing.
3762 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
3763 auto callee_video_sender = callee()->pc()->GetSenders()[1];
3764 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3765 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3766 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3767 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
3768 MediaExpectations media_expectations;
3769 media_expectations.ExpectBidirectionalAudioAndVideo();
3770 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003771}
3772
3773// This test verifies that a remote video track can be added via AddStream,
3774// and sent end-to-end. For this particular test, it's simply echoed back
3775// from the caller to the callee, rather than being forwarded to a third
3776// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003777TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07003778 ASSERT_TRUE(CreatePeerConnectionWrappers());
3779 ConnectFakeSignaling();
3780 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08003781 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07003782 caller()->CreateAndSetAndSignalOffer();
3783 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003784 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07003785
3786 // Echo the stream back, and do a new offer/anwer (initiated by callee this
3787 // time).
3788 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
3789 callee()->CreateAndSetAndSignalOffer();
3790 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3791
Seth Hampson2f0d7022018-02-20 11:54:42 -08003792 MediaExpectations media_expectations;
3793 media_expectations.ExpectBidirectionalVideo();
3794 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003795}
3796
3797// Test that we achieve the expected end-to-end connection time, using a
3798// fake clock and simulated latency on the media and signaling paths.
3799// We use a TURN<->TURN connection because this is usually the quickest to
3800// set up initially, especially when we're confident the connection will work
3801// and can start sending media before we get a STUN response.
3802//
3803// With various optimizations enabled, here are the network delays we expect to
3804// be on the critical path:
3805// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
3806// signaling answer (with DTLS fingerprint).
3807// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
3808// using TURN<->TURN pair, and DTLS exchange is 4 packets,
3809// the first of which should have arrived before the answer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003810TEST_P(PeerConnectionIntegrationTest, EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07003811 rtc::ScopedFakeClock fake_clock;
3812 // Some things use a time of "0" as a special value, so we need to start out
3813 // the fake clock at a nonzero time.
3814 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003815 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-29 21:08:16 -07003816
3817 static constexpr int media_hop_delay_ms = 50;
3818 static constexpr int signaling_trip_delay_ms = 500;
3819 // For explanation of these values, see comment above.
3820 static constexpr int required_media_hops = 9;
3821 static constexpr int required_signaling_trips = 2;
3822 // For internal delays (such as posting an event asychronously).
3823 static constexpr int allowed_internal_delay_ms = 20;
3824 static constexpr int total_connection_time_ms =
3825 media_hop_delay_ms * required_media_hops +
3826 signaling_trip_delay_ms * required_signaling_trips +
3827 allowed_internal_delay_ms;
3828
3829 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
3830 3478};
3831 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
3832 0};
3833 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
3834 3478};
3835 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
3836 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07003837 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
3838 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02003839
Seth Hampsonaed71642018-06-11 07:41:32 -07003840 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
3841 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07003842 // Bypass permission check on received packets so media can be sent before
3843 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07003844 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
3845 turn_server_1->set_enable_permission_checks(false);
3846 });
3847 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
3848 turn_server_2->set_enable_permission_checks(false);
3849 });
deadbeef1dcb1642017-03-29 21:08:16 -07003850
3851 PeerConnectionInterface::RTCConfiguration client_1_config;
3852 webrtc::PeerConnectionInterface::IceServer ice_server_1;
3853 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
3854 ice_server_1.username = "test";
3855 ice_server_1.password = "test";
3856 client_1_config.servers.push_back(ice_server_1);
3857 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
3858 client_1_config.presume_writable_when_fully_relayed = true;
3859
3860 PeerConnectionInterface::RTCConfiguration client_2_config;
3861 webrtc::PeerConnectionInterface::IceServer ice_server_2;
3862 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
3863 ice_server_2.username = "test";
3864 ice_server_2.password = "test";
3865 client_2_config.servers.push_back(ice_server_2);
3866 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
3867 client_2_config.presume_writable_when_fully_relayed = true;
3868
3869 ASSERT_TRUE(
3870 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
3871 // Set up the simulated delays.
3872 SetSignalingDelayMs(signaling_trip_delay_ms);
3873 ConnectFakeSignaling();
3874 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
3875 virtual_socket_server()->UpdateDelayDistribution();
3876
3877 // Set "offer to receive audio/video" without adding any tracks, so we just
3878 // set up ICE/DTLS with no media.
3879 PeerConnectionInterface::RTCOfferAnswerOptions options;
3880 options.offer_to_receive_audio = 1;
3881 options.offer_to_receive_video = 1;
3882 caller()->SetOfferAnswerOptions(options);
3883 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07003884 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
3885 fake_clock);
Seth Hampson1d4a76d2018-06-19 14:31:41 -07003886 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
3887 // If this is not done a DCHECK can be hit in ports.cc, because a large
3888 // negative number is calculated for the rtt due to the global clock changing.
3889 caller()->pc()->Close();
3890 callee()->pc()->Close();
deadbeef1dcb1642017-03-29 21:08:16 -07003891}
3892
Jonas Orelandbdcee282017-10-10 14:01:40 +02003893// Verify that a TurnCustomizer passed in through RTCConfiguration
3894// is actually used by the underlying TURN candidate pair.
3895// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003896TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02003897 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
3898 3478};
3899 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
3900 0};
3901 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
3902 3478};
3903 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
3904 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07003905 CreateTurnServer(turn_server_1_internal_address,
3906 turn_server_1_external_address);
3907 CreateTurnServer(turn_server_2_internal_address,
3908 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02003909
3910 PeerConnectionInterface::RTCConfiguration client_1_config;
3911 webrtc::PeerConnectionInterface::IceServer ice_server_1;
3912 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
3913 ice_server_1.username = "test";
3914 ice_server_1.password = "test";
3915 client_1_config.servers.push_back(ice_server_1);
3916 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07003917 auto* customizer1 = CreateTurnCustomizer();
3918 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02003919
3920 PeerConnectionInterface::RTCConfiguration client_2_config;
3921 webrtc::PeerConnectionInterface::IceServer ice_server_2;
3922 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
3923 ice_server_2.username = "test";
3924 ice_server_2.password = "test";
3925 client_2_config.servers.push_back(ice_server_2);
3926 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07003927 auto* customizer2 = CreateTurnCustomizer();
3928 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02003929
3930 ASSERT_TRUE(
3931 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
3932 ConnectFakeSignaling();
3933
3934 // Set "offer to receive audio/video" without adding any tracks, so we just
3935 // set up ICE/DTLS with no media.
3936 PeerConnectionInterface::RTCOfferAnswerOptions options;
3937 options.offer_to_receive_audio = 1;
3938 options.offer_to_receive_video = 1;
3939 caller()->SetOfferAnswerOptions(options);
3940 caller()->CreateAndSetAndSignalOffer();
3941 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3942
Seth Hampsonaed71642018-06-11 07:41:32 -07003943 ExpectTurnCustomizerCountersIncremented(customizer1);
3944 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02003945}
3946
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07003947// Verifies that you can use TCP instead of UDP to connect to a TURN server and
3948// send media between the caller and the callee.
3949TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
3950 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3951 3478};
3952 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3953
3954 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07003955 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
3956 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07003957
3958 webrtc::PeerConnectionInterface::IceServer ice_server;
3959 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
3960 ice_server.username = "test";
3961 ice_server.password = "test";
3962
3963 PeerConnectionInterface::RTCConfiguration client_1_config;
3964 client_1_config.servers.push_back(ice_server);
3965 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
3966
3967 PeerConnectionInterface::RTCConfiguration client_2_config;
3968 client_2_config.servers.push_back(ice_server);
3969 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
3970
3971 ASSERT_TRUE(
3972 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
3973
3974 // Do normal offer/answer and wait for ICE to complete.
3975 ConnectFakeSignaling();
3976 caller()->AddAudioVideoTracks();
3977 callee()->AddAudioVideoTracks();
3978 caller()->CreateAndSetAndSignalOffer();
3979 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3980 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3981 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3982
3983 MediaExpectations media_expectations;
3984 media_expectations.ExpectBidirectionalAudioAndVideo();
3985 EXPECT_TRUE(ExpectNewFrames(media_expectations));
3986}
3987
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07003988// Verify that a SSLCertificateVerifier passed in through
3989// PeerConnectionDependencies is actually used by the underlying SSL
3990// implementation to determine whether a certificate presented by the TURN
3991// server is accepted by the client. Note that openssladapter_unittest.cc
3992// contains more detailed, lower-level tests.
3993TEST_P(PeerConnectionIntegrationTest,
3994 SSLCertificateVerifierUsedForTurnConnections) {
3995 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3996 3478};
3997 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3998
3999 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4000 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004001 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4002 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004003
4004 webrtc::PeerConnectionInterface::IceServer ice_server;
4005 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4006 ice_server.username = "test";
4007 ice_server.password = "test";
4008
4009 PeerConnectionInterface::RTCConfiguration client_1_config;
4010 client_1_config.servers.push_back(ice_server);
4011 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4012
4013 PeerConnectionInterface::RTCConfiguration client_2_config;
4014 client_2_config.servers.push_back(ice_server);
4015 // Setting the type to kRelay forces the connection to go through a TURN
4016 // server.
4017 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4018
4019 // Get a copy to the pointer so we can verify calls later.
4020 rtc::TestCertificateVerifier* client_1_cert_verifier =
4021 new rtc::TestCertificateVerifier();
4022 client_1_cert_verifier->verify_certificate_ = true;
4023 rtc::TestCertificateVerifier* client_2_cert_verifier =
4024 new rtc::TestCertificateVerifier();
4025 client_2_cert_verifier->verify_certificate_ = true;
4026
4027 // Create the dependencies with the test certificate verifier.
4028 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4029 client_1_deps.tls_cert_verifier =
4030 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4031 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4032 client_2_deps.tls_cert_verifier =
4033 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4034
4035 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4036 client_1_config, std::move(client_1_deps), client_2_config,
4037 std::move(client_2_deps)));
4038 ConnectFakeSignaling();
4039
4040 // Set "offer to receive audio/video" without adding any tracks, so we just
4041 // set up ICE/DTLS with no media.
4042 PeerConnectionInterface::RTCOfferAnswerOptions options;
4043 options.offer_to_receive_audio = 1;
4044 options.offer_to_receive_video = 1;
4045 caller()->SetOfferAnswerOptions(options);
4046 caller()->CreateAndSetAndSignalOffer();
4047 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4048
4049 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4050 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004051}
4052
4053TEST_P(PeerConnectionIntegrationTest,
4054 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
4055 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4056 3478};
4057 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4058
4059 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4060 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004061 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4062 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004063
4064 webrtc::PeerConnectionInterface::IceServer ice_server;
4065 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4066 ice_server.username = "test";
4067 ice_server.password = "test";
4068
4069 PeerConnectionInterface::RTCConfiguration client_1_config;
4070 client_1_config.servers.push_back(ice_server);
4071 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4072
4073 PeerConnectionInterface::RTCConfiguration client_2_config;
4074 client_2_config.servers.push_back(ice_server);
4075 // Setting the type to kRelay forces the connection to go through a TURN
4076 // server.
4077 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4078
4079 // Get a copy to the pointer so we can verify calls later.
4080 rtc::TestCertificateVerifier* client_1_cert_verifier =
4081 new rtc::TestCertificateVerifier();
4082 client_1_cert_verifier->verify_certificate_ = false;
4083 rtc::TestCertificateVerifier* client_2_cert_verifier =
4084 new rtc::TestCertificateVerifier();
4085 client_2_cert_verifier->verify_certificate_ = false;
4086
4087 // Create the dependencies with the test certificate verifier.
4088 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4089 client_1_deps.tls_cert_verifier =
4090 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4091 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4092 client_2_deps.tls_cert_verifier =
4093 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4094
4095 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4096 client_1_config, std::move(client_1_deps), client_2_config,
4097 std::move(client_2_deps)));
4098 ConnectFakeSignaling();
4099
4100 // Set "offer to receive audio/video" without adding any tracks, so we just
4101 // set up ICE/DTLS with no media.
4102 PeerConnectionInterface::RTCOfferAnswerOptions options;
4103 options.offer_to_receive_audio = 1;
4104 options.offer_to_receive_video = 1;
4105 caller()->SetOfferAnswerOptions(options);
4106 caller()->CreateAndSetAndSignalOffer();
4107 bool wait_res = true;
4108 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
4109 // properly, should be able to just wait for a state of "failed" instead of
4110 // waiting a fixed 10 seconds.
4111 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
4112 ASSERT_FALSE(wait_res);
4113
4114 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4115 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004116}
4117
deadbeefc964d0b2017-04-03 10:03:35 -07004118// Test that audio and video flow end-to-end when codec names don't use the
4119// expected casing, given that they're supposed to be case insensitive. To test
4120// this, all but one codec is removed from each media description, and its
4121// casing is changed.
4122//
4123// In the past, this has regressed and caused crashes/black video, due to the
4124// fact that code at some layers was doing case-insensitive comparisons and
4125// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004126TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07004127 ASSERT_TRUE(CreatePeerConnectionWrappers());
4128 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004129 caller()->AddAudioVideoTracks();
4130 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07004131
4132 // Remove all but one audio/video codec (opus and VP8), and change the
4133 // casing of the caller's generated offer.
4134 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
4135 cricket::AudioContentDescription* audio =
4136 GetFirstAudioContentDescription(description);
4137 ASSERT_NE(nullptr, audio);
4138 auto audio_codecs = audio->codecs();
4139 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
4140 [](const cricket::AudioCodec& codec) {
4141 return codec.name != "opus";
4142 }),
4143 audio_codecs.end());
4144 ASSERT_EQ(1u, audio_codecs.size());
4145 audio_codecs[0].name = "OpUs";
4146 audio->set_codecs(audio_codecs);
4147
4148 cricket::VideoContentDescription* video =
4149 GetFirstVideoContentDescription(description);
4150 ASSERT_NE(nullptr, video);
4151 auto video_codecs = video->codecs();
4152 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
4153 [](const cricket::VideoCodec& codec) {
4154 return codec.name != "VP8";
4155 }),
4156 video_codecs.end());
4157 ASSERT_EQ(1u, video_codecs.size());
4158 video_codecs[0].name = "vP8";
4159 video->set_codecs(video_codecs);
4160 });
4161
4162 caller()->CreateAndSetAndSignalOffer();
4163 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4164
4165 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004166 MediaExpectations media_expectations;
4167 media_expectations.ExpectBidirectionalAudioAndVideo();
4168 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07004169}
4170
Seth Hampson2f0d7022018-02-20 11:54:42 -08004171TEST_P(PeerConnectionIntegrationTest, GetSources) {
hbos8d609f62017-04-10 07:39:05 -07004172 ASSERT_TRUE(CreatePeerConnectionWrappers());
4173 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004174 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07004175 caller()->CreateAndSetAndSignalOffer();
4176 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07004177 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004178 MediaExpectations media_expectations;
4179 media_expectations.CalleeExpectsSomeAudio(1);
4180 ASSERT_TRUE(ExpectNewFrames(media_expectations));
hbos8d609f62017-04-10 07:39:05 -07004181 ASSERT_GT(callee()->pc()->GetReceivers().size(), 0u);
4182 auto receiver = callee()->pc()->GetReceivers()[0];
4183 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
4184
4185 auto contributing_sources = receiver->GetSources();
4186 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4187 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
4188 contributing_sources[0].source_id());
4189}
4190
deadbeef2f425aa2017-04-14 10:41:32 -07004191// Test that if a track is removed and added again with a different stream ID,
4192// the new stream ID is successfully communicated in SDP and media continues to
4193// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004194// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
4195// it will not reuse a transceiver that has already been sending. After creating
4196// a new transceiver it tries to create an offer with two senders of the same
4197// track ids and it fails.
4198TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07004199 ASSERT_TRUE(CreatePeerConnectionWrappers());
4200 ConnectFakeSignaling();
4201
deadbeef2f425aa2017-04-14 10:41:32 -07004202 // Add track using stream 1, do offer/answer.
4203 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
4204 caller()->CreateLocalAudioTrack();
4205 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07004206 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07004207 caller()->CreateAndSetAndSignalOffer();
4208 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004209 {
4210 MediaExpectations media_expectations;
4211 media_expectations.CalleeExpectsSomeAudio(1);
4212 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4213 }
deadbeef2f425aa2017-04-14 10:41:32 -07004214 // Remove the sender, and create a new one with the new stream.
4215 caller()->pc()->RemoveTrack(sender);
Steve Antond78323f2018-07-11 11:13:44 -07004216 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07004217 caller()->CreateAndSetAndSignalOffer();
4218 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4219 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004220 {
4221 MediaExpectations media_expectations;
4222 media_expectations.CalleeExpectsSomeAudio();
4223 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4224 }
deadbeef2f425aa2017-04-14 10:41:32 -07004225}
4226
Seth Hampson2f0d7022018-02-20 11:54:42 -08004227TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02004228 ASSERT_TRUE(CreatePeerConnectionWrappers());
4229 ConnectFakeSignaling();
4230
Karl Wiberg918f50c2018-07-05 11:40:33 +02004231 auto output = absl::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Elad Alon99c3fe52017-10-13 16:29:40 +02004232 ON_CALL(*output, IsActive()).WillByDefault(testing::Return(true));
4233 ON_CALL(*output, Write(::testing::_)).WillByDefault(testing::Return(true));
4234 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01004235 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
4236 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02004237
Steve Anton15324772018-01-16 10:26:49 -08004238 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02004239 caller()->CreateAndSetAndSignalOffer();
4240 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4241}
4242
Steve Antonede9ca52017-10-16 13:04:27 -07004243// Test that if candidates are only signaled by applying full session
4244// descriptions (instead of using AddIceCandidate), the peers can connect to
4245// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004246TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07004247 ASSERT_TRUE(CreatePeerConnectionWrappers());
4248 // Each side will signal the session descriptions but not candidates.
4249 ConnectFakeSignalingForSdpOnly();
4250
4251 // Add audio video track and exchange the initial offer/answer with media
4252 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08004253 caller()->AddAudioVideoTracks();
4254 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004255 caller()->CreateAndSetAndSignalOffer();
4256
4257 // Wait for all candidates to be gathered on both the caller and callee.
4258 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4259 caller()->ice_gathering_state(), kDefaultTimeout);
4260 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4261 callee()->ice_gathering_state(), kDefaultTimeout);
4262
4263 // The candidates will now be included in the session description, so
4264 // signaling them will start the ICE connection.
4265 caller()->CreateAndSetAndSignalOffer();
4266 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4267
4268 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004269 MediaExpectations media_expectations;
4270 media_expectations.ExpectBidirectionalAudioAndVideo();
4271 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07004272}
4273
henrika5f6bf242017-11-01 11:06:56 +01004274// Test that SetAudioPlayout can be used to disable audio playout from the
4275// start, then later enable it. This may be useful, for example, if the caller
4276// needs to play a local ringtone until some event occurs, after which it
4277// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004278TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01004279 ASSERT_TRUE(CreatePeerConnectionWrappers());
4280 ConnectFakeSignaling();
4281
4282 // Set up audio-only call where audio playout is disabled on caller's side.
4283 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08004284 caller()->AddAudioTrack();
4285 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004286 caller()->CreateAndSetAndSignalOffer();
4287 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4288
4289 // Pump messages for a second.
4290 WAIT(false, 1000);
4291 // Since audio playout is disabled, the caller shouldn't have received
4292 // anything (at the playout level, at least).
4293 EXPECT_EQ(0, caller()->audio_frames_received());
4294 // As a sanity check, make sure the callee (for which playout isn't disabled)
4295 // did still see frames on its audio level.
4296 ASSERT_GT(callee()->audio_frames_received(), 0);
4297
4298 // Enable playout again, and ensure audio starts flowing.
4299 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004300 MediaExpectations media_expectations;
4301 media_expectations.ExpectBidirectionalAudio();
4302 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01004303}
4304
4305double GetAudioEnergyStat(PeerConnectionWrapper* pc) {
4306 auto report = pc->NewGetStats();
4307 auto track_stats_list =
4308 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
4309 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
4310 for (const auto* track_stats : track_stats_list) {
4311 if (track_stats->remote_source.is_defined() &&
4312 *track_stats->remote_source) {
4313 remote_track_stats = track_stats;
4314 break;
4315 }
4316 }
4317
4318 if (!remote_track_stats->total_audio_energy.is_defined()) {
4319 return 0.0;
4320 }
4321 return *remote_track_stats->total_audio_energy;
4322}
4323
4324// Test that if audio playout is disabled via the SetAudioPlayout() method, then
4325// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004326TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01004327 DisableAudioPlayoutStillGeneratesAudioStats) {
4328 ASSERT_TRUE(CreatePeerConnectionWrappers());
4329 ConnectFakeSignaling();
4330
4331 // Set up audio-only call where playout is disabled but audio-processing is
4332 // still active.
Steve Anton15324772018-01-16 10:26:49 -08004333 caller()->AddAudioTrack();
4334 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004335 caller()->pc()->SetAudioPlayout(false);
4336
4337 caller()->CreateAndSetAndSignalOffer();
4338 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4339
4340 // Wait for the callee to receive audio stats.
4341 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
4342}
4343
henrika4f167df2017-11-01 14:45:55 +01004344// Test that SetAudioRecording can be used to disable audio recording from the
4345// start, then later enable it. This may be useful, for example, if the caller
4346// wants to ensure that no audio resources are active before a certain state
4347// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004348TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01004349 ASSERT_TRUE(CreatePeerConnectionWrappers());
4350 ConnectFakeSignaling();
4351
4352 // Set up audio-only call where audio recording is disabled on caller's side.
4353 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08004354 caller()->AddAudioTrack();
4355 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01004356 caller()->CreateAndSetAndSignalOffer();
4357 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4358
4359 // Pump messages for a second.
4360 WAIT(false, 1000);
4361 // Since caller has disabled audio recording, the callee shouldn't have
4362 // received anything.
4363 EXPECT_EQ(0, callee()->audio_frames_received());
4364 // As a sanity check, make sure the caller did still see frames on its
4365 // audio level since audio recording is enabled on the calle side.
4366 ASSERT_GT(caller()->audio_frames_received(), 0);
4367
4368 // Enable audio recording again, and ensure audio starts flowing.
4369 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004370 MediaExpectations media_expectations;
4371 media_expectations.ExpectBidirectionalAudio();
4372 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01004373}
4374
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004375// Test that after closing PeerConnections, they stop sending any packets (ICE,
4376// DTLS, RTP...).
Seth Hampson2f0d7022018-02-20 11:54:42 -08004377TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004378 // Set up audio/video/data, wait for some frames to be received.
4379 ASSERT_TRUE(CreatePeerConnectionWrappers());
4380 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004381 caller()->AddAudioVideoTracks();
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004382#ifdef HAVE_SCTP
4383 caller()->CreateDataChannel();
4384#endif
4385 caller()->CreateAndSetAndSignalOffer();
4386 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004387 MediaExpectations media_expectations;
4388 media_expectations.CalleeExpectsSomeAudioAndVideo();
4389 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004390 // Close PeerConnections.
4391 caller()->pc()->Close();
4392 callee()->pc()->Close();
4393 // Pump messages for a second, and ensure no new packets end up sent.
4394 uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
4395 WAIT(false, 1000);
4396 uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
4397 EXPECT_EQ(sent_packets_a, sent_packets_b);
4398}
4399
Steve Anton7eca0932018-03-30 15:18:41 -07004400// Test that transport stats are generated by the RTCStatsCollector for a
4401// connection that only involves data channels. This is a regression test for
4402// crbug.com/826972.
4403#ifdef HAVE_SCTP
4404TEST_P(PeerConnectionIntegrationTest,
4405 TransportStatsReportedForDataChannelOnlyConnection) {
4406 ASSERT_TRUE(CreatePeerConnectionWrappers());
4407 ConnectFakeSignaling();
4408 caller()->CreateDataChannel();
4409
4410 caller()->CreateAndSetAndSignalOffer();
4411 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4412 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
4413
4414 auto caller_report = caller()->NewGetStats();
4415 EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
4416 auto callee_report = callee()->NewGetStats();
4417 EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
4418}
4419#endif // HAVE_SCTP
4420
Qingsi Wang7685e862018-06-11 20:15:46 -07004421TEST_P(PeerConnectionIntegrationTest,
4422 IceEventsGeneratedAndLoggedInRtcEventLog) {
4423 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
4424 ConnectFakeSignaling();
4425 PeerConnectionInterface::RTCOfferAnswerOptions options;
4426 options.offer_to_receive_audio = 1;
4427 caller()->SetOfferAnswerOptions(options);
4428 caller()->CreateAndSetAndSignalOffer();
4429 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4430 ASSERT_NE(nullptr, caller()->event_log_factory());
4431 ASSERT_NE(nullptr, callee()->event_log_factory());
4432 webrtc::FakeRtcEventLog* caller_event_log =
4433 static_cast<webrtc::FakeRtcEventLog*>(
4434 caller()->event_log_factory()->last_log_created());
4435 webrtc::FakeRtcEventLog* callee_event_log =
4436 static_cast<webrtc::FakeRtcEventLog*>(
4437 callee()->event_log_factory()->last_log_created());
4438 ASSERT_NE(nullptr, caller_event_log);
4439 ASSERT_NE(nullptr, callee_event_log);
4440 int caller_ice_config_count = caller_event_log->GetEventCount(
4441 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4442 int caller_ice_event_count = caller_event_log->GetEventCount(
4443 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4444 int callee_ice_config_count = callee_event_log->GetEventCount(
4445 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4446 int callee_ice_event_count = callee_event_log->GetEventCount(
4447 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4448 EXPECT_LT(0, caller_ice_config_count);
4449 EXPECT_LT(0, caller_ice_event_count);
4450 EXPECT_LT(0, callee_ice_config_count);
4451 EXPECT_LT(0, callee_ice_event_count);
4452}
4453
Seth Hampson2f0d7022018-02-20 11:54:42 -08004454INSTANTIATE_TEST_CASE_P(PeerConnectionIntegrationTest,
4455 PeerConnectionIntegrationTest,
4456 Values(SdpSemantics::kPlanB,
4457 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-17 17:41:02 -08004458
Steve Anton74255ff2018-01-24 18:32:57 -08004459// Tests that verify interoperability between Plan B and Unified Plan
4460// PeerConnections.
4461class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08004462 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08004463 public ::testing::WithParamInterface<
4464 std::tuple<SdpSemantics, SdpSemantics>> {
4465 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08004466 // Setting the SdpSemantics for the base test to kDefault does not matter
4467 // because we specify not to use the test semantics when creating
4468 // PeerConnectionWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08004469 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07004470 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08004471 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08004472 callee_semantics_(std::get<1>(GetParam())) {}
4473
4474 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07004475 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
4476 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08004477 }
4478
4479 const SdpSemantics caller_semantics_;
4480 const SdpSemantics callee_semantics_;
4481};
4482
4483TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
4484 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4485 ConnectFakeSignaling();
4486
4487 caller()->CreateAndSetAndSignalOffer();
4488 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4489}
4490
4491TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
4492 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4493 ConnectFakeSignaling();
4494 auto audio_sender = caller()->AddAudioTrack();
4495
4496 caller()->CreateAndSetAndSignalOffer();
4497 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4498
4499 // Verify that one audio receiver has been created on the remote and that it
4500 // has the same track ID as the sending track.
4501 auto receivers = callee()->pc()->GetReceivers();
4502 ASSERT_EQ(1u, receivers.size());
4503 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
4504 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
4505
Seth Hampson2f0d7022018-02-20 11:54:42 -08004506 MediaExpectations media_expectations;
4507 media_expectations.CalleeExpectsSomeAudio();
4508 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004509}
4510
4511TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
4512 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4513 ConnectFakeSignaling();
4514 auto video_sender = caller()->AddVideoTrack();
4515 auto audio_sender = caller()->AddAudioTrack();
4516
4517 caller()->CreateAndSetAndSignalOffer();
4518 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4519
4520 // Verify that one audio and one video receiver have been created on the
4521 // remote and that they have the same track IDs as the sending tracks.
4522 auto audio_receivers =
4523 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
4524 ASSERT_EQ(1u, audio_receivers.size());
4525 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
4526 auto video_receivers =
4527 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
4528 ASSERT_EQ(1u, video_receivers.size());
4529 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
4530
Seth Hampson2f0d7022018-02-20 11:54:42 -08004531 MediaExpectations media_expectations;
4532 media_expectations.CalleeExpectsSomeAudioAndVideo();
4533 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004534}
4535
4536TEST_P(PeerConnectionIntegrationInteropTest,
4537 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
4538 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4539 ConnectFakeSignaling();
4540 caller()->AddAudioVideoTracks();
4541 callee()->AddAudioVideoTracks();
4542
4543 caller()->CreateAndSetAndSignalOffer();
4544 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4545
Seth Hampson2f0d7022018-02-20 11:54:42 -08004546 MediaExpectations media_expectations;
4547 media_expectations.ExpectBidirectionalAudioAndVideo();
4548 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004549}
4550
4551TEST_P(PeerConnectionIntegrationInteropTest,
4552 ReverseRolesOneAudioLocalToOneVideoRemote) {
4553 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4554 ConnectFakeSignaling();
4555 caller()->AddAudioTrack();
4556 callee()->AddVideoTrack();
4557
4558 caller()->CreateAndSetAndSignalOffer();
4559 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4560
4561 // Verify that only the audio track has been negotiated.
4562 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
4563 // Might also check that the callee's NegotiationNeeded flag is set.
4564
4565 // Reverse roles.
4566 callee()->CreateAndSetAndSignalOffer();
4567 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4568
Seth Hampson2f0d7022018-02-20 11:54:42 -08004569 MediaExpectations media_expectations;
4570 media_expectations.CallerExpectsSomeVideo();
4571 media_expectations.CalleeExpectsSomeAudio();
4572 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004573}
4574
Steve Antonba42e992018-04-09 14:10:01 -07004575INSTANTIATE_TEST_CASE_P(
4576 PeerConnectionIntegrationTest,
4577 PeerConnectionIntegrationInteropTest,
4578 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4579 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
4580
4581// Test that if the Unified Plan side offers two video tracks then the Plan B
4582// side will only see the first one and ignore the second.
4583TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07004584 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
4585 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08004586 ConnectFakeSignaling();
4587 auto first_sender = caller()->AddVideoTrack();
4588 caller()->AddVideoTrack();
4589
4590 caller()->CreateAndSetAndSignalOffer();
4591 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4592
4593 // Verify that there is only one receiver and it corresponds to the first
4594 // added track.
4595 auto receivers = callee()->pc()->GetReceivers();
4596 ASSERT_EQ(1u, receivers.size());
4597 EXPECT_TRUE(receivers[0]->track()->enabled());
4598 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
4599
Seth Hampson2f0d7022018-02-20 11:54:42 -08004600 MediaExpectations media_expectations;
4601 media_expectations.CalleeExpectsSomeVideo();
4602 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004603}
4604
deadbeef1dcb1642017-03-29 21:08:16 -07004605} // namespace
4606
4607#endif // if !defined(THREAD_SANITIZER)