blob: 28e0110355037ed4d7ec916326ae68f171ce13d3 [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"
Zach Stein6fcdc2f2018-08-23 16:25:55 -070040#include "p2p/base/mockasyncresolver.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020041#include "p2p/base/p2pconstants.h"
42#include "p2p/base/portinterface.h"
Steve Antonede9ca52017-10-16 13:04:27 -070043#include "p2p/base/teststunserver.h"
Jonas Orelandbdcee282017-10-10 14:01:40 +020044#include "p2p/base/testturncustomizer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020045#include "p2p/base/testturnserver.h"
46#include "p2p/client/basicportallocator.h"
47#include "pc/dtmfsender.h"
48#include "pc/localaudiosource.h"
49#include "pc/mediasession.h"
50#include "pc/peerconnection.h"
51#include "pc/peerconnectionfactory.h"
Seth Hampson2f0d7022018-02-20 11:54:42 -080052#include "pc/rtpmediautils.h"
Steve Anton4ab68ee2017-12-19 14:26:11 -080053#include "pc/sessiondescription.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020054#include "pc/test/fakeaudiocapturemodule.h"
Niels Möller0f405822018-05-17 09:16:41 +020055#include "pc/test/fakeperiodicvideotracksource.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020056#include "pc/test/fakertccertificategenerator.h"
57#include "pc/test/fakevideotrackrenderer.h"
58#include "pc/test/mockpeerconnectionobservers.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020059#include "rtc_base/fakenetwork.h"
Steve Antonede9ca52017-10-16 13:04:27 -070060#include "rtc_base/firewallsocketserver.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020061#include "rtc_base/gunit.h"
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +020062#include "rtc_base/numerics/safe_conversions.h"
Benjamin Wrightd6f86e82018-05-08 13:12:25 -070063#include "rtc_base/testcertificateverifier.h"
Johannes Kron965e7942018-09-13 15:36:20 +020064#include "rtc_base/timeutils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020065#include "rtc_base/virtualsocketserver.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020066#include "system_wrappers/include/metrics.h"
Elad Alon99c3fe52017-10-13 16:29:40 +020067#include "test/gmock.h"
deadbeef1dcb1642017-03-29 21:08:16 -070068
69using cricket::ContentInfo;
70using cricket::FakeWebRtcVideoDecoder;
71using cricket::FakeWebRtcVideoDecoderFactory;
72using cricket::FakeWebRtcVideoEncoder;
73using cricket::FakeWebRtcVideoEncoderFactory;
74using cricket::MediaContentDescription;
Steve Antondf527fd2018-04-27 15:52:03 -070075using cricket::StreamParams;
Steve Antonede9ca52017-10-16 13:04:27 -070076using rtc::SocketAddress;
Seth Hampson2f0d7022018-02-20 11:54:42 -080077using ::testing::Combine;
Steve Antonede9ca52017-10-16 13:04:27 -070078using ::testing::ElementsAre;
Zach Stein6fcdc2f2018-08-23 16:25:55 -070079using ::testing::Return;
80using ::testing::SetArgPointee;
Steve Antonede9ca52017-10-16 13:04:27 -070081using ::testing::Values;
Zach Stein6fcdc2f2018-08-23 16:25:55 -070082using ::testing::_;
deadbeef1dcb1642017-03-29 21:08:16 -070083using webrtc::DataBuffer;
84using webrtc::DataChannelInterface;
85using webrtc::DtmfSender;
86using webrtc::DtmfSenderInterface;
87using webrtc::DtmfSenderObserverInterface;
Steve Anton15324772018-01-16 10:26:49 -080088using webrtc::FakeVideoTrackRenderer;
deadbeef1dcb1642017-03-29 21:08:16 -070089using webrtc::MediaStreamInterface;
90using webrtc::MediaStreamTrackInterface;
91using webrtc::MockCreateSessionDescriptionObserver;
92using webrtc::MockDataChannelObserver;
93using webrtc::MockSetSessionDescriptionObserver;
94using webrtc::MockStatsObserver;
95using webrtc::ObserverInterface;
Steve Anton8c0f7a72017-10-03 10:03:10 -070096using webrtc::PeerConnection;
deadbeef1dcb1642017-03-29 21:08:16 -070097using webrtc::PeerConnectionInterface;
Steve Anton74255ff2018-01-24 18:32:57 -080098using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
deadbeef1dcb1642017-03-29 21:08:16 -070099using webrtc::PeerConnectionFactory;
Steve Anton8c0f7a72017-10-03 10:03:10 -0700100using webrtc::PeerConnectionProxy;
Steve Anton15324772018-01-16 10:26:49 -0800101using webrtc::RTCErrorType;
Steve Anton7eca0932018-03-30 15:18:41 -0700102using webrtc::RTCTransportStats;
Steve Anton74255ff2018-01-24 18:32:57 -0800103using webrtc::RtpSenderInterface;
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100104using webrtc::RtpReceiverInterface;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800105using webrtc::RtpSenderInterface;
106using webrtc::RtpTransceiverDirection;
107using webrtc::RtpTransceiverInit;
108using webrtc::RtpTransceiverInterface;
Steve Antond3679212018-01-17 17:41:02 -0800109using webrtc::SdpSemantics;
Steve Antona3a92c22017-12-07 10:27:41 -0800110using webrtc::SdpType;
deadbeef1dcb1642017-03-29 21:08:16 -0700111using webrtc::SessionDescriptionInterface;
112using webrtc::StreamCollectionInterface;
Steve Anton15324772018-01-16 10:26:49 -0800113using webrtc::VideoTrackInterface;
deadbeef1dcb1642017-03-29 21:08:16 -0700114
115namespace {
116
117static const int kDefaultTimeout = 10000;
118static const int kMaxWaitForStatsMs = 3000;
119static const int kMaxWaitForActivationMs = 5000;
120static const int kMaxWaitForFramesMs = 10000;
121// Default number of audio/video frames to wait for before considering a test
122// successful.
123static const int kDefaultExpectedAudioFrameCount = 3;
124static const int kDefaultExpectedVideoFrameCount = 3;
125
deadbeef1dcb1642017-03-29 21:08:16 -0700126static const char kDataChannelLabel[] = "data_channel";
127
128// SRTP cipher name negotiated by the tests. This must be updated if the
129// default changes.
Taylor Brandstetterfd350d72018-04-03 16:29:26 -0700130static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_80;
deadbeef1dcb1642017-03-29 21:08:16 -0700131static const int kDefaultSrtpCryptoSuiteGcm = rtc::SRTP_AEAD_AES_256_GCM;
132
Steve Antonede9ca52017-10-16 13:04:27 -0700133static const SocketAddress kDefaultLocalAddress("192.168.1.1", 0);
134
deadbeef1dcb1642017-03-29 21:08:16 -0700135// Helper function for constructing offer/answer options to initiate an ICE
136// restart.
137PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions() {
138 PeerConnectionInterface::RTCOfferAnswerOptions options;
139 options.ice_restart = true;
140 return options;
141}
142
deadbeefd8ad7882017-04-18 16:01:17 -0700143// Remove all stream information (SSRCs, track IDs, etc.) and "msid-semantic"
144// attribute from received SDP, simulating a legacy endpoint.
145void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) {
146 for (ContentInfo& content : desc->contents()) {
Steve Antonb1c1de12017-12-21 15:14:30 -0800147 content.media_description()->mutable_streams().clear();
deadbeefd8ad7882017-04-18 16:01:17 -0700148 }
149 desc->set_msid_supported(false);
150}
151
Seth Hampson5897a6e2018-04-03 11:16:33 -0700152// Removes all stream information besides the stream ids, simulating an
153// endpoint that only signals a=msid lines to convey stream_ids.
154void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) {
155 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700156 std::string track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700157 std::vector<std::string> stream_ids;
158 if (!content.media_description()->streams().empty()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700159 const StreamParams& first_stream =
160 content.media_description()->streams()[0];
161 track_id = first_stream.id;
162 stream_ids = first_stream.stream_ids();
Seth Hampson5897a6e2018-04-03 11:16:33 -0700163 }
164 content.media_description()->mutable_streams().clear();
Steve Antondf527fd2018-04-27 15:52:03 -0700165 StreamParams new_stream;
166 new_stream.id = track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700167 new_stream.set_stream_ids(stream_ids);
168 content.media_description()->AddStream(new_stream);
169 }
170}
171
zhihuangf8164932017-05-19 13:09:47 -0700172int FindFirstMediaStatsIndexByKind(
173 const std::string& kind,
174 const std::vector<const webrtc::RTCMediaStreamTrackStats*>&
175 media_stats_vec) {
176 for (size_t i = 0; i < media_stats_vec.size(); i++) {
177 if (media_stats_vec[i]->kind.ValueToString() == kind) {
178 return i;
179 }
180 }
181 return -1;
182}
183
deadbeef1dcb1642017-03-29 21:08:16 -0700184class SignalingMessageReceiver {
185 public:
Steve Antona3a92c22017-12-07 10:27:41 -0800186 virtual void ReceiveSdpMessage(SdpType type, const std::string& msg) = 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700187 virtual void ReceiveIceMessage(const std::string& sdp_mid,
188 int sdp_mline_index,
189 const std::string& msg) = 0;
190
191 protected:
192 SignalingMessageReceiver() {}
193 virtual ~SignalingMessageReceiver() {}
194};
195
196class MockRtpReceiverObserver : public webrtc::RtpReceiverObserverInterface {
197 public:
198 explicit MockRtpReceiverObserver(cricket::MediaType media_type)
199 : expected_media_type_(media_type) {}
200
201 void OnFirstPacketReceived(cricket::MediaType media_type) override {
202 ASSERT_EQ(expected_media_type_, media_type);
203 first_packet_received_ = true;
204 }
205
206 bool first_packet_received() const { return first_packet_received_; }
207
208 virtual ~MockRtpReceiverObserver() {}
209
210 private:
211 bool first_packet_received_ = false;
212 cricket::MediaType expected_media_type_;
213};
214
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700215// Used by PeerConnectionWrapper::OnIceCandidate to allow a test to modify an
216// ICE candidate before it is signaled.
217class IceCandidateReplacerInterface {
218 public:
219 virtual ~IceCandidateReplacerInterface() = default;
220 // Return nullptr to drop the candidate (it won't be signaled to the other
221 // side).
222 virtual std::unique_ptr<webrtc::IceCandidateInterface> ReplaceCandidate(
223 const webrtc::IceCandidateInterface*) = 0;
224};
225
deadbeef1dcb1642017-03-29 21:08:16 -0700226// Helper class that wraps a peer connection, observes it, and can accept
227// signaling messages from another wrapper.
228//
229// Uses a fake network, fake A/V capture, and optionally fake
230// encoders/decoders, though they aren't used by default since they don't
231// advertise support of any codecs.
Steve Anton94286cb2017-09-26 16:20:19 -0700232// TODO(steveanton): See how this could become a subclass of
Seth Hampson2f0d7022018-02-20 11:54:42 -0800233// PeerConnectionWrapper defined in peerconnectionwrapper.h.
deadbeef1dcb1642017-03-29 21:08:16 -0700234class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
Steve Anton15324772018-01-16 10:26:49 -0800235 public SignalingMessageReceiver {
deadbeef1dcb1642017-03-29 21:08:16 -0700236 public:
237 // Different factory methods for convenience.
238 // TODO(deadbeef): Could use the pattern of:
239 //
240 // PeerConnectionWrapper =
241 // WrapperBuilder.WithConfig(...).WithOptions(...).build();
242 //
243 // To reduce some code duplication.
244 static PeerConnectionWrapper* CreateWithDtlsIdentityStore(
245 const std::string& debug_name,
246 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
247 rtc::Thread* network_thread,
248 rtc::Thread* worker_thread) {
249 PeerConnectionWrapper* client(new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700250 webrtc::PeerConnectionDependencies dependencies(nullptr);
251 dependencies.cert_generator = std::move(cert_generator);
Niels Möllerf06f9232018-08-07 12:32:18 +0200252 if (!client->Init(nullptr, nullptr, std::move(dependencies), network_thread,
253 worker_thread, nullptr)) {
deadbeef1dcb1642017-03-29 21:08:16 -0700254 delete client;
255 return nullptr;
256 }
257 return client;
258 }
259
deadbeef2f425aa2017-04-14 10:41:32 -0700260 webrtc::PeerConnectionFactoryInterface* pc_factory() const {
261 return peer_connection_factory_.get();
262 }
263
deadbeef1dcb1642017-03-29 21:08:16 -0700264 webrtc::PeerConnectionInterface* pc() const { return peer_connection_.get(); }
265
266 // If a signaling message receiver is set (via ConnectFakeSignaling), this
267 // will set the whole offer/answer exchange in motion. Just need to wait for
268 // the signaling state to reach "stable".
269 void CreateAndSetAndSignalOffer() {
270 auto offer = CreateOffer();
271 ASSERT_NE(nullptr, offer);
272 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(offer)));
273 }
274
275 // Sets the options to be used when CreateAndSetAndSignalOffer is called, or
276 // when a remote offer is received (via fake signaling) and an answer is
277 // generated. By default, uses default options.
278 void SetOfferAnswerOptions(
279 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
280 offer_answer_options_ = options;
281 }
282
283 // Set a callback to be invoked when SDP is received via the fake signaling
284 // channel, which provides an opportunity to munge (modify) the SDP. This is
285 // used to test SDP being applied that a PeerConnection would normally not
286 // generate, but a non-JSEP endpoint might.
287 void SetReceivedSdpMunger(
288 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100289 received_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700290 }
291
deadbeefc964d0b2017-04-03 10:03:35 -0700292 // Similar to the above, but this is run on SDP immediately after it's
deadbeef1dcb1642017-03-29 21:08:16 -0700293 // generated.
294 void SetGeneratedSdpMunger(
295 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100296 generated_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700297 }
298
Seth Hampson2f0d7022018-02-20 11:54:42 -0800299 // Set a callback to be invoked when a remote offer is received via the fake
300 // signaling channel. This provides an opportunity to change the
301 // PeerConnection state before an answer is created and sent to the caller.
302 void SetRemoteOfferHandler(std::function<void()> handler) {
303 remote_offer_handler_ = std::move(handler);
304 }
305
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700306 void SetLocalIceCandidateReplacer(
307 std::unique_ptr<IceCandidateReplacerInterface> replacer) {
308 local_ice_candidate_replacer_ = std::move(replacer);
309 }
310
Steve Antonede9ca52017-10-16 13:04:27 -0700311 // Every ICE connection state in order that has been seen by the observer.
312 std::vector<PeerConnectionInterface::IceConnectionState>
313 ice_connection_state_history() const {
314 return ice_connection_state_history_;
315 }
Steve Anton6f25b092017-10-23 09:39:20 -0700316 void clear_ice_connection_state_history() {
317 ice_connection_state_history_.clear();
318 }
Steve Antonede9ca52017-10-16 13:04:27 -0700319
320 // Every ICE gathering state in order that has been seen by the observer.
321 std::vector<PeerConnectionInterface::IceGatheringState>
322 ice_gathering_state_history() const {
323 return ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -0700324 }
325
Steve Anton15324772018-01-16 10:26:49 -0800326 void AddAudioVideoTracks() {
327 AddAudioTrack();
328 AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700329 }
330
Steve Anton74255ff2018-01-24 18:32:57 -0800331 rtc::scoped_refptr<RtpSenderInterface> AddAudioTrack() {
332 return AddTrack(CreateLocalAudioTrack());
333 }
deadbeef1dcb1642017-03-29 21:08:16 -0700334
Steve Anton74255ff2018-01-24 18:32:57 -0800335 rtc::scoped_refptr<RtpSenderInterface> AddVideoTrack() {
336 return AddTrack(CreateLocalVideoTrack());
337 }
deadbeef1dcb1642017-03-29 21:08:16 -0700338
339 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack() {
Niels Möller2d02e082018-05-21 11:23:35 +0200340 cricket::AudioOptions options;
deadbeef1dcb1642017-03-29 21:08:16 -0700341 // Disable highpass filter so that we can get all the test audio frames.
Niels Möller2d02e082018-05-21 11:23:35 +0200342 options.highpass_filter = false;
deadbeef1dcb1642017-03-29 21:08:16 -0700343 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
Niels Möller2d02e082018-05-21 11:23:35 +0200344 peer_connection_factory_->CreateAudioSource(options);
deadbeef1dcb1642017-03-29 21:08:16 -0700345 // TODO(perkj): Test audio source when it is implemented. Currently audio
346 // always use the default input.
deadbeefb1a15d72017-09-07 14:12:05 -0700347 return peer_connection_factory_->CreateAudioTrack(rtc::CreateRandomUuid(),
deadbeef1dcb1642017-03-29 21:08:16 -0700348 source);
349 }
350
351 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack() {
Johannes Kron965e7942018-09-13 15:36:20 +0200352 webrtc::FakePeriodicVideoSource::Config config;
353 config.timestamp_offset_ms = rtc::TimeMillis();
354 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700355 }
356
357 rtc::scoped_refptr<webrtc::VideoTrackInterface>
Niels Möller5c7efe72018-05-11 10:34:46 +0200358 CreateLocalVideoTrackWithConfig(
359 webrtc::FakePeriodicVideoSource::Config config) {
360 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700361 }
362
363 rtc::scoped_refptr<webrtc::VideoTrackInterface>
364 CreateLocalVideoTrackWithRotation(webrtc::VideoRotation rotation) {
Niels Möller5c7efe72018-05-11 10:34:46 +0200365 webrtc::FakePeriodicVideoSource::Config config;
366 config.rotation = rotation;
Johannes Kron965e7942018-09-13 15:36:20 +0200367 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +0200368 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700369 }
370
Steve Anton74255ff2018-01-24 18:32:57 -0800371 rtc::scoped_refptr<RtpSenderInterface> AddTrack(
372 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800373 const std::vector<std::string>& stream_ids = {}) {
374 auto result = pc()->AddTrack(track, stream_ids);
Steve Anton15324772018-01-16 10:26:49 -0800375 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
Steve Anton74255ff2018-01-24 18:32:57 -0800376 return result.MoveValue();
377 }
378
379 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceiversOfType(
380 cricket::MediaType media_type) {
381 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
382 for (auto receiver : pc()->GetReceivers()) {
383 if (receiver->media_type() == media_type) {
384 receivers.push_back(receiver);
385 }
386 }
387 return receivers;
deadbeef1dcb1642017-03-29 21:08:16 -0700388 }
389
Seth Hampson2f0d7022018-02-20 11:54:42 -0800390 rtc::scoped_refptr<RtpTransceiverInterface> GetFirstTransceiverOfType(
391 cricket::MediaType media_type) {
392 for (auto transceiver : pc()->GetTransceivers()) {
393 if (transceiver->receiver()->media_type() == media_type) {
394 return transceiver;
395 }
396 }
397 return nullptr;
398 }
399
deadbeef1dcb1642017-03-29 21:08:16 -0700400 bool SignalingStateStable() {
401 return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable;
402 }
403
404 void CreateDataChannel() { CreateDataChannel(nullptr); }
405
406 void CreateDataChannel(const webrtc::DataChannelInit* init) {
Steve Antonda6c0952017-10-23 11:41:54 -0700407 CreateDataChannel(kDataChannelLabel, init);
408 }
409
410 void CreateDataChannel(const std::string& label,
411 const webrtc::DataChannelInit* init) {
412 data_channel_ = pc()->CreateDataChannel(label, init);
deadbeef1dcb1642017-03-29 21:08:16 -0700413 ASSERT_TRUE(data_channel_.get() != nullptr);
414 data_observer_.reset(new MockDataChannelObserver(data_channel_));
415 }
416
417 DataChannelInterface* data_channel() { return data_channel_; }
418 const MockDataChannelObserver* data_observer() const {
419 return data_observer_.get();
420 }
421
422 int audio_frames_received() const {
423 return fake_audio_capture_module_->frames_received();
424 }
425
426 // Takes minimum of video frames received for each track.
427 //
428 // Can be used like:
429 // EXPECT_GE(expected_frames, min_video_frames_received_per_track());
430 //
431 // To ensure that all video tracks received at least a certain number of
432 // frames.
433 int min_video_frames_received_per_track() const {
434 int min_frames = INT_MAX;
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200435 if (fake_video_renderers_.empty()) {
436 return 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700437 }
deadbeef1dcb1642017-03-29 21:08:16 -0700438
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200439 for (const auto& pair : fake_video_renderers_) {
440 min_frames = std::min(min_frames, pair.second->num_rendered_frames());
deadbeef1dcb1642017-03-29 21:08:16 -0700441 }
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200442 return min_frames;
deadbeef1dcb1642017-03-29 21:08:16 -0700443 }
444
445 // Returns a MockStatsObserver in a state after stats gathering finished,
446 // which can be used to access the gathered stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700447 rtc::scoped_refptr<MockStatsObserver> OldGetStatsForTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700448 webrtc::MediaStreamTrackInterface* track) {
449 rtc::scoped_refptr<MockStatsObserver> observer(
450 new rtc::RefCountedObject<MockStatsObserver>());
451 EXPECT_TRUE(peer_connection_->GetStats(
452 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard));
453 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
454 return observer;
455 }
456
457 // Version that doesn't take a track "filter", and gathers all stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700458 rtc::scoped_refptr<MockStatsObserver> OldGetStats() {
459 return OldGetStatsForTrack(nullptr);
460 }
461
462 // Synchronously gets stats and returns them. If it times out, fails the test
463 // and returns null.
464 rtc::scoped_refptr<const webrtc::RTCStatsReport> NewGetStats() {
465 rtc::scoped_refptr<webrtc::MockRTCStatsCollectorCallback> callback(
466 new rtc::RefCountedObject<webrtc::MockRTCStatsCollectorCallback>());
467 peer_connection_->GetStats(callback);
468 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
469 return callback->report();
deadbeef1dcb1642017-03-29 21:08:16 -0700470 }
471
472 int rendered_width() {
473 EXPECT_FALSE(fake_video_renderers_.empty());
474 return fake_video_renderers_.empty()
475 ? 0
476 : fake_video_renderers_.begin()->second->width();
477 }
478
479 int rendered_height() {
480 EXPECT_FALSE(fake_video_renderers_.empty());
481 return fake_video_renderers_.empty()
482 ? 0
483 : fake_video_renderers_.begin()->second->height();
484 }
485
486 double rendered_aspect_ratio() {
487 if (rendered_height() == 0) {
488 return 0.0;
489 }
490 return static_cast<double>(rendered_width()) / rendered_height();
491 }
492
493 webrtc::VideoRotation rendered_rotation() {
494 EXPECT_FALSE(fake_video_renderers_.empty());
495 return fake_video_renderers_.empty()
496 ? webrtc::kVideoRotation_0
497 : fake_video_renderers_.begin()->second->rotation();
498 }
499
500 int local_rendered_width() {
501 return local_video_renderer_ ? local_video_renderer_->width() : 0;
502 }
503
504 int local_rendered_height() {
505 return local_video_renderer_ ? local_video_renderer_->height() : 0;
506 }
507
508 double local_rendered_aspect_ratio() {
509 if (local_rendered_height() == 0) {
510 return 0.0;
511 }
512 return static_cast<double>(local_rendered_width()) /
513 local_rendered_height();
514 }
515
516 size_t number_of_remote_streams() {
517 if (!pc()) {
518 return 0;
519 }
520 return pc()->remote_streams()->count();
521 }
522
523 StreamCollectionInterface* remote_streams() const {
524 if (!pc()) {
525 ADD_FAILURE();
526 return nullptr;
527 }
528 return pc()->remote_streams();
529 }
530
531 StreamCollectionInterface* local_streams() {
532 if (!pc()) {
533 ADD_FAILURE();
534 return nullptr;
535 }
536 return pc()->local_streams();
537 }
538
539 webrtc::PeerConnectionInterface::SignalingState signaling_state() {
540 return pc()->signaling_state();
541 }
542
543 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() {
544 return pc()->ice_connection_state();
545 }
546
547 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() {
548 return pc()->ice_gathering_state();
549 }
550
551 // Returns a MockRtpReceiverObserver for each RtpReceiver returned by
552 // GetReceivers. They're updated automatically when a remote offer/answer
553 // from the fake signaling channel is applied, or when
554 // ResetRtpReceiverObservers below is called.
555 const std::vector<std::unique_ptr<MockRtpReceiverObserver>>&
556 rtp_receiver_observers() {
557 return rtp_receiver_observers_;
558 }
559
560 void ResetRtpReceiverObservers() {
561 rtp_receiver_observers_.clear();
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100562 for (const rtc::scoped_refptr<RtpReceiverInterface>& receiver :
563 pc()->GetReceivers()) {
deadbeef1dcb1642017-03-29 21:08:16 -0700564 std::unique_ptr<MockRtpReceiverObserver> observer(
565 new MockRtpReceiverObserver(receiver->media_type()));
566 receiver->SetObserver(observer.get());
567 rtp_receiver_observers_.push_back(std::move(observer));
568 }
569 }
570
Steve Antonede9ca52017-10-16 13:04:27 -0700571 rtc::FakeNetworkManager* network() const {
572 return fake_network_manager_.get();
573 }
574 cricket::PortAllocator* port_allocator() const { return port_allocator_; }
575
Qingsi Wang7685e862018-06-11 20:15:46 -0700576 webrtc::FakeRtcEventLogFactory* event_log_factory() const {
577 return event_log_factory_;
578 }
579
deadbeef1dcb1642017-03-29 21:08:16 -0700580 private:
581 explicit PeerConnectionWrapper(const std::string& debug_name)
582 : debug_name_(debug_name) {}
583
Niels Möllerf06f9232018-08-07 12:32:18 +0200584 bool Init(const PeerConnectionFactory::Options* options,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700585 const PeerConnectionInterface::RTCConfiguration* config,
586 webrtc::PeerConnectionDependencies dependencies,
587 rtc::Thread* network_thread,
Qingsi Wang7685e862018-06-11 20:15:46 -0700588 rtc::Thread* worker_thread,
589 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory) {
deadbeef1dcb1642017-03-29 21:08:16 -0700590 // There's an error in this test code if Init ends up being called twice.
591 RTC_DCHECK(!peer_connection_);
592 RTC_DCHECK(!peer_connection_factory_);
593
594 fake_network_manager_.reset(new rtc::FakeNetworkManager());
Steve Antonede9ca52017-10-16 13:04:27 -0700595 fake_network_manager_->AddInterface(kDefaultLocalAddress);
deadbeef1dcb1642017-03-29 21:08:16 -0700596
597 std::unique_ptr<cricket::PortAllocator> port_allocator(
598 new cricket::BasicPortAllocator(fake_network_manager_.get()));
Steve Antonede9ca52017-10-16 13:04:27 -0700599 port_allocator_ = port_allocator.get();
deadbeef1dcb1642017-03-29 21:08:16 -0700600 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
601 if (!fake_audio_capture_module_) {
602 return false;
603 }
deadbeef1dcb1642017-03-29 21:08:16 -0700604 rtc::Thread* const signaling_thread = rtc::Thread::Current();
Qingsi Wang7685e862018-06-11 20:15:46 -0700605
606 webrtc::PeerConnectionFactoryDependencies pc_factory_dependencies;
607 pc_factory_dependencies.network_thread = network_thread;
608 pc_factory_dependencies.worker_thread = worker_thread;
609 pc_factory_dependencies.signaling_thread = signaling_thread;
610 pc_factory_dependencies.media_engine =
611 cricket::WebRtcMediaEngineFactory::Create(
612 rtc::scoped_refptr<webrtc::AudioDeviceModule>(
613 fake_audio_capture_module_),
614 webrtc::CreateBuiltinAudioEncoderFactory(),
615 webrtc::CreateBuiltinAudioDecoderFactory(),
616 webrtc::CreateBuiltinVideoEncoderFactory(),
617 webrtc::CreateBuiltinVideoDecoderFactory(), nullptr,
618 webrtc::AudioProcessingBuilder().Create());
619 pc_factory_dependencies.call_factory = webrtc::CreateCallFactory();
620 if (event_log_factory) {
621 event_log_factory_ = event_log_factory.get();
622 pc_factory_dependencies.event_log_factory = std::move(event_log_factory);
623 } else {
624 pc_factory_dependencies.event_log_factory =
625 webrtc::CreateRtcEventLogFactory();
626 }
627 peer_connection_factory_ = webrtc::CreateModularPeerConnectionFactory(
628 std::move(pc_factory_dependencies));
629
deadbeef1dcb1642017-03-29 21:08:16 -0700630 if (!peer_connection_factory_) {
631 return false;
632 }
633 if (options) {
634 peer_connection_factory_->SetOptions(*options);
635 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800636 if (config) {
637 sdp_semantics_ = config->sdp_semantics;
638 }
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700639
640 dependencies.allocator = std::move(port_allocator);
Niels Möllerf06f9232018-08-07 12:32:18 +0200641 peer_connection_ = CreatePeerConnection(config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700642 return peer_connection_.get() != nullptr;
643 }
644
645 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(
deadbeef1dcb1642017-03-29 21:08:16 -0700646 const PeerConnectionInterface::RTCConfiguration* config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700647 webrtc::PeerConnectionDependencies dependencies) {
deadbeef1dcb1642017-03-29 21:08:16 -0700648 PeerConnectionInterface::RTCConfiguration modified_config;
649 // If |config| is null, this will result in a default configuration being
650 // used.
651 if (config) {
652 modified_config = *config;
653 }
654 // Disable resolution adaptation; we don't want it interfering with the
655 // test results.
656 // TODO(deadbeef): Do something more robust. Since we're testing for aspect
657 // ratios and not specific resolutions, is this even necessary?
658 modified_config.set_cpu_adaptation(false);
659
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700660 dependencies.observer = this;
deadbeef1dcb1642017-03-29 21:08:16 -0700661 return peer_connection_factory_->CreatePeerConnection(
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700662 modified_config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700663 }
664
665 void set_signaling_message_receiver(
666 SignalingMessageReceiver* signaling_message_receiver) {
667 signaling_message_receiver_ = signaling_message_receiver;
668 }
669
670 void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; }
671
Steve Antonede9ca52017-10-16 13:04:27 -0700672 void set_signal_ice_candidates(bool signal) {
673 signal_ice_candidates_ = signal;
674 }
675
deadbeef1dcb1642017-03-29 21:08:16 -0700676 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
Niels Möller5c7efe72018-05-11 10:34:46 +0200677 webrtc::FakePeriodicVideoSource::Config config) {
deadbeef1dcb1642017-03-29 21:08:16 -0700678 // Set max frame rate to 10fps to reduce the risk of test flakiness.
679 // TODO(deadbeef): Do something more robust.
Niels Möller5c7efe72018-05-11 10:34:46 +0200680 config.frame_interval_ms = 100;
deadbeef1dcb1642017-03-29 21:08:16 -0700681
Niels Möller5c7efe72018-05-11 10:34:46 +0200682 video_track_sources_.emplace_back(
Niels Möller0f405822018-05-17 09:16:41 +0200683 new rtc::RefCountedObject<webrtc::FakePeriodicVideoTrackSource>(
684 config, false /* remote */));
deadbeef1dcb1642017-03-29 21:08:16 -0700685 rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
Niels Möller5c7efe72018-05-11 10:34:46 +0200686 peer_connection_factory_->CreateVideoTrack(
687 rtc::CreateRandomUuid(), video_track_sources_.back()));
deadbeef1dcb1642017-03-29 21:08:16 -0700688 if (!local_video_renderer_) {
689 local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
690 }
691 return track;
692 }
693
694 void HandleIncomingOffer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100695 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer";
Steve Antona3a92c22017-12-07 10:27:41 -0800696 std::unique_ptr<SessionDescriptionInterface> desc =
697 webrtc::CreateSessionDescription(SdpType::kOffer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700698 if (received_sdp_munger_) {
699 received_sdp_munger_(desc->description());
700 }
701
702 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
703 // Setting a remote description may have changed the number of receivers,
704 // so reset the receiver observers.
705 ResetRtpReceiverObservers();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800706 if (remote_offer_handler_) {
707 remote_offer_handler_();
708 }
deadbeef1dcb1642017-03-29 21:08:16 -0700709 auto answer = CreateAnswer();
710 ASSERT_NE(nullptr, answer);
711 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
712 }
713
714 void HandleIncomingAnswer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100715 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
Steve Antona3a92c22017-12-07 10:27:41 -0800716 std::unique_ptr<SessionDescriptionInterface> desc =
717 webrtc::CreateSessionDescription(SdpType::kAnswer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700718 if (received_sdp_munger_) {
719 received_sdp_munger_(desc->description());
720 }
721
722 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
723 // Set the RtpReceiverObserver after receivers are created.
724 ResetRtpReceiverObservers();
725 }
726
727 // Returns null on failure.
728 std::unique_ptr<SessionDescriptionInterface> CreateOffer() {
729 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
730 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
731 pc()->CreateOffer(observer, offer_answer_options_);
732 return WaitForDescriptionFromObserver(observer);
733 }
734
735 // Returns null on failure.
736 std::unique_ptr<SessionDescriptionInterface> CreateAnswer() {
737 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
738 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
739 pc()->CreateAnswer(observer, offer_answer_options_);
740 return WaitForDescriptionFromObserver(observer);
741 }
742
743 std::unique_ptr<SessionDescriptionInterface> WaitForDescriptionFromObserver(
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100744 MockCreateSessionDescriptionObserver* observer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700745 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
746 if (!observer->result()) {
747 return nullptr;
748 }
749 auto description = observer->MoveDescription();
750 if (generated_sdp_munger_) {
751 generated_sdp_munger_(description->description());
752 }
753 return description;
754 }
755
756 // Setting the local description and sending the SDP message over the fake
757 // signaling channel are combined into the same method because the SDP
758 // message needs to be sent as soon as SetLocalDescription finishes, without
759 // waiting for the observer to be called. This ensures that ICE candidates
760 // don't outrace the description.
761 bool SetLocalDescriptionAndSendSdpMessage(
762 std::unique_ptr<SessionDescriptionInterface> desc) {
763 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
764 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100765 RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage";
Steve Antona3a92c22017-12-07 10:27:41 -0800766 SdpType type = desc->GetType();
deadbeef1dcb1642017-03-29 21:08:16 -0700767 std::string sdp;
768 EXPECT_TRUE(desc->ToString(&sdp));
769 pc()->SetLocalDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800770 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
771 RemoveUnusedVideoRenderers();
772 }
deadbeef1dcb1642017-03-29 21:08:16 -0700773 // As mentioned above, we need to send the message immediately after
774 // SetLocalDescription.
775 SendSdpMessage(type, sdp);
776 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
777 return true;
778 }
779
780 bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
781 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
782 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100783 RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription";
deadbeef1dcb1642017-03-29 21:08:16 -0700784 pc()->SetRemoteDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800785 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
786 RemoveUnusedVideoRenderers();
787 }
deadbeef1dcb1642017-03-29 21:08:16 -0700788 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
789 return observer->result();
790 }
791
Seth Hampson2f0d7022018-02-20 11:54:42 -0800792 // This is a work around to remove unused fake_video_renderers from
793 // transceivers that have either stopped or are no longer receiving.
794 void RemoveUnusedVideoRenderers() {
795 auto transceivers = pc()->GetTransceivers();
796 for (auto& transceiver : transceivers) {
797 if (transceiver->receiver()->media_type() != cricket::MEDIA_TYPE_VIDEO) {
798 continue;
799 }
800 // Remove fake video renderers from any stopped transceivers.
801 if (transceiver->stopped()) {
802 auto it =
803 fake_video_renderers_.find(transceiver->receiver()->track()->id());
804 if (it != fake_video_renderers_.end()) {
805 fake_video_renderers_.erase(it);
806 }
807 }
808 // Remove fake video renderers from any transceivers that are no longer
809 // receiving.
810 if ((transceiver->current_direction() &&
811 !webrtc::RtpTransceiverDirectionHasRecv(
812 *transceiver->current_direction()))) {
813 auto it =
814 fake_video_renderers_.find(transceiver->receiver()->track()->id());
815 if (it != fake_video_renderers_.end()) {
816 fake_video_renderers_.erase(it);
817 }
818 }
819 }
820 }
821
deadbeef1dcb1642017-03-29 21:08:16 -0700822 // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by
823 // default).
Steve Antona3a92c22017-12-07 10:27:41 -0800824 void SendSdpMessage(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700825 if (signaling_delay_ms_ == 0) {
826 RelaySdpMessageIfReceiverExists(type, msg);
827 } else {
828 invoker_.AsyncInvokeDelayed<void>(
829 RTC_FROM_HERE, rtc::Thread::Current(),
830 rtc::Bind(&PeerConnectionWrapper::RelaySdpMessageIfReceiverExists,
831 this, type, msg),
832 signaling_delay_ms_);
833 }
834 }
835
Steve Antona3a92c22017-12-07 10:27:41 -0800836 void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700837 if (signaling_message_receiver_) {
838 signaling_message_receiver_->ReceiveSdpMessage(type, msg);
839 }
840 }
841
842 // Simulate trickling an ICE candidate with delay |signaling_delay_ms_| (0 by
843 // default).
844 void SendIceMessage(const std::string& sdp_mid,
845 int sdp_mline_index,
846 const std::string& msg) {
847 if (signaling_delay_ms_ == 0) {
848 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
849 } else {
850 invoker_.AsyncInvokeDelayed<void>(
851 RTC_FROM_HERE, rtc::Thread::Current(),
852 rtc::Bind(&PeerConnectionWrapper::RelayIceMessageIfReceiverExists,
853 this, sdp_mid, sdp_mline_index, msg),
854 signaling_delay_ms_);
855 }
856 }
857
858 void RelayIceMessageIfReceiverExists(const std::string& sdp_mid,
859 int sdp_mline_index,
860 const std::string& msg) {
861 if (signaling_message_receiver_) {
862 signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index,
863 msg);
864 }
865 }
866
867 // SignalingMessageReceiver callbacks.
Steve Antona3a92c22017-12-07 10:27:41 -0800868 void ReceiveSdpMessage(SdpType type, const std::string& msg) override {
869 if (type == SdpType::kOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700870 HandleIncomingOffer(msg);
871 } else {
872 HandleIncomingAnswer(msg);
873 }
874 }
875
876 void ReceiveIceMessage(const std::string& sdp_mid,
877 int sdp_mline_index,
878 const std::string& msg) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100879 RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage";
deadbeef1dcb1642017-03-29 21:08:16 -0700880 std::unique_ptr<webrtc::IceCandidateInterface> candidate(
881 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr));
882 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
883 }
884
885 // PeerConnectionObserver callbacks.
886 void OnSignalingChange(
887 webrtc::PeerConnectionInterface::SignalingState new_state) override {
888 EXPECT_EQ(pc()->signaling_state(), new_state);
889 }
Steve Anton15324772018-01-16 10:26:49 -0800890 void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
891 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
892 streams) override {
893 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
894 rtc::scoped_refptr<VideoTrackInterface> video_track(
895 static_cast<VideoTrackInterface*>(receiver->track().get()));
896 ASSERT_TRUE(fake_video_renderers_.find(video_track->id()) ==
deadbeef1dcb1642017-03-29 21:08:16 -0700897 fake_video_renderers_.end());
Steve Anton15324772018-01-16 10:26:49 -0800898 fake_video_renderers_[video_track->id()] =
Karl Wiberg918f50c2018-07-05 11:40:33 +0200899 absl::make_unique<FakeVideoTrackRenderer>(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -0700900 }
901 }
Steve Anton15324772018-01-16 10:26:49 -0800902 void OnRemoveTrack(
903 rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
904 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
905 auto it = fake_video_renderers_.find(receiver->track()->id());
906 RTC_DCHECK(it != fake_video_renderers_.end());
907 fake_video_renderers_.erase(it);
908 }
909 }
deadbeef1dcb1642017-03-29 21:08:16 -0700910 void OnRenegotiationNeeded() override {}
911 void OnIceConnectionChange(
912 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
913 EXPECT_EQ(pc()->ice_connection_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700914 ice_connection_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700915 }
916 void OnIceGatheringChange(
917 webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
deadbeef1dcb1642017-03-29 21:08:16 -0700918 EXPECT_EQ(pc()->ice_gathering_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700919 ice_gathering_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700920 }
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700921 std::unique_ptr<webrtc::IceCandidateInterface> ReplaceIceCandidate(
922 const webrtc::IceCandidateInterface* candidate) {
923 std::string candidate_string;
924 candidate->ToString(&candidate_string);
925
926 auto owned_candidate =
927 local_ice_candidate_replacer_->ReplaceCandidate(candidate);
928 if (!owned_candidate) {
929 RTC_LOG(LS_INFO) << "LocalIceCandidateReplacer dropped \""
930 << candidate_string << "\"";
931 return nullptr;
932 }
933 std::string owned_candidate_string;
934 owned_candidate->ToString(&owned_candidate_string);
935 RTC_LOG(LS_INFO) << "LocalIceCandidateReplacer changed \""
936 << candidate_string << "\" to \"" << owned_candidate_string
937 << "\"";
938 return owned_candidate;
939 }
deadbeef1dcb1642017-03-29 21:08:16 -0700940 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100941 RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate";
deadbeef1dcb1642017-03-29 21:08:16 -0700942
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700943 const webrtc::IceCandidateInterface* new_candidate = candidate;
944 std::unique_ptr<webrtc::IceCandidateInterface> owned_candidate;
945 if (local_ice_candidate_replacer_) {
946 owned_candidate = ReplaceIceCandidate(candidate);
947 if (!owned_candidate) {
948 return; // The candidate was dropped.
949 }
950 new_candidate = owned_candidate.get();
951 }
952
deadbeef1dcb1642017-03-29 21:08:16 -0700953 std::string ice_sdp;
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700954 EXPECT_TRUE(new_candidate->ToString(&ice_sdp));
Steve Antonede9ca52017-10-16 13:04:27 -0700955 if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) {
deadbeef1dcb1642017-03-29 21:08:16 -0700956 // Remote party may be deleted.
957 return;
958 }
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700959 SendIceMessage(new_candidate->sdp_mid(), new_candidate->sdp_mline_index(),
960 ice_sdp);
deadbeef1dcb1642017-03-29 21:08:16 -0700961 }
962 void OnDataChannel(
963 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100964 RTC_LOG(LS_INFO) << debug_name_ << ": OnDataChannel";
deadbeef1dcb1642017-03-29 21:08:16 -0700965 data_channel_ = data_channel;
966 data_observer_.reset(new MockDataChannelObserver(data_channel));
967 }
968
deadbeef1dcb1642017-03-29 21:08:16 -0700969 std::string debug_name_;
970
971 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
972
973 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
974 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
975 peer_connection_factory_;
976
Steve Antonede9ca52017-10-16 13:04:27 -0700977 cricket::PortAllocator* port_allocator_;
deadbeef1dcb1642017-03-29 21:08:16 -0700978 // Needed to keep track of number of frames sent.
979 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
980 // Needed to keep track of number of frames received.
981 std::map<std::string, std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
982 fake_video_renderers_;
983 // Needed to ensure frames aren't received for removed tracks.
984 std::vector<std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
985 removed_fake_video_renderers_;
deadbeef1dcb1642017-03-29 21:08:16 -0700986
987 // For remote peer communication.
988 SignalingMessageReceiver* signaling_message_receiver_ = nullptr;
989 int signaling_delay_ms_ = 0;
Steve Antonede9ca52017-10-16 13:04:27 -0700990 bool signal_ice_candidates_ = true;
deadbeef1dcb1642017-03-29 21:08:16 -0700991
Niels Möller5c7efe72018-05-11 10:34:46 +0200992 // Store references to the video sources we've created, so that we can stop
deadbeef1dcb1642017-03-29 21:08:16 -0700993 // them, if required.
Niels Möller5c7efe72018-05-11 10:34:46 +0200994 std::vector<rtc::scoped_refptr<webrtc::VideoTrackSource>>
995 video_track_sources_;
deadbeef1dcb1642017-03-29 21:08:16 -0700996 // |local_video_renderer_| attached to the first created local video track.
997 std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
998
Seth Hampson2f0d7022018-02-20 11:54:42 -0800999 SdpSemantics sdp_semantics_;
deadbeef1dcb1642017-03-29 21:08:16 -07001000 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_;
1001 std::function<void(cricket::SessionDescription*)> received_sdp_munger_;
1002 std::function<void(cricket::SessionDescription*)> generated_sdp_munger_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001003 std::function<void()> remote_offer_handler_;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001004 std::unique_ptr<IceCandidateReplacerInterface> local_ice_candidate_replacer_;
deadbeef1dcb1642017-03-29 21:08:16 -07001005 rtc::scoped_refptr<DataChannelInterface> data_channel_;
1006 std::unique_ptr<MockDataChannelObserver> data_observer_;
1007
1008 std::vector<std::unique_ptr<MockRtpReceiverObserver>> rtp_receiver_observers_;
1009
Steve Antonede9ca52017-10-16 13:04:27 -07001010 std::vector<PeerConnectionInterface::IceConnectionState>
1011 ice_connection_state_history_;
1012 std::vector<PeerConnectionInterface::IceGatheringState>
1013 ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -07001014
Qingsi Wang7685e862018-06-11 20:15:46 -07001015 webrtc::FakeRtcEventLogFactory* event_log_factory_;
1016
deadbeef1dcb1642017-03-29 21:08:16 -07001017 rtc::AsyncInvoker invoker_;
1018
Seth Hampson2f0d7022018-02-20 11:54:42 -08001019 friend class PeerConnectionIntegrationBaseTest;
deadbeef1dcb1642017-03-29 21:08:16 -07001020};
1021
Elad Alon99c3fe52017-10-13 16:29:40 +02001022class MockRtcEventLogOutput : public webrtc::RtcEventLogOutput {
1023 public:
1024 virtual ~MockRtcEventLogOutput() = default;
1025 MOCK_CONST_METHOD0(IsActive, bool());
1026 MOCK_METHOD1(Write, bool(const std::string&));
1027};
1028
Seth Hampson2f0d7022018-02-20 11:54:42 -08001029// This helper object is used for both specifying how many audio/video frames
1030// are expected to be received for a caller/callee. It provides helper functions
1031// to specify these expectations. The object initially starts in a state of no
1032// expectations.
1033class MediaExpectations {
1034 public:
1035 enum ExpectFrames {
1036 kExpectSomeFrames,
1037 kExpectNoFrames,
1038 kNoExpectation,
1039 };
1040
1041 void ExpectBidirectionalAudioAndVideo() {
1042 ExpectBidirectionalAudio();
1043 ExpectBidirectionalVideo();
1044 }
1045
1046 void ExpectBidirectionalAudio() {
1047 CallerExpectsSomeAudio();
1048 CalleeExpectsSomeAudio();
1049 }
1050
1051 void ExpectNoAudio() {
1052 CallerExpectsNoAudio();
1053 CalleeExpectsNoAudio();
1054 }
1055
1056 void ExpectBidirectionalVideo() {
1057 CallerExpectsSomeVideo();
1058 CalleeExpectsSomeVideo();
1059 }
1060
1061 void ExpectNoVideo() {
1062 CallerExpectsNoVideo();
1063 CalleeExpectsNoVideo();
1064 }
1065
1066 void CallerExpectsSomeAudioAndVideo() {
1067 CallerExpectsSomeAudio();
1068 CallerExpectsSomeVideo();
1069 }
1070
1071 void CalleeExpectsSomeAudioAndVideo() {
1072 CalleeExpectsSomeAudio();
1073 CalleeExpectsSomeVideo();
1074 }
1075
1076 // Caller's audio functions.
1077 void CallerExpectsSomeAudio(
1078 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1079 caller_audio_expectation_ = kExpectSomeFrames;
1080 caller_audio_frames_expected_ = expected_audio_frames;
1081 }
1082
1083 void CallerExpectsNoAudio() {
1084 caller_audio_expectation_ = kExpectNoFrames;
1085 caller_audio_frames_expected_ = 0;
1086 }
1087
1088 // Caller's video functions.
1089 void CallerExpectsSomeVideo(
1090 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1091 caller_video_expectation_ = kExpectSomeFrames;
1092 caller_video_frames_expected_ = expected_video_frames;
1093 }
1094
1095 void CallerExpectsNoVideo() {
1096 caller_video_expectation_ = kExpectNoFrames;
1097 caller_video_frames_expected_ = 0;
1098 }
1099
1100 // Callee's audio functions.
1101 void CalleeExpectsSomeAudio(
1102 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1103 callee_audio_expectation_ = kExpectSomeFrames;
1104 callee_audio_frames_expected_ = expected_audio_frames;
1105 }
1106
1107 void CalleeExpectsNoAudio() {
1108 callee_audio_expectation_ = kExpectNoFrames;
1109 callee_audio_frames_expected_ = 0;
1110 }
1111
1112 // Callee's video functions.
1113 void CalleeExpectsSomeVideo(
1114 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1115 callee_video_expectation_ = kExpectSomeFrames;
1116 callee_video_frames_expected_ = expected_video_frames;
1117 }
1118
1119 void CalleeExpectsNoVideo() {
1120 callee_video_expectation_ = kExpectNoFrames;
1121 callee_video_frames_expected_ = 0;
1122 }
1123
1124 ExpectFrames caller_audio_expectation_ = kNoExpectation;
1125 ExpectFrames caller_video_expectation_ = kNoExpectation;
1126 ExpectFrames callee_audio_expectation_ = kNoExpectation;
1127 ExpectFrames callee_video_expectation_ = kNoExpectation;
1128 int caller_audio_frames_expected_ = 0;
1129 int caller_video_frames_expected_ = 0;
1130 int callee_audio_frames_expected_ = 0;
1131 int callee_video_frames_expected_ = 0;
1132};
1133
deadbeef1dcb1642017-03-29 21:08:16 -07001134// Tests two PeerConnections connecting to each other end-to-end, using a
1135// virtual network, fake A/V capture and fake encoder/decoders. The
1136// PeerConnections share the threads/socket servers, but use separate versions
1137// of everything else (including "PeerConnectionFactory"s).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001138class PeerConnectionIntegrationBaseTest : public testing::Test {
deadbeef1dcb1642017-03-29 21:08:16 -07001139 public:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001140 explicit PeerConnectionIntegrationBaseTest(SdpSemantics sdp_semantics)
1141 : sdp_semantics_(sdp_semantics),
1142 ss_(new rtc::VirtualSocketServer()),
Steve Antonede9ca52017-10-16 13:04:27 -07001143 fss_(new rtc::FirewallSocketServer(ss_.get())),
1144 network_thread_(new rtc::Thread(fss_.get())),
deadbeef1dcb1642017-03-29 21:08:16 -07001145 worker_thread_(rtc::Thread::Create()) {
Sebastian Jansson8a793a02018-03-13 15:21:48 +01001146 network_thread_->SetName("PCNetworkThread", this);
1147 worker_thread_->SetName("PCWorkerThread", this);
deadbeef1dcb1642017-03-29 21:08:16 -07001148 RTC_CHECK(network_thread_->Start());
1149 RTC_CHECK(worker_thread_->Start());
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001150 webrtc::metrics::Reset();
deadbeef1dcb1642017-03-29 21:08:16 -07001151 }
1152
Seth Hampson2f0d7022018-02-20 11:54:42 -08001153 ~PeerConnectionIntegrationBaseTest() {
Seth Hampsonaed71642018-06-11 07:41:32 -07001154 // The PeerConnections should deleted before the TurnCustomizers.
1155 // A TurnPort is created with a raw pointer to a TurnCustomizer. The
1156 // TurnPort has the same lifetime as the PeerConnection, so it's expected
1157 // that the TurnCustomizer outlives the life of the PeerConnection or else
1158 // when Send() is called it will hit a seg fault.
deadbeef1dcb1642017-03-29 21:08:16 -07001159 if (caller_) {
1160 caller_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001161 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001162 }
1163 if (callee_) {
1164 callee_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001165 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001166 }
Seth Hampsonaed71642018-06-11 07:41:32 -07001167
1168 // If turn servers were created for the test they need to be destroyed on
1169 // the network thread.
1170 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
1171 turn_servers_.clear();
1172 turn_customizers_.clear();
1173 });
deadbeef1dcb1642017-03-29 21:08:16 -07001174 }
1175
1176 bool SignalingStateStable() {
1177 return caller_->SignalingStateStable() && callee_->SignalingStateStable();
1178 }
1179
deadbeef71452802017-05-07 17:21:01 -07001180 bool DtlsConnected() {
1181 // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS
1182 // are connected. This is an important distinction. Once we have separate
1183 // ICE and DTLS state, this check needs to use the DTLS state.
1184 return (callee()->ice_connection_state() ==
1185 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1186 callee()->ice_connection_state() ==
1187 webrtc::PeerConnectionInterface::kIceConnectionCompleted) &&
1188 (caller()->ice_connection_state() ==
1189 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1190 caller()->ice_connection_state() ==
1191 webrtc::PeerConnectionInterface::kIceConnectionCompleted);
1192 }
1193
Qingsi Wang7685e862018-06-11 20:15:46 -07001194 // When |event_log_factory| is null, the default implementation of the event
1195 // log factory will be used.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001196 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWrapper(
1197 const std::string& debug_name,
Seth Hampson2f0d7022018-02-20 11:54:42 -08001198 const PeerConnectionFactory::Options* options,
1199 const RTCConfiguration* config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001200 webrtc::PeerConnectionDependencies dependencies,
1201 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001202 RTCConfiguration modified_config;
1203 if (config) {
1204 modified_config = *config;
1205 }
Steve Anton3acffc32018-04-12 17:21:03 -07001206 modified_config.sdp_semantics = sdp_semantics_;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001207 if (!dependencies.cert_generator) {
1208 dependencies.cert_generator =
Karl Wiberg918f50c2018-07-05 11:40:33 +02001209 absl::make_unique<FakeRTCCertificateGenerator>();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001210 }
1211 std::unique_ptr<PeerConnectionWrapper> client(
1212 new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001213
Niels Möllerf06f9232018-08-07 12:32:18 +02001214 if (!client->Init(options, &modified_config, std::move(dependencies),
1215 network_thread_.get(), worker_thread_.get(),
1216 std::move(event_log_factory))) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001217 return nullptr;
1218 }
1219 return client;
1220 }
1221
Qingsi Wang7685e862018-06-11 20:15:46 -07001222 std::unique_ptr<PeerConnectionWrapper>
1223 CreatePeerConnectionWrapperWithFakeRtcEventLog(
1224 const std::string& debug_name,
Qingsi Wang7685e862018-06-11 20:15:46 -07001225 const PeerConnectionFactory::Options* options,
1226 const RTCConfiguration* config,
1227 webrtc::PeerConnectionDependencies dependencies) {
1228 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory(
1229 new webrtc::FakeRtcEventLogFactory(rtc::Thread::Current()));
Niels Möllerf06f9232018-08-07 12:32:18 +02001230 return CreatePeerConnectionWrapper(debug_name, options, config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001231 std::move(dependencies),
1232 std::move(event_log_factory));
1233 }
1234
deadbeef1dcb1642017-03-29 21:08:16 -07001235 bool CreatePeerConnectionWrappers() {
1236 return CreatePeerConnectionWrappersWithConfig(
1237 PeerConnectionInterface::RTCConfiguration(),
1238 PeerConnectionInterface::RTCConfiguration());
1239 }
1240
Steve Anton3acffc32018-04-12 17:21:03 -07001241 bool CreatePeerConnectionWrappersWithSdpSemantics(
1242 SdpSemantics caller_semantics,
1243 SdpSemantics callee_semantics) {
1244 // Can't specify the sdp_semantics in the passed-in configuration since it
1245 // will be overwritten by CreatePeerConnectionWrapper with whatever is
1246 // stored in sdp_semantics_. So get around this by modifying the instance
1247 // variable before calling CreatePeerConnectionWrapper for the caller and
1248 // callee PeerConnections.
1249 SdpSemantics original_semantics = sdp_semantics_;
1250 sdp_semantics_ = caller_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001251 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001252 "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
1253 nullptr);
Steve Anton3acffc32018-04-12 17:21:03 -07001254 sdp_semantics_ = callee_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001255 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001256 "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
1257 nullptr);
Steve Anton3acffc32018-04-12 17:21:03 -07001258 sdp_semantics_ = original_semantics;
1259 return caller_ && callee_;
1260 }
1261
deadbeef1dcb1642017-03-29 21:08:16 -07001262 bool CreatePeerConnectionWrappersWithConfig(
1263 const PeerConnectionInterface::RTCConfiguration& caller_config,
1264 const PeerConnectionInterface::RTCConfiguration& callee_config) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001265 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001266 "Caller", nullptr, &caller_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001267 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001268 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001269 "Callee", nullptr, &callee_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001270 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001271 return caller_ && callee_;
1272 }
1273
1274 bool CreatePeerConnectionWrappersWithConfigAndDeps(
1275 const PeerConnectionInterface::RTCConfiguration& caller_config,
1276 webrtc::PeerConnectionDependencies caller_dependencies,
1277 const PeerConnectionInterface::RTCConfiguration& callee_config,
1278 webrtc::PeerConnectionDependencies callee_dependencies) {
1279 caller_ =
Niels Möllerf06f9232018-08-07 12:32:18 +02001280 CreatePeerConnectionWrapper("Caller", nullptr, &caller_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001281 std::move(caller_dependencies), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001282 callee_ =
Niels Möllerf06f9232018-08-07 12:32:18 +02001283 CreatePeerConnectionWrapper("Callee", nullptr, &callee_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001284 std::move(callee_dependencies), nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001285 return caller_ && callee_;
1286 }
1287
1288 bool CreatePeerConnectionWrappersWithOptions(
1289 const PeerConnectionFactory::Options& caller_options,
1290 const PeerConnectionFactory::Options& callee_options) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001291 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001292 "Caller", &caller_options, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001293 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001294 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001295 "Callee", &callee_options, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001296 webrtc::PeerConnectionDependencies(nullptr), nullptr);
1297 return caller_ && callee_;
1298 }
1299
1300 bool CreatePeerConnectionWrappersWithFakeRtcEventLog() {
1301 PeerConnectionInterface::RTCConfiguration default_config;
1302 caller_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001303 "Caller", nullptr, &default_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001304 webrtc::PeerConnectionDependencies(nullptr));
1305 callee_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001306 "Callee", nullptr, &default_config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001307 webrtc::PeerConnectionDependencies(nullptr));
deadbeef1dcb1642017-03-29 21:08:16 -07001308 return caller_ && callee_;
1309 }
1310
Seth Hampson2f0d7022018-02-20 11:54:42 -08001311 std::unique_ptr<PeerConnectionWrapper>
1312 CreatePeerConnectionWrapperWithAlternateKey() {
deadbeef1dcb1642017-03-29 21:08:16 -07001313 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
1314 new FakeRTCCertificateGenerator());
1315 cert_generator->use_alternate_key();
1316
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001317 webrtc::PeerConnectionDependencies dependencies(nullptr);
1318 dependencies.cert_generator = std::move(cert_generator);
Niels Möllerf06f9232018-08-07 12:32:18 +02001319 return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001320 std::move(dependencies), nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001321 }
1322
Seth Hampsonaed71642018-06-11 07:41:32 -07001323 cricket::TestTurnServer* CreateTurnServer(
1324 rtc::SocketAddress internal_address,
1325 rtc::SocketAddress external_address,
1326 cricket::ProtocolType type = cricket::ProtocolType::PROTO_UDP,
1327 const std::string& common_name = "test turn server") {
1328 rtc::Thread* thread = network_thread();
1329 std::unique_ptr<cricket::TestTurnServer> turn_server =
1330 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnServer>>(
1331 RTC_FROM_HERE,
1332 [thread, internal_address, external_address, type, common_name] {
Karl Wiberg918f50c2018-07-05 11:40:33 +02001333 return absl::make_unique<cricket::TestTurnServer>(
Seth Hampsonaed71642018-06-11 07:41:32 -07001334 thread, internal_address, external_address, type,
1335 /*ignore_bad_certs=*/true, common_name);
1336 });
1337 turn_servers_.push_back(std::move(turn_server));
1338 // Interactions with the turn server should be done on the network thread.
1339 return turn_servers_.back().get();
1340 }
1341
1342 cricket::TestTurnCustomizer* CreateTurnCustomizer() {
1343 std::unique_ptr<cricket::TestTurnCustomizer> turn_customizer =
1344 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnCustomizer>>(
1345 RTC_FROM_HERE,
Karl Wiberg918f50c2018-07-05 11:40:33 +02001346 [] { return absl::make_unique<cricket::TestTurnCustomizer>(); });
Seth Hampsonaed71642018-06-11 07:41:32 -07001347 turn_customizers_.push_back(std::move(turn_customizer));
1348 // Interactions with the turn customizer should be done on the network
1349 // thread.
1350 return turn_customizers_.back().get();
1351 }
1352
1353 // Checks that the function counters for a TestTurnCustomizer are greater than
1354 // 0.
1355 void ExpectTurnCustomizerCountersIncremented(
1356 cricket::TestTurnCustomizer* turn_customizer) {
1357 unsigned int allow_channel_data_counter =
1358 network_thread()->Invoke<unsigned int>(
1359 RTC_FROM_HERE, [turn_customizer] {
1360 return turn_customizer->allow_channel_data_cnt_;
1361 });
1362 EXPECT_GT(allow_channel_data_counter, 0u);
1363 unsigned int modify_counter = network_thread()->Invoke<unsigned int>(
1364 RTC_FROM_HERE,
1365 [turn_customizer] { return turn_customizer->modify_cnt_; });
1366 EXPECT_GT(modify_counter, 0u);
1367 }
1368
deadbeef1dcb1642017-03-29 21:08:16 -07001369 // Once called, SDP blobs and ICE candidates will be automatically signaled
1370 // between PeerConnections.
1371 void ConnectFakeSignaling() {
1372 caller_->set_signaling_message_receiver(callee_.get());
1373 callee_->set_signaling_message_receiver(caller_.get());
1374 }
1375
Steve Antonede9ca52017-10-16 13:04:27 -07001376 // Once called, SDP blobs will be automatically signaled between
1377 // PeerConnections. Note that ICE candidates will not be signaled unless they
1378 // are in the exchanged SDP blobs.
1379 void ConnectFakeSignalingForSdpOnly() {
1380 ConnectFakeSignaling();
1381 SetSignalIceCandidates(false);
1382 }
1383
deadbeef1dcb1642017-03-29 21:08:16 -07001384 void SetSignalingDelayMs(int delay_ms) {
1385 caller_->set_signaling_delay_ms(delay_ms);
1386 callee_->set_signaling_delay_ms(delay_ms);
1387 }
1388
Steve Antonede9ca52017-10-16 13:04:27 -07001389 void SetSignalIceCandidates(bool signal) {
1390 caller_->set_signal_ice_candidates(signal);
1391 callee_->set_signal_ice_candidates(signal);
1392 }
1393
deadbeef1dcb1642017-03-29 21:08:16 -07001394 // Messages may get lost on the unreliable DataChannel, so we send multiple
1395 // times to avoid test flakiness.
1396 void SendRtpDataWithRetries(webrtc::DataChannelInterface* dc,
1397 const std::string& data,
1398 int retries) {
1399 for (int i = 0; i < retries; ++i) {
1400 dc->Send(DataBuffer(data));
1401 }
1402 }
1403
1404 rtc::Thread* network_thread() { return network_thread_.get(); }
1405
1406 rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); }
1407
1408 PeerConnectionWrapper* caller() { return caller_.get(); }
1409
1410 // Set the |caller_| to the |wrapper| passed in and return the
1411 // original |caller_|.
1412 PeerConnectionWrapper* SetCallerPcWrapperAndReturnCurrent(
1413 PeerConnectionWrapper* wrapper) {
1414 PeerConnectionWrapper* old = caller_.release();
1415 caller_.reset(wrapper);
1416 return old;
1417 }
1418
1419 PeerConnectionWrapper* callee() { return callee_.get(); }
1420
1421 // Set the |callee_| to the |wrapper| passed in and return the
1422 // original |callee_|.
1423 PeerConnectionWrapper* SetCalleePcWrapperAndReturnCurrent(
1424 PeerConnectionWrapper* wrapper) {
1425 PeerConnectionWrapper* old = callee_.release();
1426 callee_.reset(wrapper);
1427 return old;
1428 }
1429
Steve Antonede9ca52017-10-16 13:04:27 -07001430 rtc::FirewallSocketServer* firewall() const { return fss_.get(); }
1431
Seth Hampson2f0d7022018-02-20 11:54:42 -08001432 // Expects the provided number of new frames to be received within
1433 // kMaxWaitForFramesMs. The new expected frames are specified in
1434 // |media_expectations|. Returns false if any of the expectations were
1435 // not met.
1436 bool ExpectNewFrames(const MediaExpectations& media_expectations) {
1437 // First initialize the expected frame counts based upon the current
1438 // frame count.
1439 int total_caller_audio_frames_expected = caller()->audio_frames_received();
1440 if (media_expectations.caller_audio_expectation_ ==
1441 MediaExpectations::kExpectSomeFrames) {
1442 total_caller_audio_frames_expected +=
1443 media_expectations.caller_audio_frames_expected_;
1444 }
1445 int total_caller_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001446 caller()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001447 if (media_expectations.caller_video_expectation_ ==
1448 MediaExpectations::kExpectSomeFrames) {
1449 total_caller_video_frames_expected +=
1450 media_expectations.caller_video_frames_expected_;
1451 }
1452 int total_callee_audio_frames_expected = callee()->audio_frames_received();
1453 if (media_expectations.callee_audio_expectation_ ==
1454 MediaExpectations::kExpectSomeFrames) {
1455 total_callee_audio_frames_expected +=
1456 media_expectations.callee_audio_frames_expected_;
1457 }
1458 int total_callee_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001459 callee()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001460 if (media_expectations.callee_video_expectation_ ==
1461 MediaExpectations::kExpectSomeFrames) {
1462 total_callee_video_frames_expected +=
1463 media_expectations.callee_video_frames_expected_;
1464 }
deadbeef1dcb1642017-03-29 21:08:16 -07001465
Seth Hampson2f0d7022018-02-20 11:54:42 -08001466 // Wait for the expected frames.
deadbeef1dcb1642017-03-29 21:08:16 -07001467 EXPECT_TRUE_WAIT(caller()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001468 total_caller_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001469 caller()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001470 total_caller_video_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001471 callee()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001472 total_callee_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001473 callee()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001474 total_callee_video_frames_expected,
1475 kMaxWaitForFramesMs);
1476 bool expectations_correct =
1477 caller()->audio_frames_received() >=
1478 total_caller_audio_frames_expected &&
1479 caller()->min_video_frames_received_per_track() >=
1480 total_caller_video_frames_expected &&
1481 callee()->audio_frames_received() >=
1482 total_callee_audio_frames_expected &&
1483 callee()->min_video_frames_received_per_track() >=
1484 total_callee_video_frames_expected;
deadbeef1dcb1642017-03-29 21:08:16 -07001485
Seth Hampson2f0d7022018-02-20 11:54:42 -08001486 // After the combined wait, print out a more detailed message upon
1487 // failure.
deadbeef1dcb1642017-03-29 21:08:16 -07001488 EXPECT_GE(caller()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001489 total_caller_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001490 EXPECT_GE(caller()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001491 total_caller_video_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001492 EXPECT_GE(callee()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001493 total_callee_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001494 EXPECT_GE(callee()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001495 total_callee_video_frames_expected);
1496
1497 // We want to make sure nothing unexpected was received.
1498 if (media_expectations.caller_audio_expectation_ ==
1499 MediaExpectations::kExpectNoFrames) {
1500 EXPECT_EQ(caller()->audio_frames_received(),
1501 total_caller_audio_frames_expected);
1502 if (caller()->audio_frames_received() !=
1503 total_caller_audio_frames_expected) {
1504 expectations_correct = false;
1505 }
1506 }
1507 if (media_expectations.caller_video_expectation_ ==
1508 MediaExpectations::kExpectNoFrames) {
1509 EXPECT_EQ(caller()->min_video_frames_received_per_track(),
1510 total_caller_video_frames_expected);
1511 if (caller()->min_video_frames_received_per_track() !=
1512 total_caller_video_frames_expected) {
1513 expectations_correct = false;
1514 }
1515 }
1516 if (media_expectations.callee_audio_expectation_ ==
1517 MediaExpectations::kExpectNoFrames) {
1518 EXPECT_EQ(callee()->audio_frames_received(),
1519 total_callee_audio_frames_expected);
1520 if (callee()->audio_frames_received() !=
1521 total_callee_audio_frames_expected) {
1522 expectations_correct = false;
1523 }
1524 }
1525 if (media_expectations.callee_video_expectation_ ==
1526 MediaExpectations::kExpectNoFrames) {
1527 EXPECT_EQ(callee()->min_video_frames_received_per_track(),
1528 total_callee_video_frames_expected);
1529 if (callee()->min_video_frames_received_per_track() !=
1530 total_callee_video_frames_expected) {
1531 expectations_correct = false;
1532 }
1533 }
1534 return expectations_correct;
deadbeef1dcb1642017-03-29 21:08:16 -07001535 }
1536
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001537 void TestNegotiatedCipherSuite(
1538 const PeerConnectionFactory::Options& caller_options,
1539 const PeerConnectionFactory::Options& callee_options,
1540 int expected_cipher_suite) {
deadbeef1dcb1642017-03-29 21:08:16 -07001541 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options,
1542 callee_options));
deadbeef1dcb1642017-03-29 21:08:16 -07001543 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001544 caller()->AddAudioVideoTracks();
1545 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001546 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001547 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001548 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite),
deadbeefd8ad7882017-04-18 16:01:17 -07001549 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001550 // TODO(bugs.webrtc.org/9456): Fix it.
1551 EXPECT_EQ(1, webrtc::metrics::NumEvents(
1552 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1553 expected_cipher_suite));
deadbeef1dcb1642017-03-29 21:08:16 -07001554 }
1555
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001556 void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
1557 bool remote_gcm_enabled,
1558 int expected_cipher_suite) {
1559 PeerConnectionFactory::Options caller_options;
1560 caller_options.crypto_options.enable_gcm_crypto_suites = local_gcm_enabled;
1561 PeerConnectionFactory::Options callee_options;
1562 callee_options.crypto_options.enable_gcm_crypto_suites = remote_gcm_enabled;
1563 TestNegotiatedCipherSuite(caller_options, callee_options,
1564 expected_cipher_suite);
1565 }
1566
Seth Hampson2f0d7022018-02-20 11:54:42 -08001567 protected:
Steve Anton3acffc32018-04-12 17:21:03 -07001568 SdpSemantics sdp_semantics_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001569
deadbeef1dcb1642017-03-29 21:08:16 -07001570 private:
1571 // |ss_| is used by |network_thread_| so it must be destroyed later.
deadbeef1dcb1642017-03-29 21:08:16 -07001572 std::unique_ptr<rtc::VirtualSocketServer> ss_;
Steve Antonede9ca52017-10-16 13:04:27 -07001573 std::unique_ptr<rtc::FirewallSocketServer> fss_;
deadbeef1dcb1642017-03-29 21:08:16 -07001574 // |network_thread_| and |worker_thread_| are used by both
1575 // |caller_| and |callee_| so they must be destroyed
1576 // later.
1577 std::unique_ptr<rtc::Thread> network_thread_;
1578 std::unique_ptr<rtc::Thread> worker_thread_;
Seth Hampsonaed71642018-06-11 07:41:32 -07001579 // The turn servers and turn customizers should be accessed & deleted on the
1580 // network thread to avoid a race with the socket read/write that occurs
1581 // on the network thread.
1582 std::vector<std::unique_ptr<cricket::TestTurnServer>> turn_servers_;
1583 std::vector<std::unique_ptr<cricket::TestTurnCustomizer>> turn_customizers_;
deadbeef1dcb1642017-03-29 21:08:16 -07001584 std::unique_ptr<PeerConnectionWrapper> caller_;
1585 std::unique_ptr<PeerConnectionWrapper> callee_;
1586};
1587
Seth Hampson2f0d7022018-02-20 11:54:42 -08001588class PeerConnectionIntegrationTest
1589 : public PeerConnectionIntegrationBaseTest,
1590 public ::testing::WithParamInterface<SdpSemantics> {
1591 protected:
1592 PeerConnectionIntegrationTest()
1593 : PeerConnectionIntegrationBaseTest(GetParam()) {}
1594};
1595
1596class PeerConnectionIntegrationTestPlanB
1597 : public PeerConnectionIntegrationBaseTest {
1598 protected:
1599 PeerConnectionIntegrationTestPlanB()
1600 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
1601};
1602
1603class PeerConnectionIntegrationTestUnifiedPlan
1604 : public PeerConnectionIntegrationBaseTest {
1605 protected:
1606 PeerConnectionIntegrationTestUnifiedPlan()
1607 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
1608};
1609
deadbeef1dcb1642017-03-29 21:08:16 -07001610// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
1611// includes testing that the callback is invoked if an observer is connected
1612// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001613TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001614 RtpReceiverObserverOnFirstPacketReceived) {
1615 ASSERT_TRUE(CreatePeerConnectionWrappers());
1616 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001617 caller()->AddAudioVideoTracks();
1618 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001619 // Start offer/answer exchange and wait for it to complete.
1620 caller()->CreateAndSetAndSignalOffer();
1621 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1622 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001623 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1624 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001625 // Wait for all "first packet received" callbacks to be fired.
1626 EXPECT_TRUE_WAIT(
1627 std::all_of(caller()->rtp_receiver_observers().begin(),
1628 caller()->rtp_receiver_observers().end(),
1629 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1630 return o->first_packet_received();
1631 }),
1632 kMaxWaitForFramesMs);
1633 EXPECT_TRUE_WAIT(
1634 std::all_of(callee()->rtp_receiver_observers().begin(),
1635 callee()->rtp_receiver_observers().end(),
1636 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1637 return o->first_packet_received();
1638 }),
1639 kMaxWaitForFramesMs);
1640 // If new observers are set after the first packet was already received, the
1641 // callback should still be invoked.
1642 caller()->ResetRtpReceiverObservers();
1643 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001644 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1645 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001646 EXPECT_TRUE(
1647 std::all_of(caller()->rtp_receiver_observers().begin(),
1648 caller()->rtp_receiver_observers().end(),
1649 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1650 return o->first_packet_received();
1651 }));
1652 EXPECT_TRUE(
1653 std::all_of(callee()->rtp_receiver_observers().begin(),
1654 callee()->rtp_receiver_observers().end(),
1655 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1656 return o->first_packet_received();
1657 }));
1658}
1659
1660class DummyDtmfObserver : public DtmfSenderObserverInterface {
1661 public:
1662 DummyDtmfObserver() : completed_(false) {}
1663
1664 // Implements DtmfSenderObserverInterface.
1665 void OnToneChange(const std::string& tone) override {
1666 tones_.push_back(tone);
1667 if (tone.empty()) {
1668 completed_ = true;
1669 }
1670 }
1671
1672 const std::vector<std::string>& tones() const { return tones_; }
1673 bool completed() const { return completed_; }
1674
1675 private:
1676 bool completed_;
1677 std::vector<std::string> tones_;
1678};
1679
1680// Assumes |sender| already has an audio track added and the offer/answer
1681// exchange is done.
1682void TestDtmfFromSenderToReceiver(PeerConnectionWrapper* sender,
1683 PeerConnectionWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -08001684 // We should be able to get a DTMF sender from the local sender.
1685 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
1686 sender->pc()->GetSenders().at(0)->GetDtmfSender();
1687 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -07001688 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -07001689 dtmf_sender->RegisterObserver(&observer);
1690
1691 // Test the DtmfSender object just created.
1692 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
1693 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
1694
1695 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
1696 std::vector<std::string> tones = {"1", "a", ""};
1697 EXPECT_EQ(tones, observer.tones());
1698 dtmf_sender->UnregisterObserver();
1699 // TODO(deadbeef): Verify the tones were actually received end-to-end.
1700}
1701
1702// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
1703// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001704TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -07001705 ASSERT_TRUE(CreatePeerConnectionWrappers());
1706 ConnectFakeSignaling();
1707 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -08001708 caller()->AddAudioTrack();
1709 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001710 caller()->CreateAndSetAndSignalOffer();
1711 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -07001712 // DTLS must finish before the DTMF sender can be used reliably.
1713 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001714 TestDtmfFromSenderToReceiver(caller(), callee());
1715 TestDtmfFromSenderToReceiver(callee(), caller());
1716}
1717
1718// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
1719// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001720TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -07001721 ASSERT_TRUE(CreatePeerConnectionWrappers());
1722 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +01001723
deadbeef1dcb1642017-03-29 21:08:16 -07001724 // Do normal offer/answer and wait for some frames to be received in each
1725 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001726 caller()->AddAudioVideoTracks();
1727 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001728 caller()->CreateAndSetAndSignalOffer();
1729 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001730 MediaExpectations media_expectations;
1731 media_expectations.ExpectBidirectionalAudioAndVideo();
1732 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001733 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1734 webrtc::kEnumCounterKeyProtocolDtls));
1735 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1736 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -07001737}
1738
1739// Uses SDES instead of DTLS for key agreement.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001740TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
deadbeef1dcb1642017-03-29 21:08:16 -07001741 PeerConnectionInterface::RTCConfiguration sdes_config;
1742 sdes_config.enable_dtls_srtp.emplace(false);
1743 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
1744 ConnectFakeSignaling();
1745
1746 // Do normal offer/answer and wait for some frames to be received in each
1747 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001748 caller()->AddAudioVideoTracks();
1749 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001750 caller()->CreateAndSetAndSignalOffer();
1751 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001752 MediaExpectations media_expectations;
1753 media_expectations.ExpectBidirectionalAudioAndVideo();
1754 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001755 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1756 webrtc::kEnumCounterKeyProtocolSdes));
1757 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1758 webrtc::kEnumCounterKeyProtocolDtls));
deadbeef1dcb1642017-03-29 21:08:16 -07001759}
1760
Steve Anton8c0f7a72017-10-03 10:03:10 -07001761// Tests that the GetRemoteAudioSSLCertificate method returns the remote DTLS
1762// certificate once the DTLS handshake has finished.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001763TEST_P(PeerConnectionIntegrationTest,
Steve Anton8c0f7a72017-10-03 10:03:10 -07001764 GetRemoteAudioSSLCertificateReturnsExchangedCertificate) {
1765 auto GetRemoteAudioSSLCertificate = [](PeerConnectionWrapper* wrapper) {
1766 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1767 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1768 return pc->GetRemoteAudioSSLCertificate();
1769 };
Zhi Huang70b820f2018-01-27 14:16:15 -08001770 auto GetRemoteAudioSSLCertChain = [](PeerConnectionWrapper* wrapper) {
1771 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1772 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1773 return pc->GetRemoteAudioSSLCertChain();
1774 };
Steve Anton8c0f7a72017-10-03 10:03:10 -07001775
1776 auto caller_cert = rtc::RTCCertificate::FromPEM(kRsaPems[0]);
1777 auto callee_cert = rtc::RTCCertificate::FromPEM(kRsaPems[1]);
1778
1779 // Configure each side with a known certificate so they can be compared later.
1780 PeerConnectionInterface::RTCConfiguration caller_config;
1781 caller_config.enable_dtls_srtp.emplace(true);
1782 caller_config.certificates.push_back(caller_cert);
1783 PeerConnectionInterface::RTCConfiguration callee_config;
1784 callee_config.enable_dtls_srtp.emplace(true);
1785 callee_config.certificates.push_back(callee_cert);
1786 ASSERT_TRUE(
1787 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
1788 ConnectFakeSignaling();
1789
1790 // When first initialized, there should not be a remote SSL certificate (and
1791 // calling this method should not crash).
1792 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(caller()));
1793 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(callee()));
Zhi Huang70b820f2018-01-27 14:16:15 -08001794 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(caller()));
1795 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(callee()));
Steve Anton8c0f7a72017-10-03 10:03:10 -07001796
Steve Anton15324772018-01-16 10:26:49 -08001797 caller()->AddAudioTrack();
1798 callee()->AddAudioTrack();
Steve Anton8c0f7a72017-10-03 10:03:10 -07001799 caller()->CreateAndSetAndSignalOffer();
1800 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1801 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
1802
1803 // Once DTLS has been connected, each side should return the other's SSL
1804 // certificate when calling GetRemoteAudioSSLCertificate.
1805
1806 auto caller_remote_cert = GetRemoteAudioSSLCertificate(caller());
1807 ASSERT_TRUE(caller_remote_cert);
1808 EXPECT_EQ(callee_cert->ssl_certificate().ToPEMString(),
1809 caller_remote_cert->ToPEMString());
1810
1811 auto callee_remote_cert = GetRemoteAudioSSLCertificate(callee());
1812 ASSERT_TRUE(callee_remote_cert);
1813 EXPECT_EQ(caller_cert->ssl_certificate().ToPEMString(),
1814 callee_remote_cert->ToPEMString());
Zhi Huang70b820f2018-01-27 14:16:15 -08001815
1816 auto caller_remote_cert_chain = GetRemoteAudioSSLCertChain(caller());
1817 ASSERT_TRUE(caller_remote_cert_chain);
1818 ASSERT_EQ(1U, caller_remote_cert_chain->GetSize());
1819 auto remote_cert = &caller_remote_cert_chain->Get(0);
1820 EXPECT_EQ(callee_cert->ssl_certificate().ToPEMString(),
1821 remote_cert->ToPEMString());
1822
1823 auto callee_remote_cert_chain = GetRemoteAudioSSLCertChain(callee());
1824 ASSERT_TRUE(callee_remote_cert_chain);
1825 ASSERT_EQ(1U, callee_remote_cert_chain->GetSize());
1826 remote_cert = &callee_remote_cert_chain->Get(0);
1827 EXPECT_EQ(caller_cert->ssl_certificate().ToPEMString(),
1828 remote_cert->ToPEMString());
Steve Anton8c0f7a72017-10-03 10:03:10 -07001829}
1830
deadbeef1dcb1642017-03-29 21:08:16 -07001831// This test sets up a call between two parties with a source resolution of
1832// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001833TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001834 Send1280By720ResolutionAndReceive16To9AspectRatio) {
1835 ASSERT_TRUE(CreatePeerConnectionWrappers());
1836 ConnectFakeSignaling();
1837
Niels Möller5c7efe72018-05-11 10:34:46 +02001838 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
1839 webrtc::FakePeriodicVideoSource::Config config;
1840 config.width = 1280;
1841 config.height = 720;
Johannes Kron965e7942018-09-13 15:36:20 +02001842 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +02001843 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
1844 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -07001845
1846 // Do normal offer/answer and wait for at least one frame to be received in
1847 // each direction.
1848 caller()->CreateAndSetAndSignalOffer();
1849 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
1850 callee()->min_video_frames_received_per_track() > 0,
1851 kMaxWaitForFramesMs);
1852
1853 // Check rendered aspect ratio.
1854 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
1855 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
1856 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
1857 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
1858}
1859
1860// This test sets up an one-way call, with media only from caller to
1861// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001862TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -07001863 ASSERT_TRUE(CreatePeerConnectionWrappers());
1864 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001865 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001866 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001867 MediaExpectations media_expectations;
1868 media_expectations.CalleeExpectsSomeAudioAndVideo();
1869 media_expectations.CallerExpectsNoAudio();
1870 media_expectations.CallerExpectsNoVideo();
1871 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001872}
1873
1874// This test sets up a audio call initially, with the callee rejecting video
1875// initially. Then later the callee decides to upgrade to audio/video, and
1876// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001877TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -07001878 ASSERT_TRUE(CreatePeerConnectionWrappers());
1879 ConnectFakeSignaling();
1880 // Initially, offer an audio/video stream from the caller, but refuse to
1881 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -08001882 caller()->AddAudioVideoTracks();
1883 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001884 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1885 PeerConnectionInterface::RTCOfferAnswerOptions options;
1886 options.offer_to_receive_video = 0;
1887 callee()->SetOfferAnswerOptions(options);
1888 } else {
1889 callee()->SetRemoteOfferHandler([this] {
1890 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
1891 });
1892 }
deadbeef1dcb1642017-03-29 21:08:16 -07001893 // Do offer/answer and make sure audio is still received end-to-end.
1894 caller()->CreateAndSetAndSignalOffer();
1895 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001896 {
1897 MediaExpectations media_expectations;
1898 media_expectations.ExpectBidirectionalAudio();
1899 media_expectations.ExpectNoVideo();
1900 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1901 }
deadbeef1dcb1642017-03-29 21:08:16 -07001902 // Sanity check that the callee's description has a rejected video section.
1903 ASSERT_NE(nullptr, callee()->pc()->local_description());
1904 const ContentInfo* callee_video_content =
1905 GetFirstVideoContent(callee()->pc()->local_description()->description());
1906 ASSERT_NE(nullptr, callee_video_content);
1907 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001908
deadbeef1dcb1642017-03-29 21:08:16 -07001909 // Now negotiate with video and ensure negotiation succeeds, with video
1910 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -08001911 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001912 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1913 PeerConnectionInterface::RTCOfferAnswerOptions options;
1914 options.offer_to_receive_video = 1;
1915 callee()->SetOfferAnswerOptions(options);
1916 } else {
1917 callee()->SetRemoteOfferHandler(nullptr);
1918 caller()->SetRemoteOfferHandler([this] {
1919 // The caller creates a new transceiver to receive video on when receiving
1920 // the offer, but by default it is send only.
1921 auto transceivers = caller()->pc()->GetTransceivers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001922 ASSERT_EQ(3U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08001923 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
1924 transceivers[2]->receiver()->media_type());
1925 transceivers[2]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
1926 transceivers[2]->SetDirection(RtpTransceiverDirection::kSendRecv);
1927 });
1928 }
deadbeef1dcb1642017-03-29 21:08:16 -07001929 callee()->CreateAndSetAndSignalOffer();
1930 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001931 {
1932 // Expect additional audio frames to be received after the upgrade.
1933 MediaExpectations media_expectations;
1934 media_expectations.ExpectBidirectionalAudioAndVideo();
1935 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1936 }
deadbeef1dcb1642017-03-29 21:08:16 -07001937}
1938
deadbeef4389b4d2017-09-07 09:07:36 -07001939// Simpler than the above test; just add an audio track to an established
1940// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001941TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -07001942 ASSERT_TRUE(CreatePeerConnectionWrappers());
1943 ConnectFakeSignaling();
1944 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -08001945 caller()->AddVideoTrack();
1946 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07001947 caller()->CreateAndSetAndSignalOffer();
1948 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1949 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001950 caller()->AddAudioTrack();
1951 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07001952 caller()->CreateAndSetAndSignalOffer();
1953 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1954 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001955 MediaExpectations media_expectations;
1956 media_expectations.ExpectBidirectionalAudioAndVideo();
1957 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -07001958}
1959
deadbeef1dcb1642017-03-29 21:08:16 -07001960// This test sets up a call that's transferred to a new caller with a different
1961// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001962TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -07001963 ASSERT_TRUE(CreatePeerConnectionWrappers());
1964 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001965 caller()->AddAudioVideoTracks();
1966 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001967 caller()->CreateAndSetAndSignalOffer();
1968 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1969
1970 // Keep the original peer around which will still send packets to the
1971 // receiving client. These SRTP packets will be dropped.
1972 std::unique_ptr<PeerConnectionWrapper> original_peer(
1973 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08001974 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07001975 // TODO(deadbeef): Why do we call Close here? That goes against the comment
1976 // directly above.
1977 original_peer->pc()->Close();
1978
1979 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001980 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001981 caller()->CreateAndSetAndSignalOffer();
1982 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1983 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001984 MediaExpectations media_expectations;
1985 media_expectations.ExpectBidirectionalAudioAndVideo();
1986 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001987}
1988
1989// This test sets up a call that's transferred to a new callee with a different
1990// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001991TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -07001992 ASSERT_TRUE(CreatePeerConnectionWrappers());
1993 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001994 caller()->AddAudioVideoTracks();
1995 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001996 caller()->CreateAndSetAndSignalOffer();
1997 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1998
1999 // Keep the original peer around which will still send packets to the
2000 // receiving client. These SRTP packets will be dropped.
2001 std::unique_ptr<PeerConnectionWrapper> original_peer(
2002 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002003 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07002004 // TODO(deadbeef): Why do we call Close here? That goes against the comment
2005 // directly above.
2006 original_peer->pc()->Close();
2007
2008 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002009 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002010 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2011 caller()->CreateAndSetAndSignalOffer();
2012 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2013 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002014 MediaExpectations media_expectations;
2015 media_expectations.ExpectBidirectionalAudioAndVideo();
2016 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002017}
2018
2019// This test sets up a non-bundled call and negotiates bundling at the same
2020// time as starting an ICE restart. When bundling is in effect in the restart,
2021// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002022TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -07002023 ASSERT_TRUE(CreatePeerConnectionWrappers());
2024 ConnectFakeSignaling();
2025
Steve Anton15324772018-01-16 10:26:49 -08002026 caller()->AddAudioVideoTracks();
2027 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002028 // Remove the bundle group from the SDP received by the callee.
2029 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2030 desc->RemoveGroupByName("BUNDLE");
2031 });
2032 caller()->CreateAndSetAndSignalOffer();
2033 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002034 {
2035 MediaExpectations media_expectations;
2036 media_expectations.ExpectBidirectionalAudioAndVideo();
2037 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2038 }
deadbeef1dcb1642017-03-29 21:08:16 -07002039 // Now stop removing the BUNDLE group, and trigger an ICE restart.
2040 callee()->SetReceivedSdpMunger(nullptr);
2041 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2042 caller()->CreateAndSetAndSignalOffer();
2043 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2044
2045 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002046 {
2047 MediaExpectations media_expectations;
2048 media_expectations.ExpectBidirectionalAudioAndVideo();
2049 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2050 }
deadbeef1dcb1642017-03-29 21:08:16 -07002051}
2052
2053// Test CVO (Coordination of Video Orientation). If a video source is rotated
2054// and both peers support the CVO RTP header extension, the actual video frames
2055// don't need to be encoded in different resolutions, since the rotation is
2056// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002057TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002058 ASSERT_TRUE(CreatePeerConnectionWrappers());
2059 ConnectFakeSignaling();
2060 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002061 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002062 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002063 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002064 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2065
2066 // Wait for video frames to be received by both sides.
2067 caller()->CreateAndSetAndSignalOffer();
2068 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2069 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2070 callee()->min_video_frames_received_per_track() > 0,
2071 kMaxWaitForFramesMs);
2072
2073 // Ensure that the aspect ratio is unmodified.
2074 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2075 // not just assumed.
2076 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
2077 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
2078 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
2079 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
2080 // Ensure that the CVO bits were surfaced to the renderer.
2081 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
2082 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
2083}
2084
2085// Test that when the CVO extension isn't supported, video is rotated the
2086// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002087TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002088 ASSERT_TRUE(CreatePeerConnectionWrappers());
2089 ConnectFakeSignaling();
2090 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002091 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002092 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002093 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002094 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2095
2096 // Remove the CVO extension from the offered SDP.
2097 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2098 cricket::VideoContentDescription* video =
2099 GetFirstVideoContentDescription(desc);
2100 video->ClearRtpHeaderExtensions();
2101 });
2102 // Wait for video frames to be received by both sides.
2103 caller()->CreateAndSetAndSignalOffer();
2104 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2105 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2106 callee()->min_video_frames_received_per_track() > 0,
2107 kMaxWaitForFramesMs);
2108
2109 // Expect that the aspect ratio is inversed to account for the 90/270 degree
2110 // rotation.
2111 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2112 // not just assumed.
2113 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
2114 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
2115 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
2116 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
2117 // Expect that each endpoint is unaware of the rotation of the other endpoint.
2118 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
2119 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
2120}
2121
deadbeef1dcb1642017-03-29 21:08:16 -07002122// Test that if the answerer rejects the audio m= section, no audio is sent or
2123// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002124TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002125 ASSERT_TRUE(CreatePeerConnectionWrappers());
2126 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002127 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002128 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2129 // Only add video track for callee, and set offer_to_receive_audio to 0, so
2130 // it will reject the audio m= section completely.
2131 PeerConnectionInterface::RTCOfferAnswerOptions options;
2132 options.offer_to_receive_audio = 0;
2133 callee()->SetOfferAnswerOptions(options);
2134 } else {
2135 // Stopping the audio RtpTransceiver will cause the media section to be
2136 // rejected in the answer.
2137 callee()->SetRemoteOfferHandler([this] {
2138 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)->Stop();
2139 });
2140 }
Steve Anton15324772018-01-16 10:26:49 -08002141 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002142 // Do offer/answer and wait for successful end-to-end video frames.
2143 caller()->CreateAndSetAndSignalOffer();
2144 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002145 MediaExpectations media_expectations;
2146 media_expectations.ExpectBidirectionalVideo();
2147 media_expectations.ExpectNoAudio();
2148 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2149
deadbeef1dcb1642017-03-29 21:08:16 -07002150 // Sanity check that the callee's description has a rejected audio section.
2151 ASSERT_NE(nullptr, callee()->pc()->local_description());
2152 const ContentInfo* callee_audio_content =
2153 GetFirstAudioContent(callee()->pc()->local_description()->description());
2154 ASSERT_NE(nullptr, callee_audio_content);
2155 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002156 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2157 // The caller's transceiver should have stopped after receiving the answer.
2158 EXPECT_TRUE(caller()
2159 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
2160 ->stopped());
2161 }
deadbeef1dcb1642017-03-29 21:08:16 -07002162}
2163
2164// Test that if the answerer rejects the video m= section, no video is sent or
2165// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002166TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002167 ASSERT_TRUE(CreatePeerConnectionWrappers());
2168 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002169 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002170 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2171 // Only add audio track for callee, and set offer_to_receive_video to 0, so
2172 // it will reject the video m= section completely.
2173 PeerConnectionInterface::RTCOfferAnswerOptions options;
2174 options.offer_to_receive_video = 0;
2175 callee()->SetOfferAnswerOptions(options);
2176 } else {
2177 // Stopping the video RtpTransceiver will cause the media section to be
2178 // rejected in the answer.
2179 callee()->SetRemoteOfferHandler([this] {
2180 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2181 });
2182 }
Steve Anton15324772018-01-16 10:26:49 -08002183 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002184 // Do offer/answer and wait for successful end-to-end audio frames.
2185 caller()->CreateAndSetAndSignalOffer();
2186 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002187 MediaExpectations media_expectations;
2188 media_expectations.ExpectBidirectionalAudio();
2189 media_expectations.ExpectNoVideo();
2190 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2191
deadbeef1dcb1642017-03-29 21:08:16 -07002192 // Sanity check that the callee's description has a rejected video section.
2193 ASSERT_NE(nullptr, callee()->pc()->local_description());
2194 const ContentInfo* callee_video_content =
2195 GetFirstVideoContent(callee()->pc()->local_description()->description());
2196 ASSERT_NE(nullptr, callee_video_content);
2197 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002198 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2199 // The caller's transceiver should have stopped after receiving the answer.
2200 EXPECT_TRUE(caller()
2201 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2202 ->stopped());
2203 }
deadbeef1dcb1642017-03-29 21:08:16 -07002204}
2205
2206// Test that if the answerer rejects both audio and video m= sections, nothing
2207// bad happens.
2208// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
2209// test anything but the fact that negotiation succeeds, which doesn't mean
2210// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002211TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -07002212 ASSERT_TRUE(CreatePeerConnectionWrappers());
2213 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002214 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002215 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2216 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
2217 // will reject both audio and video m= sections.
2218 PeerConnectionInterface::RTCOfferAnswerOptions options;
2219 options.offer_to_receive_audio = 0;
2220 options.offer_to_receive_video = 0;
2221 callee()->SetOfferAnswerOptions(options);
2222 } else {
2223 callee()->SetRemoteOfferHandler([this] {
2224 // Stopping all transceivers will cause all media sections to be rejected.
2225 for (auto transceiver : callee()->pc()->GetTransceivers()) {
2226 transceiver->Stop();
2227 }
2228 });
2229 }
deadbeef1dcb1642017-03-29 21:08:16 -07002230 // Do offer/answer and wait for stable signaling state.
2231 caller()->CreateAndSetAndSignalOffer();
2232 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002233
deadbeef1dcb1642017-03-29 21:08:16 -07002234 // Sanity check that the callee's description has rejected m= sections.
2235 ASSERT_NE(nullptr, callee()->pc()->local_description());
2236 const ContentInfo* callee_audio_content =
2237 GetFirstAudioContent(callee()->pc()->local_description()->description());
2238 ASSERT_NE(nullptr, callee_audio_content);
2239 EXPECT_TRUE(callee_audio_content->rejected);
2240 const ContentInfo* callee_video_content =
2241 GetFirstVideoContent(callee()->pc()->local_description()->description());
2242 ASSERT_NE(nullptr, callee_video_content);
2243 EXPECT_TRUE(callee_video_content->rejected);
2244}
2245
2246// This test sets up an audio and video call between two parties. After the
2247// call runs for a while, the caller sends an updated offer with video being
2248// rejected. Once the re-negotiation is done, the video flow should stop and
2249// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002250TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07002251 ASSERT_TRUE(CreatePeerConnectionWrappers());
2252 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002253 caller()->AddAudioVideoTracks();
2254 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002255 caller()->CreateAndSetAndSignalOffer();
2256 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002257 {
2258 MediaExpectations media_expectations;
2259 media_expectations.ExpectBidirectionalAudioAndVideo();
2260 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2261 }
deadbeef1dcb1642017-03-29 21:08:16 -07002262 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002263 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2264 caller()->SetGeneratedSdpMunger(
2265 [](cricket::SessionDescription* description) {
2266 for (cricket::ContentInfo& content : description->contents()) {
2267 if (cricket::IsVideoContent(&content)) {
2268 content.rejected = true;
2269 }
2270 }
2271 });
2272 } else {
2273 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2274 }
deadbeef1dcb1642017-03-29 21:08:16 -07002275 caller()->CreateAndSetAndSignalOffer();
2276 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2277
2278 // Sanity check that the caller's description has a rejected video section.
2279 ASSERT_NE(nullptr, caller()->pc()->local_description());
2280 const ContentInfo* caller_video_content =
2281 GetFirstVideoContent(caller()->pc()->local_description()->description());
2282 ASSERT_NE(nullptr, caller_video_content);
2283 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -07002284 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002285 {
2286 MediaExpectations media_expectations;
2287 media_expectations.ExpectBidirectionalAudio();
2288 media_expectations.ExpectNoVideo();
2289 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2290 }
deadbeef1dcb1642017-03-29 21:08:16 -07002291}
2292
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -07002293// Do one offer/answer with audio, another that disables it (rejecting the m=
2294// section), and another that re-enables it. Regression test for:
2295// bugs.webrtc.org/6023
2296TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
2297 ASSERT_TRUE(CreatePeerConnectionWrappers());
2298 ConnectFakeSignaling();
2299
2300 // Add audio track, do normal offer/answer.
2301 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2302 caller()->CreateLocalAudioTrack();
2303 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2304 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2305 caller()->CreateAndSetAndSignalOffer();
2306 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2307
2308 // Remove audio track, and set offer_to_receive_audio to false to cause the
2309 // m= section to be completely disabled, not just "recvonly".
2310 caller()->pc()->RemoveTrack(sender);
2311 PeerConnectionInterface::RTCOfferAnswerOptions options;
2312 options.offer_to_receive_audio = 0;
2313 caller()->SetOfferAnswerOptions(options);
2314 caller()->CreateAndSetAndSignalOffer();
2315 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2316
2317 // Add the audio track again, expecting negotiation to succeed and frames to
2318 // flow.
2319 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2320 options.offer_to_receive_audio = 1;
2321 caller()->SetOfferAnswerOptions(options);
2322 caller()->CreateAndSetAndSignalOffer();
2323 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2324
2325 MediaExpectations media_expectations;
2326 media_expectations.CalleeExpectsSomeAudio();
2327 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2328}
2329
deadbeef1dcb1642017-03-29 21:08:16 -07002330// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
2331// is needed to support legacy endpoints.
2332// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
2333// add a test for an end-to-end test without MID signaling either (basically,
2334// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002335TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -07002336 ASSERT_TRUE(CreatePeerConnectionWrappers());
2337 ConnectFakeSignaling();
2338 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08002339 caller()->AddAudioVideoTracks();
2340 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07002341 // Remove SSRCs and MSIDs from the received offer SDP.
2342 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07002343 caller()->CreateAndSetAndSignalOffer();
2344 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002345 MediaExpectations media_expectations;
2346 media_expectations.ExpectBidirectionalAudioAndVideo();
2347 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002348}
2349
Seth Hampson5897a6e2018-04-03 11:16:33 -07002350// Basic end-to-end test, without SSRC signaling. This means that the track
2351// was created properly and frames are delivered when the MSIDs are communicated
2352// with a=msid lines and no a=ssrc lines.
2353TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2354 EndToEndCallWithoutSsrcSignaling) {
2355 const char kStreamId[] = "streamId";
2356 ASSERT_TRUE(CreatePeerConnectionWrappers());
2357 ConnectFakeSignaling();
2358 // Add just audio tracks.
2359 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
2360 callee()->AddAudioTrack();
2361
2362 // Remove SSRCs from the received offer SDP.
2363 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
2364 caller()->CreateAndSetAndSignalOffer();
2365 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2366 MediaExpectations media_expectations;
2367 media_expectations.ExpectBidirectionalAudio();
2368 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2369}
2370
Steve Antondf527fd2018-04-27 15:52:03 -07002371// Tests that video flows between multiple video tracks when SSRCs are not
2372// signaled. This exercises the MID RTP header extension which is needed to
2373// demux the incoming video tracks.
2374TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2375 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
2376 ASSERT_TRUE(CreatePeerConnectionWrappers());
2377 ConnectFakeSignaling();
2378 caller()->AddVideoTrack();
2379 caller()->AddVideoTrack();
2380 callee()->AddVideoTrack();
2381 callee()->AddVideoTrack();
2382
2383 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2384 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2385 caller()->CreateAndSetAndSignalOffer();
2386 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2387 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2388 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2389
2390 // Expect video to be received in both directions on both tracks.
2391 MediaExpectations media_expectations;
2392 media_expectations.ExpectBidirectionalVideo();
2393 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2394}
2395
deadbeef1dcb1642017-03-29 21:08:16 -07002396// Test that if two video tracks are sent (from caller to callee, in this test),
2397// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002398TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07002399 ASSERT_TRUE(CreatePeerConnectionWrappers());
2400 ConnectFakeSignaling();
2401 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08002402 caller()->AddAudioVideoTracks();
2403 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002404 caller()->CreateAndSetAndSignalOffer();
2405 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08002406 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002407
2408 MediaExpectations media_expectations;
2409 media_expectations.CalleeExpectsSomeAudioAndVideo();
2410 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002411}
2412
2413static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
2414 bool first = true;
2415 for (cricket::ContentInfo& content : desc->contents()) {
2416 if (first) {
2417 first = false;
2418 continue;
2419 }
2420 content.bundle_only = true;
2421 }
2422 first = true;
2423 for (cricket::TransportInfo& transport : desc->transport_infos()) {
2424 if (first) {
2425 first = false;
2426 continue;
2427 }
2428 transport.description.ice_ufrag.clear();
2429 transport.description.ice_pwd.clear();
2430 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
2431 transport.description.identity_fingerprint.reset(nullptr);
2432 }
2433}
2434
2435// Test that if applying a true "max bundle" offer, which uses ports of 0,
2436// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
2437// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
2438// successfully and media flows.
2439// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
2440// TODO(deadbeef): Won't need this test once we start generating actual
2441// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002442TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002443 EndToEndCallWithSpecCompliantMaxBundleOffer) {
2444 ASSERT_TRUE(CreatePeerConnectionWrappers());
2445 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002446 caller()->AddAudioVideoTracks();
2447 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002448 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
2449 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
2450 // but the first m= section.
2451 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
2452 caller()->CreateAndSetAndSignalOffer();
2453 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002454 MediaExpectations media_expectations;
2455 media_expectations.ExpectBidirectionalAudioAndVideo();
2456 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002457}
2458
2459// Test that we can receive the audio output level from a remote audio track.
2460// TODO(deadbeef): Use a fake audio source and verify that the output level is
2461// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002462TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002463 ASSERT_TRUE(CreatePeerConnectionWrappers());
2464 ConnectFakeSignaling();
2465 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002466 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002467 caller()->CreateAndSetAndSignalOffer();
2468 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2469
2470 // Get the audio output level stats. Note that the level is not available
2471 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07002472 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002473 kMaxWaitForFramesMs);
2474}
2475
2476// Test that an audio input level is reported.
2477// TODO(deadbeef): Use a fake audio source and verify that the input level is
2478// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002479TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002480 ASSERT_TRUE(CreatePeerConnectionWrappers());
2481 ConnectFakeSignaling();
2482 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002483 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002484 caller()->CreateAndSetAndSignalOffer();
2485 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2486
2487 // Get the audio input level stats. The level should be available very
2488 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07002489 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002490 kMaxWaitForStatsMs);
2491}
2492
2493// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002494TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002495 ASSERT_TRUE(CreatePeerConnectionWrappers());
2496 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002497 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002498 // Do offer/answer, wait for the callee to receive some frames.
2499 caller()->CreateAndSetAndSignalOffer();
2500 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002501
2502 MediaExpectations media_expectations;
2503 media_expectations.CalleeExpectsSomeAudioAndVideo();
2504 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002505
2506 // Get a handle to the remote tracks created, so they can be used as GetStats
2507 // filters.
Steve Anton15324772018-01-16 10:26:49 -08002508 for (auto receiver : callee()->pc()->GetReceivers()) {
2509 // We received frames, so we definitely should have nonzero "received bytes"
2510 // stats at this point.
2511 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
2512 0);
2513 }
deadbeef1dcb1642017-03-29 21:08:16 -07002514}
2515
2516// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002517TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002518 ASSERT_TRUE(CreatePeerConnectionWrappers());
2519 ConnectFakeSignaling();
2520 auto audio_track = caller()->CreateLocalAudioTrack();
2521 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08002522 caller()->AddTrack(audio_track);
2523 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07002524 // Do offer/answer, wait for the callee to receive some frames.
2525 caller()->CreateAndSetAndSignalOffer();
2526 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002527 MediaExpectations media_expectations;
2528 media_expectations.CalleeExpectsSomeAudioAndVideo();
2529 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002530
2531 // The callee received frames, so we definitely should have nonzero "sent
2532 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07002533 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
2534 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
2535}
2536
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002537// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002538TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002539 ASSERT_TRUE(CreatePeerConnectionWrappers());
2540 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002541 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002542
Steve Anton15324772018-01-16 10:26:49 -08002543 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002544
2545 // Do offer/answer, wait for the callee to receive some frames.
2546 caller()->CreateAndSetAndSignalOffer();
2547 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2548
2549 // Get the remote audio track created on the receiver, so they can be used as
2550 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08002551 auto receivers = callee()->pc()->GetReceivers();
2552 ASSERT_EQ(1u, receivers.size());
2553 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002554
2555 // Get the audio output level stats. Note that the level is not available
2556 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07002557 EXPECT_TRUE_WAIT(
2558 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
2559 0,
2560 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002561}
2562
deadbeefd8ad7882017-04-18 16:01:17 -07002563// Test that we can get stats (using the new stats implemnetation) for
2564// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
2565// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002566TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07002567 GetStatsForUnsignaledStreamWithNewStatsApi) {
2568 ASSERT_TRUE(CreatePeerConnectionWrappers());
2569 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002570 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07002571 // Remove SSRCs and MSIDs from the received offer SDP.
2572 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2573 caller()->CreateAndSetAndSignalOffer();
2574 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002575 MediaExpectations media_expectations;
2576 media_expectations.CalleeExpectsSomeAudio(1);
2577 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07002578
2579 // We received a frame, so we should have nonzero "bytes received" stats for
2580 // the unsignaled stream, if stats are working for it.
2581 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2582 callee()->NewGetStats();
2583 ASSERT_NE(nullptr, report);
2584 auto inbound_stream_stats =
2585 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2586 ASSERT_EQ(1U, inbound_stream_stats.size());
2587 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
2588 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07002589 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
2590}
2591
Taylor Brandstettera4653442018-06-19 09:44:26 -07002592// Same as above but for the legacy stats implementation.
2593TEST_P(PeerConnectionIntegrationTest,
2594 GetStatsForUnsignaledStreamWithOldStatsApi) {
2595 ASSERT_TRUE(CreatePeerConnectionWrappers());
2596 ConnectFakeSignaling();
2597 caller()->AddAudioTrack();
2598 // Remove SSRCs and MSIDs from the received offer SDP.
2599 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2600 caller()->CreateAndSetAndSignalOffer();
2601 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2602
2603 // Note that, since the old stats implementation associates SSRCs with tracks
2604 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
2605 // associated track ID. So we can't use the track "selector" argument.
2606 //
2607 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
2608 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002609 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07002610 kDefaultTimeout);
2611}
2612
zhihuangf8164932017-05-19 13:09:47 -07002613// Test that we can successfully get the media related stats (audio level
2614// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002615TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07002616 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
2617 ASSERT_TRUE(CreatePeerConnectionWrappers());
2618 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002619 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07002620 // Remove SSRCs and MSIDs from the received offer SDP.
2621 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2622 caller()->CreateAndSetAndSignalOffer();
2623 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002624 MediaExpectations media_expectations;
2625 media_expectations.CalleeExpectsSomeAudio(1);
2626 media_expectations.CalleeExpectsSomeVideo(1);
2627 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07002628
2629 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2630 callee()->NewGetStats();
2631 ASSERT_NE(nullptr, report);
2632
2633 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2634 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
2635 ASSERT_GE(audio_index, 0);
2636 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07002637}
2638
deadbeef4e2deab2017-09-20 13:56:21 -07002639// Helper for test below.
2640void ModifySsrcs(cricket::SessionDescription* desc) {
2641 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07002642 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08002643 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07002644 for (uint32_t& ssrc : stream.ssrcs) {
2645 ssrc = rtc::CreateRandomId();
2646 }
2647 }
2648 }
2649}
2650
2651// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
2652// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
2653// This should result in two "RTCInboundRTPStreamStats", but only one
2654// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
2655// being reset to 0 once the SSRC change occurs.
2656//
2657// Regression test for this bug:
2658// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
2659//
2660// The bug causes the track stats to only represent one of the two streams:
2661// whichever one has the higher SSRC. So with this bug, there was a 50% chance
2662// that the track stat counters would reset to 0 when the new stream is
2663// received, and a 50% chance that they'll stop updating (while
2664// "concealed_samples" continues increasing, due to silence being generated for
2665// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002666TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08002667 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07002668 ASSERT_TRUE(CreatePeerConnectionWrappers());
2669 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002670 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07002671 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
2672 // that doesn't signal SSRCs (from the callee's perspective).
2673 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2674 caller()->CreateAndSetAndSignalOffer();
2675 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2676 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002677 {
2678 MediaExpectations media_expectations;
2679 media_expectations.CalleeExpectsSomeAudio(50);
2680 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2681 }
deadbeef4e2deab2017-09-20 13:56:21 -07002682 // Some audio frames were received, so we should have nonzero "samples
2683 // received" for the track.
2684 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2685 callee()->NewGetStats();
2686 ASSERT_NE(nullptr, report);
2687 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2688 ASSERT_EQ(1U, track_stats.size());
2689 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2690 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
2691 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
2692
2693 // Create a new offer and munge it to cause the caller to use a new SSRC.
2694 caller()->SetGeneratedSdpMunger(ModifySsrcs);
2695 caller()->CreateAndSetAndSignalOffer();
2696 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2697 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
2698 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002699 {
2700 MediaExpectations media_expectations;
2701 media_expectations.CalleeExpectsSomeAudio(25);
2702 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2703 }
deadbeef4e2deab2017-09-20 13:56:21 -07002704
2705 report = callee()->NewGetStats();
2706 ASSERT_NE(nullptr, report);
2707 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2708 ASSERT_EQ(1U, track_stats.size());
2709 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2710 // The "total samples received" stat should only be greater than it was
2711 // before.
2712 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
2713 // Right now, the new SSRC will cause the counters to reset to 0.
2714 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
2715
2716 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08002717 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07002718 // good sign that we're seeing stats from the old stream that's no longer
2719 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08002720 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07002721 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
2722 EXPECT_LT(*track_stats[0]->concealed_samples,
2723 *track_stats[0]->total_samples_received *
2724 kAcceptableConcealedSamplesPercentage);
2725
2726 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
2727 // sanity check that the SSRC really changed.
2728 // TODO(deadbeef): This isn't working right now, because we're not returning
2729 // *any* stats for the inactive stream. Uncomment when the bug is completely
2730 // fixed.
2731 // auto inbound_stream_stats =
2732 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2733 // ASSERT_EQ(2U, inbound_stream_stats.size());
2734}
2735
deadbeef1dcb1642017-03-29 21:08:16 -07002736// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002737TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002738 PeerConnectionFactory::Options dtls_10_options;
2739 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2740 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2741 dtls_10_options));
2742 ConnectFakeSignaling();
2743 // Do normal offer/answer and wait for some frames to be received in each
2744 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002745 caller()->AddAudioVideoTracks();
2746 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002747 caller()->CreateAndSetAndSignalOffer();
2748 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002749 MediaExpectations media_expectations;
2750 media_expectations.ExpectBidirectionalAudioAndVideo();
2751 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002752}
2753
2754// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002755TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002756 PeerConnectionFactory::Options dtls_10_options;
2757 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2758 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2759 dtls_10_options));
2760 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002761 caller()->AddAudioVideoTracks();
2762 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002763 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002764 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002765 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002766 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002767 kDefaultTimeout);
2768 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002769 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002770 // TODO(bugs.webrtc.org/9456): Fix it.
2771 EXPECT_EQ(1, webrtc::metrics::NumEvents(
2772 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2773 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07002774}
2775
2776// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002777TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002778 PeerConnectionFactory::Options dtls_12_options;
2779 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2780 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
2781 dtls_12_options));
2782 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002783 caller()->AddAudioVideoTracks();
2784 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002785 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002786 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002787 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002788 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002789 kDefaultTimeout);
2790 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002791 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002792 // TODO(bugs.webrtc.org/9456): Fix it.
2793 EXPECT_EQ(1, webrtc::metrics::NumEvents(
2794 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2795 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07002796}
2797
2798// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
2799// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002800TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002801 PeerConnectionFactory::Options caller_options;
2802 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2803 PeerConnectionFactory::Options callee_options;
2804 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2805 ASSERT_TRUE(
2806 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2807 ConnectFakeSignaling();
2808 // Do normal offer/answer and wait for some frames to be received in each
2809 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002810 caller()->AddAudioVideoTracks();
2811 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002812 caller()->CreateAndSetAndSignalOffer();
2813 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002814 MediaExpectations media_expectations;
2815 media_expectations.ExpectBidirectionalAudioAndVideo();
2816 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002817}
2818
2819// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
2820// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002821TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07002822 PeerConnectionFactory::Options caller_options;
2823 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2824 PeerConnectionFactory::Options callee_options;
2825 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2826 ASSERT_TRUE(
2827 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2828 ConnectFakeSignaling();
2829 // Do normal offer/answer and wait for some frames to be received in each
2830 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002831 caller()->AddAudioVideoTracks();
2832 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002833 caller()->CreateAndSetAndSignalOffer();
2834 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002835 MediaExpectations media_expectations;
2836 media_expectations.ExpectBidirectionalAudioAndVideo();
2837 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002838}
2839
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07002840// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
2841// works as expected; the cipher should only be used if enabled by both sides.
2842TEST_P(PeerConnectionIntegrationTest,
2843 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
2844 PeerConnectionFactory::Options caller_options;
2845 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2846 PeerConnectionFactory::Options callee_options;
2847 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
2848 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2849 TestNegotiatedCipherSuite(caller_options, callee_options,
2850 expected_cipher_suite);
2851}
2852
2853TEST_P(PeerConnectionIntegrationTest,
2854 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
2855 PeerConnectionFactory::Options caller_options;
2856 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
2857 PeerConnectionFactory::Options callee_options;
2858 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2859 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2860 TestNegotiatedCipherSuite(caller_options, callee_options,
2861 expected_cipher_suite);
2862}
2863
2864TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
2865 PeerConnectionFactory::Options caller_options;
2866 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2867 PeerConnectionFactory::Options callee_options;
2868 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2869 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
2870 TestNegotiatedCipherSuite(caller_options, callee_options,
2871 expected_cipher_suite);
2872}
2873
deadbeef1dcb1642017-03-29 21:08:16 -07002874// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002875TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07002876 bool local_gcm_enabled = false;
2877 bool remote_gcm_enabled = false;
2878 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2879 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2880 expected_cipher_suite);
2881}
2882
2883// Test that a GCM cipher is used if both ends support it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002884TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07002885 bool local_gcm_enabled = true;
2886 bool remote_gcm_enabled = true;
2887 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
2888 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2889 expected_cipher_suite);
2890}
2891
2892// Test that GCM isn't used if only the offerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002893TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002894 NonGcmCipherUsedWhenOnlyCallerSupportsGcm) {
2895 bool local_gcm_enabled = true;
2896 bool remote_gcm_enabled = false;
2897 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2898 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2899 expected_cipher_suite);
2900}
2901
2902// Test that GCM isn't used if only the answerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002903TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002904 NonGcmCipherUsedWhenOnlyCalleeSupportsGcm) {
2905 bool local_gcm_enabled = false;
2906 bool remote_gcm_enabled = true;
2907 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2908 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2909 expected_cipher_suite);
2910}
2911
deadbeef7914b8c2017-04-21 03:23:33 -07002912// Verify that media can be transmitted end-to-end when GCM crypto suites are
2913// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
2914// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
2915// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002916TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07002917 PeerConnectionFactory::Options gcm_options;
2918 gcm_options.crypto_options.enable_gcm_crypto_suites = true;
2919 ASSERT_TRUE(
2920 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
2921 ConnectFakeSignaling();
2922 // Do normal offer/answer and wait for some frames to be received in each
2923 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002924 caller()->AddAudioVideoTracks();
2925 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07002926 caller()->CreateAndSetAndSignalOffer();
2927 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002928 MediaExpectations media_expectations;
2929 media_expectations.ExpectBidirectionalAudioAndVideo();
2930 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07002931}
2932
deadbeef1dcb1642017-03-29 21:08:16 -07002933// This test sets up a call between two parties with audio, video and an RTP
2934// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002935TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002936 PeerConnectionInterface::RTCConfiguration rtc_config;
2937 rtc_config.enable_rtp_data_channel = true;
2938 rtc_config.enable_dtls_srtp = false;
2939 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07002940 ConnectFakeSignaling();
2941 // Expect that data channel created on caller side will show up for callee as
2942 // well.
2943 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08002944 caller()->AddAudioVideoTracks();
2945 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002946 caller()->CreateAndSetAndSignalOffer();
2947 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2948 // Ensure the existence of the RTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002949 MediaExpectations media_expectations;
2950 media_expectations.ExpectBidirectionalAudioAndVideo();
2951 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002952 ASSERT_NE(nullptr, caller()->data_channel());
2953 ASSERT_NE(nullptr, callee()->data_channel());
2954 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2955 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2956
2957 // Ensure data can be sent in both directions.
2958 std::string data = "hello world";
2959 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
2960 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
2961 kDefaultTimeout);
2962 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
2963 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
2964 kDefaultTimeout);
2965}
2966
2967// Ensure that an RTP data channel is signaled as closed for the caller when
2968// the callee rejects it in a subsequent offer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002969TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002970 RtpDataChannelSignaledClosedInCalleeOffer) {
2971 // Same procedure as above test.
Niels Möllerf06f9232018-08-07 12:32:18 +02002972 PeerConnectionInterface::RTCConfiguration rtc_config;
2973 rtc_config.enable_rtp_data_channel = true;
2974 rtc_config.enable_dtls_srtp = false;
2975 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07002976 ConnectFakeSignaling();
2977 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08002978 caller()->AddAudioVideoTracks();
2979 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002980 caller()->CreateAndSetAndSignalOffer();
2981 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2982 ASSERT_NE(nullptr, caller()->data_channel());
2983 ASSERT_NE(nullptr, callee()->data_channel());
2984 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2985 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2986
2987 // Close the data channel on the callee, and do an updated offer/answer.
2988 callee()->data_channel()->Close();
2989 callee()->CreateAndSetAndSignalOffer();
2990 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2991 EXPECT_FALSE(caller()->data_observer()->IsOpen());
2992 EXPECT_FALSE(callee()->data_observer()->IsOpen());
2993}
2994
2995// Tests that data is buffered in an RTP data channel until an observer is
2996// registered for it.
2997//
2998// NOTE: RTP data channels can receive data before the underlying
2999// transport has detected that a channel is writable and thus data can be
3000// received before the data channel state changes to open. That is hard to test
3001// but the same buffering is expected to be used in that case.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003002TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003003 DataBufferedUntilRtpDataChannelObserverRegistered) {
3004 // Use fake clock and simulated network delay so that we predictably can wait
3005 // until an SCTP message has been delivered without "sleep()"ing.
3006 rtc::ScopedFakeClock fake_clock;
3007 // Some things use a time of "0" as a special value, so we need to start out
3008 // the fake clock at a nonzero time.
3009 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003010 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-29 21:08:16 -07003011 virtual_socket_server()->set_delay_mean(5); // 5 ms per hop.
3012 virtual_socket_server()->UpdateDelayDistribution();
3013
Niels Möllerf06f9232018-08-07 12:32:18 +02003014 PeerConnectionInterface::RTCConfiguration rtc_config;
3015 rtc_config.enable_rtp_data_channel = true;
3016 rtc_config.enable_dtls_srtp = false;
3017 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003018 ConnectFakeSignaling();
3019 caller()->CreateDataChannel();
3020 caller()->CreateAndSetAndSignalOffer();
3021 ASSERT_TRUE(caller()->data_channel() != nullptr);
3022 ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr,
3023 kDefaultTimeout, fake_clock);
3024 ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(),
3025 kDefaultTimeout, fake_clock);
3026 ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen,
3027 callee()->data_channel()->state(), kDefaultTimeout,
3028 fake_clock);
3029
3030 // Unregister the observer which is normally automatically registered.
3031 callee()->data_channel()->UnregisterObserver();
3032 // Send data and advance fake clock until it should have been received.
3033 std::string data = "hello world";
3034 caller()->data_channel()->Send(DataBuffer(data));
3035 SIMULATED_WAIT(false, 50, fake_clock);
3036
3037 // Attach data channel and expect data to be received immediately. Note that
3038 // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any
3039 // further, but data can be received even if the callback is asynchronous.
3040 MockDataChannelObserver new_observer(callee()->data_channel());
3041 EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout,
3042 fake_clock);
Seth Hampson1d4a76d2018-06-19 14:31:41 -07003043 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
3044 // If this is not done a DCHECK can be hit in ports.cc, because a large
3045 // negative number is calculated for the rtt due to the global clock changing.
3046 caller()->pc()->Close();
3047 callee()->pc()->Close();
deadbeef1dcb1642017-03-29 21:08:16 -07003048}
3049
3050// This test sets up a call between two parties with audio, video and but only
3051// the caller client supports RTP data channels.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003052TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003053 PeerConnectionInterface::RTCConfiguration rtc_config_1;
3054 rtc_config_1.enable_rtp_data_channel = true;
deadbeef1dcb1642017-03-29 21:08:16 -07003055 // Must disable DTLS to make negotiation succeed.
Niels Möllerf06f9232018-08-07 12:32:18 +02003056 rtc_config_1.enable_dtls_srtp = false;
3057 PeerConnectionInterface::RTCConfiguration rtc_config_2;
3058 rtc_config_2.enable_dtls_srtp = false;
3059 rtc_config_2.enable_dtls_srtp = false;
3060 ASSERT_TRUE(
3061 CreatePeerConnectionWrappersWithConfig(rtc_config_1, rtc_config_2));
deadbeef1dcb1642017-03-29 21:08:16 -07003062 ConnectFakeSignaling();
3063 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003064 caller()->AddAudioVideoTracks();
3065 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003066 caller()->CreateAndSetAndSignalOffer();
3067 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3068 // The caller should still have a data channel, but it should be closed, and
3069 // one should ever have been created for the callee.
3070 EXPECT_TRUE(caller()->data_channel() != nullptr);
3071 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3072 EXPECT_EQ(nullptr, callee()->data_channel());
3073}
3074
3075// This test sets up a call between two parties with audio, and video. When
3076// audio and video is setup and flowing, an RTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003077TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003078 PeerConnectionInterface::RTCConfiguration rtc_config;
3079 rtc_config.enable_rtp_data_channel = true;
3080 rtc_config.enable_dtls_srtp = false;
3081 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003082 ConnectFakeSignaling();
3083 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003084 caller()->AddAudioVideoTracks();
3085 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003086 caller()->CreateAndSetAndSignalOffer();
3087 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3088 // Create data channel and do new offer and answer.
3089 caller()->CreateDataChannel();
3090 caller()->CreateAndSetAndSignalOffer();
3091 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3092 ASSERT_NE(nullptr, caller()->data_channel());
3093 ASSERT_NE(nullptr, callee()->data_channel());
3094 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3095 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3096 // Ensure data can be sent in both directions.
3097 std::string data = "hello world";
3098 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3099 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3100 kDefaultTimeout);
3101 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3102 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3103 kDefaultTimeout);
3104}
3105
3106#ifdef HAVE_SCTP
3107
3108// This test sets up a call between two parties with audio, video and an SCTP
3109// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003110TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003111 ASSERT_TRUE(CreatePeerConnectionWrappers());
3112 ConnectFakeSignaling();
3113 // Expect that data channel created on caller side will show up for callee as
3114 // well.
3115 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003116 caller()->AddAudioVideoTracks();
3117 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003118 caller()->CreateAndSetAndSignalOffer();
3119 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3120 // Ensure the existence of the SCTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003121 MediaExpectations media_expectations;
3122 media_expectations.ExpectBidirectionalAudioAndVideo();
3123 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003124 // Caller data channel should already exist (it created one). Callee data
3125 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3126 ASSERT_NE(nullptr, caller()->data_channel());
3127 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3128 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3129 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3130
3131 // Ensure data can be sent in both directions.
3132 std::string data = "hello world";
3133 caller()->data_channel()->Send(DataBuffer(data));
3134 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3135 kDefaultTimeout);
3136 callee()->data_channel()->Send(DataBuffer(data));
3137 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3138 kDefaultTimeout);
3139}
3140
3141// Ensure that when the callee closes an SCTP data channel, the closing
3142// procedure results in the data channel being closed for the caller as well.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003143TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003144 // Same procedure as above test.
3145 ASSERT_TRUE(CreatePeerConnectionWrappers());
3146 ConnectFakeSignaling();
3147 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003148 caller()->AddAudioVideoTracks();
3149 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003150 caller()->CreateAndSetAndSignalOffer();
3151 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3152 ASSERT_NE(nullptr, caller()->data_channel());
3153 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3154 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3155 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3156
3157 // Close the data channel on the callee side, and wait for it to reach the
3158 // "closed" state on both sides.
3159 callee()->data_channel()->Close();
3160 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3161 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3162}
3163
Seth Hampson2f0d7022018-02-20 11:54:42 -08003164TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
Steve Antonda6c0952017-10-23 11:41:54 -07003165 ASSERT_TRUE(CreatePeerConnectionWrappers());
3166 ConnectFakeSignaling();
3167 webrtc::DataChannelInit init;
3168 init.id = 53;
3169 init.maxRetransmits = 52;
3170 caller()->CreateDataChannel("data-channel", &init);
Steve Anton15324772018-01-16 10:26:49 -08003171 caller()->AddAudioVideoTracks();
3172 callee()->AddAudioVideoTracks();
Steve Antonda6c0952017-10-23 11:41:54 -07003173 caller()->CreateAndSetAndSignalOffer();
3174 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton074dece2017-10-24 13:04:12 -07003175 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3176 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Steve Antonda6c0952017-10-23 11:41:54 -07003177 EXPECT_EQ(init.id, callee()->data_channel()->id());
3178 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3179 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3180 EXPECT_FALSE(callee()->data_channel()->negotiated());
3181}
3182
deadbeef1dcb1642017-03-29 21:08:16 -07003183// Test usrsctp's ability to process unordered data stream, where data actually
3184// arrives out of order using simulated delays. Previously there have been some
3185// bugs in this area.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003186TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003187 // Introduce random network delays.
3188 // Otherwise it's not a true "unordered" test.
3189 virtual_socket_server()->set_delay_mean(20);
3190 virtual_socket_server()->set_delay_stddev(5);
3191 virtual_socket_server()->UpdateDelayDistribution();
3192 // Normal procedure, but with unordered data channel config.
3193 ASSERT_TRUE(CreatePeerConnectionWrappers());
3194 ConnectFakeSignaling();
3195 webrtc::DataChannelInit init;
3196 init.ordered = false;
3197 caller()->CreateDataChannel(&init);
3198 caller()->CreateAndSetAndSignalOffer();
3199 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3200 ASSERT_NE(nullptr, caller()->data_channel());
3201 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3202 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3203 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3204
3205 static constexpr int kNumMessages = 100;
3206 // Deliberately chosen to be larger than the MTU so messages get fragmented.
3207 static constexpr size_t kMaxMessageSize = 4096;
3208 // Create and send random messages.
3209 std::vector<std::string> sent_messages;
3210 for (int i = 0; i < kNumMessages; ++i) {
3211 size_t length =
3212 (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand)
3213 std::string message;
3214 ASSERT_TRUE(rtc::CreateRandomString(length, &message));
3215 caller()->data_channel()->Send(DataBuffer(message));
3216 callee()->data_channel()->Send(DataBuffer(message));
3217 sent_messages.push_back(message);
3218 }
3219
3220 // Wait for all messages to be received.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003221 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003222 caller()->data_observer()->received_message_count(),
3223 kDefaultTimeout);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003224 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003225 callee()->data_observer()->received_message_count(),
3226 kDefaultTimeout);
3227
3228 // Sort and compare to make sure none of the messages were corrupted.
3229 std::vector<std::string> caller_received_messages =
3230 caller()->data_observer()->messages();
3231 std::vector<std::string> callee_received_messages =
3232 callee()->data_observer()->messages();
3233 std::sort(sent_messages.begin(), sent_messages.end());
3234 std::sort(caller_received_messages.begin(), caller_received_messages.end());
3235 std::sort(callee_received_messages.begin(), callee_received_messages.end());
3236 EXPECT_EQ(sent_messages, caller_received_messages);
3237 EXPECT_EQ(sent_messages, callee_received_messages);
3238}
3239
3240// This test sets up a call between two parties with audio, and video. When
3241// audio and video are setup and flowing, an SCTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003242TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07003243 ASSERT_TRUE(CreatePeerConnectionWrappers());
3244 ConnectFakeSignaling();
3245 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003246 caller()->AddAudioVideoTracks();
3247 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003248 caller()->CreateAndSetAndSignalOffer();
3249 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3250 // Create data channel and do new offer and answer.
3251 caller()->CreateDataChannel();
3252 caller()->CreateAndSetAndSignalOffer();
3253 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3254 // Caller data channel should already exist (it created one). Callee data
3255 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3256 ASSERT_NE(nullptr, caller()->data_channel());
3257 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3258 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3259 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3260 // Ensure data can be sent in both directions.
3261 std::string data = "hello world";
3262 caller()->data_channel()->Send(DataBuffer(data));
3263 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3264 kDefaultTimeout);
3265 callee()->data_channel()->Send(DataBuffer(data));
3266 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3267 kDefaultTimeout);
3268}
3269
deadbeef7914b8c2017-04-21 03:23:33 -07003270// Set up a connection initially just using SCTP data channels, later upgrading
3271// to audio/video, ensuring frames are received end-to-end. Effectively the
3272// inverse of the test above.
3273// This was broken in M57; see https://crbug.com/711243
Seth Hampson2f0d7022018-02-20 11:54:42 -08003274TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
deadbeef7914b8c2017-04-21 03:23:33 -07003275 ASSERT_TRUE(CreatePeerConnectionWrappers());
3276 ConnectFakeSignaling();
3277 // Do initial offer/answer with just data channel.
3278 caller()->CreateDataChannel();
3279 caller()->CreateAndSetAndSignalOffer();
3280 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3281 // Wait until data can be sent over the data channel.
3282 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3283 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3284 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3285
3286 // Do subsequent offer/answer with two-way audio and video. Audio and video
3287 // should end up bundled on the DTLS/ICE transport already used for data.
Steve Anton15324772018-01-16 10:26:49 -08003288 caller()->AddAudioVideoTracks();
3289 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003290 caller()->CreateAndSetAndSignalOffer();
3291 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003292 MediaExpectations media_expectations;
3293 media_expectations.ExpectBidirectionalAudioAndVideo();
3294 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003295}
3296
deadbeef8b7e9ad2017-05-25 09:38:55 -07003297static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
deadbeef8b7e9ad2017-05-25 09:38:55 -07003298 cricket::DataContentDescription* dcd_offer =
Steve Antonb1c1de12017-12-21 15:14:30 -08003299 GetFirstDataContentDescription(desc);
3300 ASSERT_TRUE(dcd_offer);
deadbeef8b7e9ad2017-05-25 09:38:55 -07003301 dcd_offer->set_use_sctpmap(false);
3302 dcd_offer->set_protocol("UDP/DTLS/SCTP");
3303}
3304
3305// Test that the data channel works when a spec-compliant SCTP m= section is
3306// offered (using "a=sctp-port" instead of "a=sctpmap", and using
3307// "UDP/DTLS/SCTP" as the protocol).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003308TEST_P(PeerConnectionIntegrationTest,
deadbeef8b7e9ad2017-05-25 09:38:55 -07003309 DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
3310 ASSERT_TRUE(CreatePeerConnectionWrappers());
3311 ConnectFakeSignaling();
3312 caller()->CreateDataChannel();
3313 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
3314 caller()->CreateAndSetAndSignalOffer();
3315 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3316 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3317 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3318 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3319
3320 // Ensure data can be sent in both directions.
3321 std::string data = "hello world";
3322 caller()->data_channel()->Send(DataBuffer(data));
3323 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3324 kDefaultTimeout);
3325 callee()->data_channel()->Send(DataBuffer(data));
3326 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3327 kDefaultTimeout);
3328}
3329
deadbeef1dcb1642017-03-29 21:08:16 -07003330#endif // HAVE_SCTP
3331
3332// Test that the ICE connection and gathering states eventually reach
3333// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08003334TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07003335 ASSERT_TRUE(CreatePeerConnectionWrappers());
3336 ConnectFakeSignaling();
3337 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08003338 caller()->AddAudioVideoTracks();
3339 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003340 caller()->CreateAndSetAndSignalOffer();
3341 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3342 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3343 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
3344 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3345 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
3346 // After the best candidate pair is selected and all candidates are signaled,
3347 // the ICE connection state should reach "complete".
3348 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
3349 // answerer/"callee" by default) only reaches "connected". When this is
3350 // fixed, this test should be updated.
3351 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3352 caller()->ice_connection_state(), kDefaultTimeout);
3353 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3354 callee()->ice_connection_state(), kDefaultTimeout);
3355}
3356
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003357// Replaces the first candidate with a static address and configures a
3358// MockAsyncResolver to return the replaced address the first time the static
3359// address is resolved. Candidates past the first will not be signaled.
3360class ReplaceFirstCandidateAddressDropOthers final
3361 : public IceCandidateReplacerInterface {
3362 public:
3363 ReplaceFirstCandidateAddressDropOthers(
3364 const SocketAddress& new_address,
3365 rtc::MockAsyncResolver* mock_async_resolver)
3366 : mock_async_resolver_(mock_async_resolver), new_address_(new_address) {
3367 RTC_DCHECK(mock_async_resolver);
3368 }
3369
3370 std::unique_ptr<webrtc::IceCandidateInterface> ReplaceCandidate(
3371 const webrtc::IceCandidateInterface* candidate) override {
3372 if (replaced_candidate_) {
3373 return nullptr;
3374 }
3375
3376 replaced_candidate_ = true;
3377 cricket::Candidate new_candidate(candidate->candidate());
3378 new_candidate.set_address(new_address_);
3379 EXPECT_CALL(*mock_async_resolver_, GetResolvedAddress(_, _))
3380 .WillOnce(DoAll(SetArgPointee<1>(candidate->candidate().address()),
3381 Return(true)));
3382 EXPECT_CALL(*mock_async_resolver_, Destroy(_));
3383 return webrtc::CreateIceCandidate(
3384 candidate->sdp_mid(), candidate->sdp_mline_index(), new_candidate);
3385 }
3386
3387 private:
3388 rtc::MockAsyncResolver* mock_async_resolver_;
3389 SocketAddress new_address_;
3390 bool replaced_candidate_ = false;
3391};
3392
3393// Drops all candidates before they are signaled.
3394class DropAllCandidates final : public IceCandidateReplacerInterface {
3395 public:
3396 std::unique_ptr<webrtc::IceCandidateInterface> ReplaceCandidate(
3397 const webrtc::IceCandidateInterface*) override {
3398 return nullptr;
3399 }
3400};
3401
3402// Replace the first caller ICE candidate IP with a fake hostname and drop the
3403// other candidates. Drop all candidates on the callee side (to avoid a prflx
3404// connection). Use a mock resolver to resolve the hostname back to the original
3405// IP on the callee side and check that the ice connection connects.
3406TEST_P(PeerConnectionIntegrationTest,
3407 IceStatesReachCompletionWithRemoteHostname) {
3408 webrtc::MockAsyncResolverFactory* callee_mock_async_resolver_factory;
3409 {
3410 auto resolver_factory =
3411 absl::make_unique<webrtc::MockAsyncResolverFactory>();
3412 callee_mock_async_resolver_factory = resolver_factory.get();
3413 webrtc::PeerConnectionDependencies callee_deps(nullptr);
3414 callee_deps.async_resolver_factory = std::move(resolver_factory);
3415
3416 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
3417 RTCConfiguration(), webrtc::PeerConnectionDependencies(nullptr),
3418 RTCConfiguration(), std::move(callee_deps)));
3419 }
3420
3421 rtc::MockAsyncResolver mock_async_resolver;
3422
3423 // This also verifies that the injected AsyncResolverFactory is used by
3424 // P2PTransportChannel.
3425 EXPECT_CALL(*callee_mock_async_resolver_factory, Create())
3426 .WillOnce(Return(&mock_async_resolver));
3427 caller()->SetLocalIceCandidateReplacer(
3428 absl::make_unique<ReplaceFirstCandidateAddressDropOthers>(
3429 SocketAddress("a.b", 10000), &mock_async_resolver));
3430 callee()->SetLocalIceCandidateReplacer(
3431 absl::make_unique<DropAllCandidates>());
3432
3433 ConnectFakeSignaling();
3434 caller()->AddAudioVideoTracks();
3435 callee()->AddAudioVideoTracks();
3436 caller()->CreateAndSetAndSignalOffer();
3437 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3438 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3439 caller()->ice_connection_state(), kDefaultTimeout);
3440 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3441 callee()->ice_connection_state(), kDefaultTimeout);
3442}
3443
Steve Antonede9ca52017-10-16 13:04:27 -07003444// Test that firewalling the ICE connection causes the clients to identify the
3445// disconnected state and then removing the firewall causes them to reconnect.
3446class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003447 : public PeerConnectionIntegrationBaseTest,
3448 public ::testing::WithParamInterface<
3449 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07003450 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003451 PeerConnectionIntegrationIceStatesTest()
3452 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
3453 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07003454 }
3455
3456 void StartStunServer(const SocketAddress& server_address) {
3457 stun_server_.reset(
3458 cricket::TestStunServer::Create(network_thread(), server_address));
3459 }
3460
3461 bool TestIPv6() {
3462 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
3463 }
3464
3465 void SetPortAllocatorFlags() {
Qingsi Wanga2d60672018-04-11 16:57:45 -07003466 network_thread()->Invoke<void>(
3467 RTC_FROM_HERE,
3468 rtc::Bind(&cricket::PortAllocator::set_flags,
3469 caller()->port_allocator(), port_allocator_flags_));
3470 network_thread()->Invoke<void>(
3471 RTC_FROM_HERE,
3472 rtc::Bind(&cricket::PortAllocator::set_flags,
3473 callee()->port_allocator(), port_allocator_flags_));
Steve Antonede9ca52017-10-16 13:04:27 -07003474 }
3475
3476 std::vector<SocketAddress> CallerAddresses() {
3477 std::vector<SocketAddress> addresses;
3478 addresses.push_back(SocketAddress("1.1.1.1", 0));
3479 if (TestIPv6()) {
3480 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
3481 }
3482 return addresses;
3483 }
3484
3485 std::vector<SocketAddress> CalleeAddresses() {
3486 std::vector<SocketAddress> addresses;
3487 addresses.push_back(SocketAddress("2.2.2.2", 0));
3488 if (TestIPv6()) {
3489 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
3490 }
3491 return addresses;
3492 }
3493
3494 void SetUpNetworkInterfaces() {
3495 // Remove the default interfaces added by the test infrastructure.
3496 caller()->network()->RemoveInterface(kDefaultLocalAddress);
3497 callee()->network()->RemoveInterface(kDefaultLocalAddress);
3498
3499 // Add network addresses for test.
3500 for (const auto& caller_address : CallerAddresses()) {
3501 caller()->network()->AddInterface(caller_address);
3502 }
3503 for (const auto& callee_address : CalleeAddresses()) {
3504 callee()->network()->AddInterface(callee_address);
3505 }
3506 }
3507
3508 private:
3509 uint32_t port_allocator_flags_;
3510 std::unique_ptr<cricket::TestStunServer> stun_server_;
3511};
3512
3513// Tests that the PeerConnection goes through all the ICE gathering/connection
3514// states over the duration of the call. This includes Disconnected and Failed
3515// states, induced by putting a firewall between the peers and waiting for them
3516// to time out.
Steve Anton83119dd2017-11-10 16:19:52 -08003517TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyIceStates) {
3518 // TODO(bugs.webrtc.org/8295): When using a ScopedFakeClock, this test will
3519 // sometimes hit a DCHECK in platform_thread.cc about the PacerThread being
3520 // too busy. For now, revert to running without a fake clock.
Steve Antonede9ca52017-10-16 13:04:27 -07003521
3522 const SocketAddress kStunServerAddress =
3523 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
3524 StartStunServer(kStunServerAddress);
3525
3526 PeerConnectionInterface::RTCConfiguration config;
3527 PeerConnectionInterface::IceServer ice_stun_server;
3528 ice_stun_server.urls.push_back(
3529 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
3530 kStunServerAddress.PortAsString());
3531 config.servers.push_back(ice_stun_server);
3532
3533 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3534 ConnectFakeSignaling();
3535 SetPortAllocatorFlags();
3536 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08003537 caller()->AddAudioVideoTracks();
3538 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003539
3540 // Initial state before anything happens.
3541 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
3542 caller()->ice_gathering_state());
3543 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
3544 caller()->ice_connection_state());
3545
3546 // Start the call by creating the offer, setting it as the local description,
3547 // then sending it to the peer who will respond with an answer. This happens
3548 // asynchronously so that we can watch the states as it runs in the
3549 // background.
3550 caller()->CreateAndSetAndSignalOffer();
3551
Steve Anton83119dd2017-11-10 16:19:52 -08003552 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3553 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003554
3555 // Verify that the observer was notified of the intermediate transitions.
3556 EXPECT_THAT(caller()->ice_connection_state_history(),
3557 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
3558 PeerConnectionInterface::kIceConnectionConnected,
3559 PeerConnectionInterface::kIceConnectionCompleted));
3560 EXPECT_THAT(caller()->ice_gathering_state_history(),
3561 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3562 PeerConnectionInterface::kIceGatheringComplete));
3563
3564 // Block connections to/from the caller and wait for ICE to become
3565 // disconnected.
3566 for (const auto& caller_address : CallerAddresses()) {
3567 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3568 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01003569 RTC_LOG(LS_INFO) << "Firewall rules applied";
Steve Anton83119dd2017-11-10 16:19:52 -08003570 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
3571 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003572
3573 // Let ICE re-establish by removing the firewall rules.
3574 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01003575 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Steve Anton83119dd2017-11-10 16:19:52 -08003576 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3577 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003578
3579 // According to RFC7675, if there is no response within 30 seconds then the
3580 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08003581 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07003582 constexpr int kConsentTimeout = 30000;
3583 for (const auto& caller_address : CallerAddresses()) {
3584 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3585 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01003586 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Steve Anton83119dd2017-11-10 16:19:52 -08003587 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionFailed,
3588 caller()->ice_connection_state(), kConsentTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003589}
3590
3591// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
3592// and that the statistics in the metric observers are updated correctly.
3593TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) {
3594 ASSERT_TRUE(CreatePeerConnectionWrappers());
3595 ConnectFakeSignaling();
3596 SetPortAllocatorFlags();
3597 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08003598 caller()->AddAudioVideoTracks();
3599 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003600 caller()->CreateAndSetAndSignalOffer();
3601
3602 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3603
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003604 // TODO(bugs.webrtc.org/9456): Fix it.
3605 const int num_best_ipv4 = webrtc::metrics::NumEvents(
3606 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
3607 const int num_best_ipv6 = webrtc::metrics::NumEvents(
3608 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07003609 if (TestIPv6()) {
3610 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
3611 // connection.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003612 EXPECT_EQ(0, num_best_ipv4);
3613 EXPECT_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07003614 } else {
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003615 EXPECT_EQ(1, num_best_ipv4);
3616 EXPECT_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07003617 }
3618
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003619 EXPECT_EQ(0, webrtc::metrics::NumEvents(
3620 "WebRTC.PeerConnection.CandidatePairType_UDP",
3621 webrtc::kIceCandidatePairHostHost));
3622 EXPECT_EQ(1, webrtc::metrics::NumEvents(
3623 "WebRTC.PeerConnection.CandidatePairType_UDP",
3624 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07003625}
3626
3627constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
3628 cricket::PORTALLOCATOR_DISABLE_STUN |
3629 cricket::PORTALLOCATOR_DISABLE_RELAY;
3630constexpr uint32_t kFlagsIPv6NoStun =
3631 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
3632 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
3633constexpr uint32_t kFlagsIPv4Stun =
3634 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
3635
Seth Hampson2f0d7022018-02-20 11:54:42 -08003636INSTANTIATE_TEST_CASE_P(
3637 PeerConnectionIntegrationTest,
3638 PeerConnectionIntegrationIceStatesTest,
3639 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3640 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
3641 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
3642 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07003643
deadbeef1dcb1642017-03-29 21:08:16 -07003644// This test sets up a call between two parties with audio and video.
3645// During the call, the caller restarts ICE and the test verifies that
3646// new ICE candidates are generated and audio and video still can flow, and the
3647// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003648TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07003649 ASSERT_TRUE(CreatePeerConnectionWrappers());
3650 ConnectFakeSignaling();
3651 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08003652 caller()->AddAudioVideoTracks();
3653 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003654 caller()->CreateAndSetAndSignalOffer();
3655 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3656 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3657 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3658 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3659 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3660
3661 // To verify that the ICE restart actually occurs, get
3662 // ufrag/password/candidates before and after restart.
3663 // Create an SDP string of the first audio candidate for both clients.
3664 const webrtc::IceCandidateCollection* audio_candidates_caller =
3665 caller()->pc()->local_description()->candidates(0);
3666 const webrtc::IceCandidateCollection* audio_candidates_callee =
3667 callee()->pc()->local_description()->candidates(0);
3668 ASSERT_GT(audio_candidates_caller->count(), 0u);
3669 ASSERT_GT(audio_candidates_callee->count(), 0u);
3670 std::string caller_candidate_pre_restart;
3671 ASSERT_TRUE(
3672 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
3673 std::string callee_candidate_pre_restart;
3674 ASSERT_TRUE(
3675 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
3676 const cricket::SessionDescription* desc =
3677 caller()->pc()->local_description()->description();
3678 std::string caller_ufrag_pre_restart =
3679 desc->transport_infos()[0].description.ice_ufrag;
3680 desc = callee()->pc()->local_description()->description();
3681 std::string callee_ufrag_pre_restart =
3682 desc->transport_infos()[0].description.ice_ufrag;
3683
3684 // Have the caller initiate an ICE restart.
3685 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
3686 caller()->CreateAndSetAndSignalOffer();
3687 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3688 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3689 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3690 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3691 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3692
3693 // Grab the ufrags/candidates again.
3694 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
3695 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
3696 ASSERT_GT(audio_candidates_caller->count(), 0u);
3697 ASSERT_GT(audio_candidates_callee->count(), 0u);
3698 std::string caller_candidate_post_restart;
3699 ASSERT_TRUE(
3700 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
3701 std::string callee_candidate_post_restart;
3702 ASSERT_TRUE(
3703 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
3704 desc = caller()->pc()->local_description()->description();
3705 std::string caller_ufrag_post_restart =
3706 desc->transport_infos()[0].description.ice_ufrag;
3707 desc = callee()->pc()->local_description()->description();
3708 std::string callee_ufrag_post_restart =
3709 desc->transport_infos()[0].description.ice_ufrag;
3710 // Sanity check that an ICE restart was actually negotiated in SDP.
3711 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
3712 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
3713 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
3714 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
3715
3716 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003717 MediaExpectations media_expectations;
3718 media_expectations.ExpectBidirectionalAudioAndVideo();
3719 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003720}
3721
3722// Verify that audio/video can be received end-to-end when ICE renomination is
3723// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003724TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07003725 PeerConnectionInterface::RTCConfiguration config;
3726 config.enable_ice_renomination = true;
3727 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3728 ConnectFakeSignaling();
3729 // Do normal offer/answer and wait for some frames to be received in each
3730 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003731 caller()->AddAudioVideoTracks();
3732 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003733 caller()->CreateAndSetAndSignalOffer();
3734 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3735 // Sanity check that ICE renomination was actually negotiated.
3736 const cricket::SessionDescription* desc =
3737 caller()->pc()->local_description()->description();
3738 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 02:41:29 -07003739 ASSERT_NE(
3740 info.description.transport_options.end(),
3741 std::find(info.description.transport_options.begin(),
3742 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07003743 }
3744 desc = callee()->pc()->local_description()->description();
3745 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 02:41:29 -07003746 ASSERT_NE(
3747 info.description.transport_options.end(),
3748 std::find(info.description.transport_options.begin(),
3749 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07003750 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08003751 MediaExpectations media_expectations;
3752 media_expectations.ExpectBidirectionalAudioAndVideo();
3753 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003754}
3755
Steve Anton6f25b092017-10-23 09:39:20 -07003756// With a max bundle policy and RTCP muxing, adding a new media description to
3757// the connection should not affect ICE at all because the new media will use
3758// the existing connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003759TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08003760 AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07003761 PeerConnectionInterface::RTCConfiguration config;
3762 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3763 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3764 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
3765 config, PeerConnectionInterface::RTCConfiguration()));
3766 ConnectFakeSignaling();
3767
Steve Anton15324772018-01-16 10:26:49 -08003768 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07003769 caller()->CreateAndSetAndSignalOffer();
3770 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07003771 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3772 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07003773
3774 caller()->clear_ice_connection_state_history();
3775
Steve Anton15324772018-01-16 10:26:49 -08003776 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07003777 caller()->CreateAndSetAndSignalOffer();
3778 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3779
3780 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
3781}
3782
deadbeef1dcb1642017-03-29 21:08:16 -07003783// This test sets up a call between two parties with audio and video. It then
3784// renegotiates setting the video m-line to "port 0", then later renegotiates
3785// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003786TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003787 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
3788 ASSERT_TRUE(CreatePeerConnectionWrappers());
3789 ConnectFakeSignaling();
3790
3791 // Do initial negotiation, only sending media from the caller. Will result in
3792 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08003793 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003794 caller()->CreateAndSetAndSignalOffer();
3795 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3796
3797 // Negotiate again, disabling the video "m=" section (the callee will set the
3798 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003799 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3800 PeerConnectionInterface::RTCOfferAnswerOptions options;
3801 options.offer_to_receive_video = 0;
3802 callee()->SetOfferAnswerOptions(options);
3803 } else {
3804 callee()->SetRemoteOfferHandler([this] {
3805 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
3806 });
3807 }
deadbeef1dcb1642017-03-29 21:08:16 -07003808 caller()->CreateAndSetAndSignalOffer();
3809 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3810 // Sanity check that video "m=" section was actually rejected.
3811 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
3812 callee()->pc()->local_description()->description());
3813 ASSERT_NE(nullptr, answer_video_content);
3814 ASSERT_TRUE(answer_video_content->rejected);
3815
3816 // Enable video and do negotiation again, making sure video is received
3817 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003818 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3819 PeerConnectionInterface::RTCOfferAnswerOptions options;
3820 options.offer_to_receive_video = 1;
3821 callee()->SetOfferAnswerOptions(options);
3822 } else {
3823 // The caller's transceiver is stopped, so we need to add another track.
3824 auto caller_transceiver =
3825 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
3826 EXPECT_TRUE(caller_transceiver->stopped());
3827 caller()->AddVideoTrack();
3828 }
3829 callee()->AddVideoTrack();
3830 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07003831 caller()->CreateAndSetAndSignalOffer();
3832 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003833
deadbeef1dcb1642017-03-29 21:08:16 -07003834 // Verify the caller receives frames from the newly added stream, and the
3835 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003836 MediaExpectations media_expectations;
3837 media_expectations.CalleeExpectsSomeAudio();
3838 media_expectations.ExpectBidirectionalVideo();
3839 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003840}
3841
deadbeef1dcb1642017-03-29 21:08:16 -07003842// This tests that if we negotiate after calling CreateSender but before we
3843// have a track, then set a track later, frames from the newly-set track are
3844// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003845TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07003846 MediaFlowsAfterEarlyWarmupWithCreateSender) {
3847 ASSERT_TRUE(CreatePeerConnectionWrappers());
3848 ConnectFakeSignaling();
3849 auto caller_audio_sender =
3850 caller()->pc()->CreateSender("audio", "caller_stream");
3851 auto caller_video_sender =
3852 caller()->pc()->CreateSender("video", "caller_stream");
3853 auto callee_audio_sender =
3854 callee()->pc()->CreateSender("audio", "callee_stream");
3855 auto callee_video_sender =
3856 callee()->pc()->CreateSender("video", "callee_stream");
3857 caller()->CreateAndSetAndSignalOffer();
3858 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3859 // Wait for ICE to complete, without any tracks being set.
3860 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3861 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3862 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3863 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3864 // Now set the tracks, and expect frames to immediately start flowing.
3865 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3866 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3867 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3868 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08003869 MediaExpectations media_expectations;
3870 media_expectations.ExpectBidirectionalAudioAndVideo();
3871 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3872}
3873
3874// This tests that if we negotiate after calling AddTransceiver but before we
3875// have a track, then set a track later, frames from the newly-set tracks are
3876// received end-to-end.
3877TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3878 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
3879 ASSERT_TRUE(CreatePeerConnectionWrappers());
3880 ConnectFakeSignaling();
3881 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3882 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
3883 auto caller_audio_sender = audio_result.MoveValue()->sender();
3884 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3885 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
3886 auto caller_video_sender = video_result.MoveValue()->sender();
3887 callee()->SetRemoteOfferHandler([this] {
3888 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
3889 callee()->pc()->GetTransceivers()[0]->SetDirection(
3890 RtpTransceiverDirection::kSendRecv);
3891 callee()->pc()->GetTransceivers()[1]->SetDirection(
3892 RtpTransceiverDirection::kSendRecv);
3893 });
3894 caller()->CreateAndSetAndSignalOffer();
3895 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3896 // Wait for ICE to complete, without any tracks being set.
3897 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3898 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3899 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3900 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3901 // Now set the tracks, and expect frames to immediately start flowing.
3902 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
3903 auto callee_video_sender = callee()->pc()->GetSenders()[1];
3904 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3905 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3906 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3907 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
3908 MediaExpectations media_expectations;
3909 media_expectations.ExpectBidirectionalAudioAndVideo();
3910 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003911}
3912
3913// This test verifies that a remote video track can be added via AddStream,
3914// and sent end-to-end. For this particular test, it's simply echoed back
3915// from the caller to the callee, rather than being forwarded to a third
3916// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003917TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07003918 ASSERT_TRUE(CreatePeerConnectionWrappers());
3919 ConnectFakeSignaling();
3920 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08003921 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07003922 caller()->CreateAndSetAndSignalOffer();
3923 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003924 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07003925
3926 // Echo the stream back, and do a new offer/anwer (initiated by callee this
3927 // time).
3928 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
3929 callee()->CreateAndSetAndSignalOffer();
3930 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3931
Seth Hampson2f0d7022018-02-20 11:54:42 -08003932 MediaExpectations media_expectations;
3933 media_expectations.ExpectBidirectionalVideo();
3934 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003935}
3936
3937// Test that we achieve the expected end-to-end connection time, using a
3938// fake clock and simulated latency on the media and signaling paths.
3939// We use a TURN<->TURN connection because this is usually the quickest to
3940// set up initially, especially when we're confident the connection will work
3941// and can start sending media before we get a STUN response.
3942//
3943// With various optimizations enabled, here are the network delays we expect to
3944// be on the critical path:
3945// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
3946// signaling answer (with DTLS fingerprint).
3947// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
3948// using TURN<->TURN pair, and DTLS exchange is 4 packets,
3949// the first of which should have arrived before the answer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003950TEST_P(PeerConnectionIntegrationTest, EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07003951 rtc::ScopedFakeClock fake_clock;
3952 // Some things use a time of "0" as a special value, so we need to start out
3953 // the fake clock at a nonzero time.
3954 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003955 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-29 21:08:16 -07003956
3957 static constexpr int media_hop_delay_ms = 50;
3958 static constexpr int signaling_trip_delay_ms = 500;
3959 // For explanation of these values, see comment above.
3960 static constexpr int required_media_hops = 9;
3961 static constexpr int required_signaling_trips = 2;
3962 // For internal delays (such as posting an event asychronously).
3963 static constexpr int allowed_internal_delay_ms = 20;
3964 static constexpr int total_connection_time_ms =
3965 media_hop_delay_ms * required_media_hops +
3966 signaling_trip_delay_ms * required_signaling_trips +
3967 allowed_internal_delay_ms;
3968
3969 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
3970 3478};
3971 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
3972 0};
3973 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
3974 3478};
3975 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
3976 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07003977 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
3978 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02003979
Seth Hampsonaed71642018-06-11 07:41:32 -07003980 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
3981 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07003982 // Bypass permission check on received packets so media can be sent before
3983 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07003984 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
3985 turn_server_1->set_enable_permission_checks(false);
3986 });
3987 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
3988 turn_server_2->set_enable_permission_checks(false);
3989 });
deadbeef1dcb1642017-03-29 21:08:16 -07003990
3991 PeerConnectionInterface::RTCConfiguration client_1_config;
3992 webrtc::PeerConnectionInterface::IceServer ice_server_1;
3993 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
3994 ice_server_1.username = "test";
3995 ice_server_1.password = "test";
3996 client_1_config.servers.push_back(ice_server_1);
3997 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
3998 client_1_config.presume_writable_when_fully_relayed = true;
3999
4000 PeerConnectionInterface::RTCConfiguration client_2_config;
4001 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4002 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4003 ice_server_2.username = "test";
4004 ice_server_2.password = "test";
4005 client_2_config.servers.push_back(ice_server_2);
4006 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4007 client_2_config.presume_writable_when_fully_relayed = true;
4008
4009 ASSERT_TRUE(
4010 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4011 // Set up the simulated delays.
4012 SetSignalingDelayMs(signaling_trip_delay_ms);
4013 ConnectFakeSignaling();
4014 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
4015 virtual_socket_server()->UpdateDelayDistribution();
4016
4017 // Set "offer to receive audio/video" without adding any tracks, so we just
4018 // set up ICE/DTLS with no media.
4019 PeerConnectionInterface::RTCOfferAnswerOptions options;
4020 options.offer_to_receive_audio = 1;
4021 options.offer_to_receive_video = 1;
4022 caller()->SetOfferAnswerOptions(options);
4023 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07004024 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
4025 fake_clock);
Seth Hampson1d4a76d2018-06-19 14:31:41 -07004026 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
4027 // If this is not done a DCHECK can be hit in ports.cc, because a large
4028 // negative number is calculated for the rtt due to the global clock changing.
4029 caller()->pc()->Close();
4030 callee()->pc()->Close();
deadbeef1dcb1642017-03-29 21:08:16 -07004031}
4032
Jonas Orelandbdcee282017-10-10 14:01:40 +02004033// Verify that a TurnCustomizer passed in through RTCConfiguration
4034// is actually used by the underlying TURN candidate pair.
4035// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004036TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02004037 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4038 3478};
4039 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4040 0};
4041 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4042 3478};
4043 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4044 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004045 CreateTurnServer(turn_server_1_internal_address,
4046 turn_server_1_external_address);
4047 CreateTurnServer(turn_server_2_internal_address,
4048 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004049
4050 PeerConnectionInterface::RTCConfiguration client_1_config;
4051 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4052 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4053 ice_server_1.username = "test";
4054 ice_server_1.password = "test";
4055 client_1_config.servers.push_back(ice_server_1);
4056 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004057 auto* customizer1 = CreateTurnCustomizer();
4058 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004059
4060 PeerConnectionInterface::RTCConfiguration client_2_config;
4061 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4062 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4063 ice_server_2.username = "test";
4064 ice_server_2.password = "test";
4065 client_2_config.servers.push_back(ice_server_2);
4066 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004067 auto* customizer2 = CreateTurnCustomizer();
4068 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004069
4070 ASSERT_TRUE(
4071 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4072 ConnectFakeSignaling();
4073
4074 // Set "offer to receive audio/video" without adding any tracks, so we just
4075 // set up ICE/DTLS with no media.
4076 PeerConnectionInterface::RTCOfferAnswerOptions options;
4077 options.offer_to_receive_audio = 1;
4078 options.offer_to_receive_video = 1;
4079 caller()->SetOfferAnswerOptions(options);
4080 caller()->CreateAndSetAndSignalOffer();
4081 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4082
Seth Hampsonaed71642018-06-11 07:41:32 -07004083 ExpectTurnCustomizerCountersIncremented(customizer1);
4084 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004085}
4086
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004087// Verifies that you can use TCP instead of UDP to connect to a TURN server and
4088// send media between the caller and the callee.
4089TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
4090 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4091 3478};
4092 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4093
4094 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07004095 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4096 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004097
4098 webrtc::PeerConnectionInterface::IceServer ice_server;
4099 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
4100 ice_server.username = "test";
4101 ice_server.password = "test";
4102
4103 PeerConnectionInterface::RTCConfiguration client_1_config;
4104 client_1_config.servers.push_back(ice_server);
4105 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4106
4107 PeerConnectionInterface::RTCConfiguration client_2_config;
4108 client_2_config.servers.push_back(ice_server);
4109 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4110
4111 ASSERT_TRUE(
4112 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4113
4114 // Do normal offer/answer and wait for ICE to complete.
4115 ConnectFakeSignaling();
4116 caller()->AddAudioVideoTracks();
4117 callee()->AddAudioVideoTracks();
4118 caller()->CreateAndSetAndSignalOffer();
4119 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4120 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4121 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4122
4123 MediaExpectations media_expectations;
4124 media_expectations.ExpectBidirectionalAudioAndVideo();
4125 EXPECT_TRUE(ExpectNewFrames(media_expectations));
4126}
4127
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004128// Verify that a SSLCertificateVerifier passed in through
4129// PeerConnectionDependencies is actually used by the underlying SSL
4130// implementation to determine whether a certificate presented by the TURN
4131// server is accepted by the client. Note that openssladapter_unittest.cc
4132// contains more detailed, lower-level tests.
4133TEST_P(PeerConnectionIntegrationTest,
4134 SSLCertificateVerifierUsedForTurnConnections) {
4135 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4136 3478};
4137 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4138
4139 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4140 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004141 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4142 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004143
4144 webrtc::PeerConnectionInterface::IceServer ice_server;
4145 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4146 ice_server.username = "test";
4147 ice_server.password = "test";
4148
4149 PeerConnectionInterface::RTCConfiguration client_1_config;
4150 client_1_config.servers.push_back(ice_server);
4151 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4152
4153 PeerConnectionInterface::RTCConfiguration client_2_config;
4154 client_2_config.servers.push_back(ice_server);
4155 // Setting the type to kRelay forces the connection to go through a TURN
4156 // server.
4157 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4158
4159 // Get a copy to the pointer so we can verify calls later.
4160 rtc::TestCertificateVerifier* client_1_cert_verifier =
4161 new rtc::TestCertificateVerifier();
4162 client_1_cert_verifier->verify_certificate_ = true;
4163 rtc::TestCertificateVerifier* client_2_cert_verifier =
4164 new rtc::TestCertificateVerifier();
4165 client_2_cert_verifier->verify_certificate_ = true;
4166
4167 // Create the dependencies with the test certificate verifier.
4168 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4169 client_1_deps.tls_cert_verifier =
4170 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4171 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4172 client_2_deps.tls_cert_verifier =
4173 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4174
4175 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4176 client_1_config, std::move(client_1_deps), client_2_config,
4177 std::move(client_2_deps)));
4178 ConnectFakeSignaling();
4179
4180 // Set "offer to receive audio/video" without adding any tracks, so we just
4181 // set up ICE/DTLS with no media.
4182 PeerConnectionInterface::RTCOfferAnswerOptions options;
4183 options.offer_to_receive_audio = 1;
4184 options.offer_to_receive_video = 1;
4185 caller()->SetOfferAnswerOptions(options);
4186 caller()->CreateAndSetAndSignalOffer();
4187 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4188
4189 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4190 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004191}
4192
4193TEST_P(PeerConnectionIntegrationTest,
4194 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
4195 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4196 3478};
4197 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4198
4199 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4200 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004201 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4202 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004203
4204 webrtc::PeerConnectionInterface::IceServer ice_server;
4205 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4206 ice_server.username = "test";
4207 ice_server.password = "test";
4208
4209 PeerConnectionInterface::RTCConfiguration client_1_config;
4210 client_1_config.servers.push_back(ice_server);
4211 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4212
4213 PeerConnectionInterface::RTCConfiguration client_2_config;
4214 client_2_config.servers.push_back(ice_server);
4215 // Setting the type to kRelay forces the connection to go through a TURN
4216 // server.
4217 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4218
4219 // Get a copy to the pointer so we can verify calls later.
4220 rtc::TestCertificateVerifier* client_1_cert_verifier =
4221 new rtc::TestCertificateVerifier();
4222 client_1_cert_verifier->verify_certificate_ = false;
4223 rtc::TestCertificateVerifier* client_2_cert_verifier =
4224 new rtc::TestCertificateVerifier();
4225 client_2_cert_verifier->verify_certificate_ = false;
4226
4227 // Create the dependencies with the test certificate verifier.
4228 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4229 client_1_deps.tls_cert_verifier =
4230 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4231 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4232 client_2_deps.tls_cert_verifier =
4233 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4234
4235 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4236 client_1_config, std::move(client_1_deps), client_2_config,
4237 std::move(client_2_deps)));
4238 ConnectFakeSignaling();
4239
4240 // Set "offer to receive audio/video" without adding any tracks, so we just
4241 // set up ICE/DTLS with no media.
4242 PeerConnectionInterface::RTCOfferAnswerOptions options;
4243 options.offer_to_receive_audio = 1;
4244 options.offer_to_receive_video = 1;
4245 caller()->SetOfferAnswerOptions(options);
4246 caller()->CreateAndSetAndSignalOffer();
4247 bool wait_res = true;
4248 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
4249 // properly, should be able to just wait for a state of "failed" instead of
4250 // waiting a fixed 10 seconds.
4251 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
4252 ASSERT_FALSE(wait_res);
4253
4254 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4255 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004256}
4257
deadbeefc964d0b2017-04-03 10:03:35 -07004258// Test that audio and video flow end-to-end when codec names don't use the
4259// expected casing, given that they're supposed to be case insensitive. To test
4260// this, all but one codec is removed from each media description, and its
4261// casing is changed.
4262//
4263// In the past, this has regressed and caused crashes/black video, due to the
4264// fact that code at some layers was doing case-insensitive comparisons and
4265// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004266TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07004267 ASSERT_TRUE(CreatePeerConnectionWrappers());
4268 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004269 caller()->AddAudioVideoTracks();
4270 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07004271
4272 // Remove all but one audio/video codec (opus and VP8), and change the
4273 // casing of the caller's generated offer.
4274 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
4275 cricket::AudioContentDescription* audio =
4276 GetFirstAudioContentDescription(description);
4277 ASSERT_NE(nullptr, audio);
4278 auto audio_codecs = audio->codecs();
4279 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
4280 [](const cricket::AudioCodec& codec) {
4281 return codec.name != "opus";
4282 }),
4283 audio_codecs.end());
4284 ASSERT_EQ(1u, audio_codecs.size());
4285 audio_codecs[0].name = "OpUs";
4286 audio->set_codecs(audio_codecs);
4287
4288 cricket::VideoContentDescription* video =
4289 GetFirstVideoContentDescription(description);
4290 ASSERT_NE(nullptr, video);
4291 auto video_codecs = video->codecs();
4292 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
4293 [](const cricket::VideoCodec& codec) {
4294 return codec.name != "VP8";
4295 }),
4296 video_codecs.end());
4297 ASSERT_EQ(1u, video_codecs.size());
4298 video_codecs[0].name = "vP8";
4299 video->set_codecs(video_codecs);
4300 });
4301
4302 caller()->CreateAndSetAndSignalOffer();
4303 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4304
4305 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004306 MediaExpectations media_expectations;
4307 media_expectations.ExpectBidirectionalAudioAndVideo();
4308 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07004309}
4310
Jonas Oreland49ac5952018-09-26 16:04:32 +02004311TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07004312 ASSERT_TRUE(CreatePeerConnectionWrappers());
4313 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004314 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07004315 caller()->CreateAndSetAndSignalOffer();
4316 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07004317 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004318 MediaExpectations media_expectations;
4319 media_expectations.CalleeExpectsSomeAudio(1);
4320 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02004321 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07004322 auto receiver = callee()->pc()->GetReceivers()[0];
4323 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02004324 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07004325 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4326 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02004327 sources[0].source_id());
4328 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
4329}
4330
4331TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
4332 ASSERT_TRUE(CreatePeerConnectionWrappers());
4333 ConnectFakeSignaling();
4334 caller()->AddVideoTrack();
4335 caller()->CreateAndSetAndSignalOffer();
4336 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4337 // Wait for one video frame to be received by the callee.
4338 MediaExpectations media_expectations;
4339 media_expectations.CalleeExpectsSomeVideo(1);
4340 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4341 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
4342 auto receiver = callee()->pc()->GetReceivers()[0];
4343 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
4344 auto sources = receiver->GetSources();
4345 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4346 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
4347 sources[0].source_id());
4348 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07004349}
4350
deadbeef2f425aa2017-04-14 10:41:32 -07004351// Test that if a track is removed and added again with a different stream ID,
4352// the new stream ID is successfully communicated in SDP and media continues to
4353// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004354// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
4355// it will not reuse a transceiver that has already been sending. After creating
4356// a new transceiver it tries to create an offer with two senders of the same
4357// track ids and it fails.
4358TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07004359 ASSERT_TRUE(CreatePeerConnectionWrappers());
4360 ConnectFakeSignaling();
4361
deadbeef2f425aa2017-04-14 10:41:32 -07004362 // Add track using stream 1, do offer/answer.
4363 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
4364 caller()->CreateLocalAudioTrack();
4365 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07004366 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07004367 caller()->CreateAndSetAndSignalOffer();
4368 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004369 {
4370 MediaExpectations media_expectations;
4371 media_expectations.CalleeExpectsSomeAudio(1);
4372 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4373 }
deadbeef2f425aa2017-04-14 10:41:32 -07004374 // Remove the sender, and create a new one with the new stream.
4375 caller()->pc()->RemoveTrack(sender);
Steve Antond78323f2018-07-11 11:13:44 -07004376 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07004377 caller()->CreateAndSetAndSignalOffer();
4378 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4379 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004380 {
4381 MediaExpectations media_expectations;
4382 media_expectations.CalleeExpectsSomeAudio();
4383 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4384 }
deadbeef2f425aa2017-04-14 10:41:32 -07004385}
4386
Seth Hampson2f0d7022018-02-20 11:54:42 -08004387TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02004388 ASSERT_TRUE(CreatePeerConnectionWrappers());
4389 ConnectFakeSignaling();
4390
Karl Wiberg918f50c2018-07-05 11:40:33 +02004391 auto output = absl::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Elad Alon99c3fe52017-10-13 16:29:40 +02004392 ON_CALL(*output, IsActive()).WillByDefault(testing::Return(true));
4393 ON_CALL(*output, Write(::testing::_)).WillByDefault(testing::Return(true));
4394 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01004395 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
4396 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02004397
Steve Anton15324772018-01-16 10:26:49 -08004398 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02004399 caller()->CreateAndSetAndSignalOffer();
4400 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4401}
4402
Steve Antonede9ca52017-10-16 13:04:27 -07004403// Test that if candidates are only signaled by applying full session
4404// descriptions (instead of using AddIceCandidate), the peers can connect to
4405// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004406TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07004407 ASSERT_TRUE(CreatePeerConnectionWrappers());
4408 // Each side will signal the session descriptions but not candidates.
4409 ConnectFakeSignalingForSdpOnly();
4410
4411 // Add audio video track and exchange the initial offer/answer with media
4412 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08004413 caller()->AddAudioVideoTracks();
4414 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004415 caller()->CreateAndSetAndSignalOffer();
4416
4417 // Wait for all candidates to be gathered on both the caller and callee.
4418 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4419 caller()->ice_gathering_state(), kDefaultTimeout);
4420 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4421 callee()->ice_gathering_state(), kDefaultTimeout);
4422
4423 // The candidates will now be included in the session description, so
4424 // signaling them will start the ICE connection.
4425 caller()->CreateAndSetAndSignalOffer();
4426 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4427
4428 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004429 MediaExpectations media_expectations;
4430 media_expectations.ExpectBidirectionalAudioAndVideo();
4431 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07004432}
4433
henrika5f6bf242017-11-01 11:06:56 +01004434// Test that SetAudioPlayout can be used to disable audio playout from the
4435// start, then later enable it. This may be useful, for example, if the caller
4436// needs to play a local ringtone until some event occurs, after which it
4437// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004438TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01004439 ASSERT_TRUE(CreatePeerConnectionWrappers());
4440 ConnectFakeSignaling();
4441
4442 // Set up audio-only call where audio playout is disabled on caller's side.
4443 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08004444 caller()->AddAudioTrack();
4445 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004446 caller()->CreateAndSetAndSignalOffer();
4447 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4448
4449 // Pump messages for a second.
4450 WAIT(false, 1000);
4451 // Since audio playout is disabled, the caller shouldn't have received
4452 // anything (at the playout level, at least).
4453 EXPECT_EQ(0, caller()->audio_frames_received());
4454 // As a sanity check, make sure the callee (for which playout isn't disabled)
4455 // did still see frames on its audio level.
4456 ASSERT_GT(callee()->audio_frames_received(), 0);
4457
4458 // Enable playout again, and ensure audio starts flowing.
4459 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004460 MediaExpectations media_expectations;
4461 media_expectations.ExpectBidirectionalAudio();
4462 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01004463}
4464
4465double GetAudioEnergyStat(PeerConnectionWrapper* pc) {
4466 auto report = pc->NewGetStats();
4467 auto track_stats_list =
4468 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
4469 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
4470 for (const auto* track_stats : track_stats_list) {
4471 if (track_stats->remote_source.is_defined() &&
4472 *track_stats->remote_source) {
4473 remote_track_stats = track_stats;
4474 break;
4475 }
4476 }
4477
4478 if (!remote_track_stats->total_audio_energy.is_defined()) {
4479 return 0.0;
4480 }
4481 return *remote_track_stats->total_audio_energy;
4482}
4483
4484// Test that if audio playout is disabled via the SetAudioPlayout() method, then
4485// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004486TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01004487 DisableAudioPlayoutStillGeneratesAudioStats) {
4488 ASSERT_TRUE(CreatePeerConnectionWrappers());
4489 ConnectFakeSignaling();
4490
4491 // Set up audio-only call where playout is disabled but audio-processing is
4492 // still active.
Steve Anton15324772018-01-16 10:26:49 -08004493 caller()->AddAudioTrack();
4494 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004495 caller()->pc()->SetAudioPlayout(false);
4496
4497 caller()->CreateAndSetAndSignalOffer();
4498 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4499
4500 // Wait for the callee to receive audio stats.
4501 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
4502}
4503
henrika4f167df2017-11-01 14:45:55 +01004504// Test that SetAudioRecording can be used to disable audio recording from the
4505// start, then later enable it. This may be useful, for example, if the caller
4506// wants to ensure that no audio resources are active before a certain state
4507// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004508TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01004509 ASSERT_TRUE(CreatePeerConnectionWrappers());
4510 ConnectFakeSignaling();
4511
4512 // Set up audio-only call where audio recording is disabled on caller's side.
4513 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08004514 caller()->AddAudioTrack();
4515 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01004516 caller()->CreateAndSetAndSignalOffer();
4517 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4518
4519 // Pump messages for a second.
4520 WAIT(false, 1000);
4521 // Since caller has disabled audio recording, the callee shouldn't have
4522 // received anything.
4523 EXPECT_EQ(0, callee()->audio_frames_received());
4524 // As a sanity check, make sure the caller did still see frames on its
4525 // audio level since audio recording is enabled on the calle side.
4526 ASSERT_GT(caller()->audio_frames_received(), 0);
4527
4528 // Enable audio recording again, and ensure audio starts flowing.
4529 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004530 MediaExpectations media_expectations;
4531 media_expectations.ExpectBidirectionalAudio();
4532 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01004533}
4534
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004535// Test that after closing PeerConnections, they stop sending any packets (ICE,
4536// DTLS, RTP...).
Seth Hampson2f0d7022018-02-20 11:54:42 -08004537TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004538 // Set up audio/video/data, wait for some frames to be received.
4539 ASSERT_TRUE(CreatePeerConnectionWrappers());
4540 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004541 caller()->AddAudioVideoTracks();
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004542#ifdef HAVE_SCTP
4543 caller()->CreateDataChannel();
4544#endif
4545 caller()->CreateAndSetAndSignalOffer();
4546 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004547 MediaExpectations media_expectations;
4548 media_expectations.CalleeExpectsSomeAudioAndVideo();
4549 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004550 // Close PeerConnections.
4551 caller()->pc()->Close();
4552 callee()->pc()->Close();
4553 // Pump messages for a second, and ensure no new packets end up sent.
4554 uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
4555 WAIT(false, 1000);
4556 uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
4557 EXPECT_EQ(sent_packets_a, sent_packets_b);
4558}
4559
Steve Anton7eca0932018-03-30 15:18:41 -07004560// Test that transport stats are generated by the RTCStatsCollector for a
4561// connection that only involves data channels. This is a regression test for
4562// crbug.com/826972.
4563#ifdef HAVE_SCTP
4564TEST_P(PeerConnectionIntegrationTest,
4565 TransportStatsReportedForDataChannelOnlyConnection) {
4566 ASSERT_TRUE(CreatePeerConnectionWrappers());
4567 ConnectFakeSignaling();
4568 caller()->CreateDataChannel();
4569
4570 caller()->CreateAndSetAndSignalOffer();
4571 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4572 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
4573
4574 auto caller_report = caller()->NewGetStats();
4575 EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
4576 auto callee_report = callee()->NewGetStats();
4577 EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
4578}
4579#endif // HAVE_SCTP
4580
Qingsi Wang7685e862018-06-11 20:15:46 -07004581TEST_P(PeerConnectionIntegrationTest,
4582 IceEventsGeneratedAndLoggedInRtcEventLog) {
4583 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
4584 ConnectFakeSignaling();
4585 PeerConnectionInterface::RTCOfferAnswerOptions options;
4586 options.offer_to_receive_audio = 1;
4587 caller()->SetOfferAnswerOptions(options);
4588 caller()->CreateAndSetAndSignalOffer();
4589 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4590 ASSERT_NE(nullptr, caller()->event_log_factory());
4591 ASSERT_NE(nullptr, callee()->event_log_factory());
4592 webrtc::FakeRtcEventLog* caller_event_log =
4593 static_cast<webrtc::FakeRtcEventLog*>(
4594 caller()->event_log_factory()->last_log_created());
4595 webrtc::FakeRtcEventLog* callee_event_log =
4596 static_cast<webrtc::FakeRtcEventLog*>(
4597 callee()->event_log_factory()->last_log_created());
4598 ASSERT_NE(nullptr, caller_event_log);
4599 ASSERT_NE(nullptr, callee_event_log);
4600 int caller_ice_config_count = caller_event_log->GetEventCount(
4601 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4602 int caller_ice_event_count = caller_event_log->GetEventCount(
4603 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4604 int callee_ice_config_count = callee_event_log->GetEventCount(
4605 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4606 int callee_ice_event_count = callee_event_log->GetEventCount(
4607 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4608 EXPECT_LT(0, caller_ice_config_count);
4609 EXPECT_LT(0, caller_ice_event_count);
4610 EXPECT_LT(0, callee_ice_config_count);
4611 EXPECT_LT(0, callee_ice_event_count);
4612}
4613
Seth Hampson2f0d7022018-02-20 11:54:42 -08004614INSTANTIATE_TEST_CASE_P(PeerConnectionIntegrationTest,
4615 PeerConnectionIntegrationTest,
4616 Values(SdpSemantics::kPlanB,
4617 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-17 17:41:02 -08004618
Steve Anton74255ff2018-01-24 18:32:57 -08004619// Tests that verify interoperability between Plan B and Unified Plan
4620// PeerConnections.
4621class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08004622 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08004623 public ::testing::WithParamInterface<
4624 std::tuple<SdpSemantics, SdpSemantics>> {
4625 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08004626 // Setting the SdpSemantics for the base test to kDefault does not matter
4627 // because we specify not to use the test semantics when creating
4628 // PeerConnectionWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08004629 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07004630 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08004631 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08004632 callee_semantics_(std::get<1>(GetParam())) {}
4633
4634 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07004635 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
4636 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08004637 }
4638
4639 const SdpSemantics caller_semantics_;
4640 const SdpSemantics callee_semantics_;
4641};
4642
4643TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
4644 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4645 ConnectFakeSignaling();
4646
4647 caller()->CreateAndSetAndSignalOffer();
4648 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4649}
4650
4651TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
4652 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4653 ConnectFakeSignaling();
4654 auto audio_sender = caller()->AddAudioTrack();
4655
4656 caller()->CreateAndSetAndSignalOffer();
4657 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4658
4659 // Verify that one audio receiver has been created on the remote and that it
4660 // has the same track ID as the sending track.
4661 auto receivers = callee()->pc()->GetReceivers();
4662 ASSERT_EQ(1u, receivers.size());
4663 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
4664 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
4665
Seth Hampson2f0d7022018-02-20 11:54:42 -08004666 MediaExpectations media_expectations;
4667 media_expectations.CalleeExpectsSomeAudio();
4668 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004669}
4670
4671TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
4672 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4673 ConnectFakeSignaling();
4674 auto video_sender = caller()->AddVideoTrack();
4675 auto audio_sender = caller()->AddAudioTrack();
4676
4677 caller()->CreateAndSetAndSignalOffer();
4678 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4679
4680 // Verify that one audio and one video receiver have been created on the
4681 // remote and that they have the same track IDs as the sending tracks.
4682 auto audio_receivers =
4683 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
4684 ASSERT_EQ(1u, audio_receivers.size());
4685 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
4686 auto video_receivers =
4687 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
4688 ASSERT_EQ(1u, video_receivers.size());
4689 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
4690
Seth Hampson2f0d7022018-02-20 11:54:42 -08004691 MediaExpectations media_expectations;
4692 media_expectations.CalleeExpectsSomeAudioAndVideo();
4693 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004694}
4695
4696TEST_P(PeerConnectionIntegrationInteropTest,
4697 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
4698 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4699 ConnectFakeSignaling();
4700 caller()->AddAudioVideoTracks();
4701 callee()->AddAudioVideoTracks();
4702
4703 caller()->CreateAndSetAndSignalOffer();
4704 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4705
Seth Hampson2f0d7022018-02-20 11:54:42 -08004706 MediaExpectations media_expectations;
4707 media_expectations.ExpectBidirectionalAudioAndVideo();
4708 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004709}
4710
4711TEST_P(PeerConnectionIntegrationInteropTest,
4712 ReverseRolesOneAudioLocalToOneVideoRemote) {
4713 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4714 ConnectFakeSignaling();
4715 caller()->AddAudioTrack();
4716 callee()->AddVideoTrack();
4717
4718 caller()->CreateAndSetAndSignalOffer();
4719 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4720
4721 // Verify that only the audio track has been negotiated.
4722 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
4723 // Might also check that the callee's NegotiationNeeded flag is set.
4724
4725 // Reverse roles.
4726 callee()->CreateAndSetAndSignalOffer();
4727 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4728
Seth Hampson2f0d7022018-02-20 11:54:42 -08004729 MediaExpectations media_expectations;
4730 media_expectations.CallerExpectsSomeVideo();
4731 media_expectations.CalleeExpectsSomeAudio();
4732 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004733}
4734
Steve Antonba42e992018-04-09 14:10:01 -07004735INSTANTIATE_TEST_CASE_P(
4736 PeerConnectionIntegrationTest,
4737 PeerConnectionIntegrationInteropTest,
4738 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4739 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
4740
4741// Test that if the Unified Plan side offers two video tracks then the Plan B
4742// side will only see the first one and ignore the second.
4743TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07004744 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
4745 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08004746 ConnectFakeSignaling();
4747 auto first_sender = caller()->AddVideoTrack();
4748 caller()->AddVideoTrack();
4749
4750 caller()->CreateAndSetAndSignalOffer();
4751 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4752
4753 // Verify that there is only one receiver and it corresponds to the first
4754 // added track.
4755 auto receivers = callee()->pc()->GetReceivers();
4756 ASSERT_EQ(1u, receivers.size());
4757 EXPECT_TRUE(receivers[0]->track()->enabled());
4758 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
4759
Seth Hampson2f0d7022018-02-20 11:54:42 -08004760 MediaExpectations media_expectations;
4761 media_expectations.CalleeExpectsSomeVideo();
4762 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004763}
4764
deadbeef1dcb1642017-03-29 21:08:16 -07004765} // namespace
4766
4767#endif // if !defined(THREAD_SANITIZER)