blob: 7b2d17103502318111678f6e7ede6ae4e9e3ab89 [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
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -070017#include <algorithm>
deadbeef1dcb1642017-03-29 21:08:16 -070018#include <functional>
19#include <list>
20#include <map>
21#include <memory>
22#include <utility>
23#include <vector>
24
Steve Anton64b626b2019-01-28 17:25:26 -080025#include "absl/algorithm/container.h"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "api/media_stream_interface.h"
27#include "api/peer_connection_interface.h"
28#include "api/peer_connection_proxy.h"
Danil Chapovalov9da25bd2019-06-20 10:19:42 +020029#include "api/rtc_event_log/rtc_event_log_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080030#include "api/rtp_receiver_interface.h"
Danil Chapovalov9da25bd2019-06-20 10:19:42 +020031#include "api/task_queue/default_task_queue_factory.h"
Erik Språngceb44952020-09-22 11:36:35 +020032#include "api/transport/field_trial_based_config.h"
Steve Anton10542f22019-01-11 09:11:00 -080033#include "api/uma_metrics.h"
Anders Carlsson67537952018-05-03 11:28:29 +020034#include "api/video_codecs/sdp_video_format.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070035#include "call/call.h"
36#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080037#include "media/engine/fake_webrtc_video_engine.h"
38#include "media/engine/webrtc_media_engine.h"
Danil Chapovalov9da25bd2019-06-20 10:19:42 +020039#include "media/engine/webrtc_media_engine_defaults.h"
Per Åhgrencc73ed32020-04-26 23:56:17 +020040#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
Qingsi Wang25ec8882019-11-15 12:33:05 -080041#include "p2p/base/fake_ice_transport.h"
Steve Anton10542f22019-01-11 09:11:00 -080042#include "p2p/base/mock_async_resolver.h"
43#include "p2p/base/p2p_constants.h"
44#include "p2p/base/port_interface.h"
45#include "p2p/base/test_stun_server.h"
46#include "p2p/base/test_turn_customizer.h"
47#include "p2p/base/test_turn_server.h"
48#include "p2p/client/basic_port_allocator.h"
49#include "pc/dtmf_sender.h"
50#include "pc/local_audio_source.h"
51#include "pc/media_session.h"
52#include "pc/peer_connection.h"
53#include "pc/peer_connection_factory.h"
54#include "pc/rtp_media_utils.h"
55#include "pc/session_description.h"
56#include "pc/test/fake_audio_capture_module.h"
57#include "pc/test/fake_periodic_video_track_source.h"
58#include "pc/test/fake_rtc_certificate_generator.h"
59#include "pc/test/fake_video_track_renderer.h"
60#include "pc/test/mock_peer_connection_observers.h"
Jonas Olssonb75d9e92019-02-22 10:33:29 +010061#include "rtc_base/fake_clock.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070062#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080063#include "rtc_base/fake_network.h"
64#include "rtc_base/firewall_socket_server.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020065#include "rtc_base/gunit.h"
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +020066#include "rtc_base/numerics/safe_conversions.h"
Steve Anton10542f22019-01-11 09:11:00 -080067#include "rtc_base/test_certificate_verifier.h"
68#include "rtc_base/time_utils.h"
69#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020070#include "system_wrappers/include/metrics.h"
Qingsi Wangc129c352019-04-18 10:41:58 -070071#include "test/field_trial.h"
Elad Alon99c3fe52017-10-13 16:29:40 +020072#include "test/gmock.h"
deadbeef1dcb1642017-03-29 21:08:16 -070073
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010074namespace webrtc {
75namespace {
76
77using ::cricket::ContentInfo;
78using ::cricket::StreamParams;
79using ::rtc::SocketAddress;
80using ::testing::_;
Seth Hampson2f0d7022018-02-20 11:54:42 -080081using ::testing::Combine;
Steve Anton64b626b2019-01-28 17:25:26 -080082using ::testing::Contains;
Mirko Bonadeie46f5db2019-03-26 20:14:46 +010083using ::testing::DoAll;
Steve Antonede9ca52017-10-16 13:04:27 -070084using ::testing::ElementsAre;
Qingsi Wang1dac6d82018-12-12 15:28:47 -080085using ::testing::NiceMock;
Steve Anton64b626b2019-01-28 17:25:26 -080086using ::testing::Return;
Zach Stein6fcdc2f2018-08-23 16:25:55 -070087using ::testing::SetArgPointee;
Steve Antonffa6ce42018-11-30 09:26:08 -080088using ::testing::UnorderedElementsAreArray;
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010089using ::testing::Values;
Steve Anton74255ff2018-01-24 18:32:57 -080090using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
deadbeef1dcb1642017-03-29 21:08:16 -070091
92static const int kDefaultTimeout = 10000;
93static const int kMaxWaitForStatsMs = 3000;
94static const int kMaxWaitForActivationMs = 5000;
95static const int kMaxWaitForFramesMs = 10000;
96// Default number of audio/video frames to wait for before considering a test
97// successful.
98static const int kDefaultExpectedAudioFrameCount = 3;
99static const int kDefaultExpectedVideoFrameCount = 3;
100
deadbeef1dcb1642017-03-29 21:08:16 -0700101static const char kDataChannelLabel[] = "data_channel";
102
103// SRTP cipher name negotiated by the tests. This must be updated if the
104// default changes.
Taylor Brandstetterfd350d72018-04-03 16:29:26 -0700105static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_80;
deadbeef1dcb1642017-03-29 21:08:16 -0700106static const int kDefaultSrtpCryptoSuiteGcm = rtc::SRTP_AEAD_AES_256_GCM;
107
Steve Antonede9ca52017-10-16 13:04:27 -0700108static const SocketAddress kDefaultLocalAddress("192.168.1.1", 0);
109
deadbeef1dcb1642017-03-29 21:08:16 -0700110// Helper function for constructing offer/answer options to initiate an ICE
111// restart.
112PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions() {
113 PeerConnectionInterface::RTCOfferAnswerOptions options;
114 options.ice_restart = true;
115 return options;
116}
117
deadbeefd8ad7882017-04-18 16:01:17 -0700118// Remove all stream information (SSRCs, track IDs, etc.) and "msid-semantic"
119// attribute from received SDP, simulating a legacy endpoint.
120void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) {
121 for (ContentInfo& content : desc->contents()) {
Steve Antonb1c1de12017-12-21 15:14:30 -0800122 content.media_description()->mutable_streams().clear();
deadbeefd8ad7882017-04-18 16:01:17 -0700123 }
124 desc->set_msid_supported(false);
Henrik Boström5b147782018-12-04 11:25:05 +0100125 desc->set_msid_signaling(0);
deadbeefd8ad7882017-04-18 16:01:17 -0700126}
127
Seth Hampson5897a6e2018-04-03 11:16:33 -0700128// Removes all stream information besides the stream ids, simulating an
129// endpoint that only signals a=msid lines to convey stream_ids.
130void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) {
131 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700132 std::string track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700133 std::vector<std::string> stream_ids;
134 if (!content.media_description()->streams().empty()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700135 const StreamParams& first_stream =
136 content.media_description()->streams()[0];
137 track_id = first_stream.id;
138 stream_ids = first_stream.stream_ids();
Seth Hampson5897a6e2018-04-03 11:16:33 -0700139 }
140 content.media_description()->mutable_streams().clear();
Steve Antondf527fd2018-04-27 15:52:03 -0700141 StreamParams new_stream;
142 new_stream.id = track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700143 new_stream.set_stream_ids(stream_ids);
144 content.media_description()->AddStream(new_stream);
145 }
146}
147
zhihuangf8164932017-05-19 13:09:47 -0700148int FindFirstMediaStatsIndexByKind(
149 const std::string& kind,
150 const std::vector<const webrtc::RTCMediaStreamTrackStats*>&
151 media_stats_vec) {
152 for (size_t i = 0; i < media_stats_vec.size(); i++) {
153 if (media_stats_vec[i]->kind.ValueToString() == kind) {
154 return i;
155 }
156 }
157 return -1;
158}
159
deadbeef1dcb1642017-03-29 21:08:16 -0700160class SignalingMessageReceiver {
161 public:
Steve Antona3a92c22017-12-07 10:27:41 -0800162 virtual void ReceiveSdpMessage(SdpType type, const std::string& msg) = 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700163 virtual void ReceiveIceMessage(const std::string& sdp_mid,
164 int sdp_mline_index,
165 const std::string& msg) = 0;
166
167 protected:
168 SignalingMessageReceiver() {}
169 virtual ~SignalingMessageReceiver() {}
170};
171
172class MockRtpReceiverObserver : public webrtc::RtpReceiverObserverInterface {
173 public:
174 explicit MockRtpReceiverObserver(cricket::MediaType media_type)
175 : expected_media_type_(media_type) {}
176
177 void OnFirstPacketReceived(cricket::MediaType media_type) override {
178 ASSERT_EQ(expected_media_type_, media_type);
179 first_packet_received_ = true;
180 }
181
182 bool first_packet_received() const { return first_packet_received_; }
183
184 virtual ~MockRtpReceiverObserver() {}
185
186 private:
187 bool first_packet_received_ = false;
188 cricket::MediaType expected_media_type_;
189};
190
191// Helper class that wraps a peer connection, observes it, and can accept
192// signaling messages from another wrapper.
193//
194// Uses a fake network, fake A/V capture, and optionally fake
195// encoders/decoders, though they aren't used by default since they don't
196// advertise support of any codecs.
Steve Anton94286cb2017-09-26 16:20:19 -0700197// TODO(steveanton): See how this could become a subclass of
Seth Hampson2f0d7022018-02-20 11:54:42 -0800198// PeerConnectionWrapper defined in peerconnectionwrapper.h.
deadbeef1dcb1642017-03-29 21:08:16 -0700199class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
Steve Anton15324772018-01-16 10:26:49 -0800200 public SignalingMessageReceiver {
deadbeef1dcb1642017-03-29 21:08:16 -0700201 public:
202 // Different factory methods for convenience.
203 // TODO(deadbeef): Could use the pattern of:
204 //
205 // PeerConnectionWrapper =
206 // WrapperBuilder.WithConfig(...).WithOptions(...).build();
207 //
208 // To reduce some code duplication.
209 static PeerConnectionWrapper* CreateWithDtlsIdentityStore(
210 const std::string& debug_name,
211 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
212 rtc::Thread* network_thread,
213 rtc::Thread* worker_thread) {
214 PeerConnectionWrapper* client(new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700215 webrtc::PeerConnectionDependencies dependencies(nullptr);
216 dependencies.cert_generator = std::move(cert_generator);
Niels Möllerf06f9232018-08-07 12:32:18 +0200217 if (!client->Init(nullptr, nullptr, std::move(dependencies), network_thread,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800218 worker_thread, nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +0200219 /*reset_encoder_factory=*/false,
220 /*reset_decoder_factory=*/false)) {
deadbeef1dcb1642017-03-29 21:08:16 -0700221 delete client;
222 return nullptr;
223 }
224 return client;
225 }
226
deadbeef2f425aa2017-04-14 10:41:32 -0700227 webrtc::PeerConnectionFactoryInterface* pc_factory() const {
228 return peer_connection_factory_.get();
229 }
230
deadbeef1dcb1642017-03-29 21:08:16 -0700231 webrtc::PeerConnectionInterface* pc() const { return peer_connection_.get(); }
232
233 // If a signaling message receiver is set (via ConnectFakeSignaling), this
234 // will set the whole offer/answer exchange in motion. Just need to wait for
235 // the signaling state to reach "stable".
236 void CreateAndSetAndSignalOffer() {
Eldar Rello5ab79e62019-10-09 18:29:44 +0300237 auto offer = CreateOfferAndWait();
deadbeef1dcb1642017-03-29 21:08:16 -0700238 ASSERT_NE(nullptr, offer);
239 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(offer)));
240 }
241
242 // Sets the options to be used when CreateAndSetAndSignalOffer is called, or
243 // when a remote offer is received (via fake signaling) and an answer is
244 // generated. By default, uses default options.
245 void SetOfferAnswerOptions(
246 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
247 offer_answer_options_ = options;
248 }
249
250 // Set a callback to be invoked when SDP is received via the fake signaling
251 // channel, which provides an opportunity to munge (modify) the SDP. This is
252 // used to test SDP being applied that a PeerConnection would normally not
253 // generate, but a non-JSEP endpoint might.
254 void SetReceivedSdpMunger(
255 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100256 received_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700257 }
258
deadbeefc964d0b2017-04-03 10:03:35 -0700259 // Similar to the above, but this is run on SDP immediately after it's
deadbeef1dcb1642017-03-29 21:08:16 -0700260 // generated.
261 void SetGeneratedSdpMunger(
262 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100263 generated_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700264 }
265
Seth Hampson2f0d7022018-02-20 11:54:42 -0800266 // Set a callback to be invoked when a remote offer is received via the fake
267 // signaling channel. This provides an opportunity to change the
268 // PeerConnection state before an answer is created and sent to the caller.
269 void SetRemoteOfferHandler(std::function<void()> handler) {
270 remote_offer_handler_ = std::move(handler);
271 }
272
Qingsi Wang1dac6d82018-12-12 15:28:47 -0800273 void SetRemoteAsyncResolver(rtc::MockAsyncResolver* resolver) {
274 remote_async_resolver_ = resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700275 }
276
Steve Antonede9ca52017-10-16 13:04:27 -0700277 // Every ICE connection state in order that has been seen by the observer.
278 std::vector<PeerConnectionInterface::IceConnectionState>
279 ice_connection_state_history() const {
280 return ice_connection_state_history_;
281 }
Steve Anton6f25b092017-10-23 09:39:20 -0700282 void clear_ice_connection_state_history() {
283 ice_connection_state_history_.clear();
284 }
Steve Antonede9ca52017-10-16 13:04:27 -0700285
Jonas Olssonacd8ae72019-02-25 15:26:24 +0100286 // Every standardized ICE connection state in order that has been seen by the
287 // observer.
288 std::vector<PeerConnectionInterface::IceConnectionState>
289 standardized_ice_connection_state_history() const {
290 return standardized_ice_connection_state_history_;
291 }
292
Jonas Olsson635474e2018-10-18 15:58:17 +0200293 // Every PeerConnection state in order that has been seen by the observer.
294 std::vector<PeerConnectionInterface::PeerConnectionState>
295 peer_connection_state_history() const {
296 return peer_connection_state_history_;
297 }
298
Steve Antonede9ca52017-10-16 13:04:27 -0700299 // Every ICE gathering state in order that has been seen by the observer.
300 std::vector<PeerConnectionInterface::IceGatheringState>
301 ice_gathering_state_history() const {
302 return ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -0700303 }
Alex Drake00c7ecf2019-08-06 10:54:47 -0700304 std::vector<cricket::CandidatePairChangeEvent>
305 ice_candidate_pair_change_history() const {
306 return ice_candidate_pair_change_history_;
307 }
deadbeef1dcb1642017-03-29 21:08:16 -0700308
Eldar Rello5ab79e62019-10-09 18:29:44 +0300309 // Every PeerConnection signaling state in order that has been seen by the
310 // observer.
311 std::vector<PeerConnectionInterface::SignalingState>
312 peer_connection_signaling_state_history() const {
313 return peer_connection_signaling_state_history_;
314 }
315
Steve Anton15324772018-01-16 10:26:49 -0800316 void AddAudioVideoTracks() {
317 AddAudioTrack();
318 AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700319 }
320
Steve Anton74255ff2018-01-24 18:32:57 -0800321 rtc::scoped_refptr<RtpSenderInterface> AddAudioTrack() {
322 return AddTrack(CreateLocalAudioTrack());
323 }
deadbeef1dcb1642017-03-29 21:08:16 -0700324
Steve Anton74255ff2018-01-24 18:32:57 -0800325 rtc::scoped_refptr<RtpSenderInterface> AddVideoTrack() {
326 return AddTrack(CreateLocalVideoTrack());
327 }
deadbeef1dcb1642017-03-29 21:08:16 -0700328
329 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack() {
Niels Möller2d02e082018-05-21 11:23:35 +0200330 cricket::AudioOptions options;
deadbeef1dcb1642017-03-29 21:08:16 -0700331 // Disable highpass filter so that we can get all the test audio frames.
Niels Möller2d02e082018-05-21 11:23:35 +0200332 options.highpass_filter = false;
deadbeef1dcb1642017-03-29 21:08:16 -0700333 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
Niels Möller2d02e082018-05-21 11:23:35 +0200334 peer_connection_factory_->CreateAudioSource(options);
deadbeef1dcb1642017-03-29 21:08:16 -0700335 // TODO(perkj): Test audio source when it is implemented. Currently audio
336 // always use the default input.
deadbeefb1a15d72017-09-07 14:12:05 -0700337 return peer_connection_factory_->CreateAudioTrack(rtc::CreateRandomUuid(),
deadbeef1dcb1642017-03-29 21:08:16 -0700338 source);
339 }
340
341 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack() {
Johannes Kron965e7942018-09-13 15:36:20 +0200342 webrtc::FakePeriodicVideoSource::Config config;
343 config.timestamp_offset_ms = rtc::TimeMillis();
344 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700345 }
346
347 rtc::scoped_refptr<webrtc::VideoTrackInterface>
Niels Möller5c7efe72018-05-11 10:34:46 +0200348 CreateLocalVideoTrackWithConfig(
349 webrtc::FakePeriodicVideoSource::Config config) {
350 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700351 }
352
353 rtc::scoped_refptr<webrtc::VideoTrackInterface>
354 CreateLocalVideoTrackWithRotation(webrtc::VideoRotation rotation) {
Niels Möller5c7efe72018-05-11 10:34:46 +0200355 webrtc::FakePeriodicVideoSource::Config config;
356 config.rotation = rotation;
Johannes Kron965e7942018-09-13 15:36:20 +0200357 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +0200358 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700359 }
360
Steve Anton74255ff2018-01-24 18:32:57 -0800361 rtc::scoped_refptr<RtpSenderInterface> AddTrack(
362 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800363 const std::vector<std::string>& stream_ids = {}) {
364 auto result = pc()->AddTrack(track, stream_ids);
Steve Anton15324772018-01-16 10:26:49 -0800365 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
Steve Anton74255ff2018-01-24 18:32:57 -0800366 return result.MoveValue();
367 }
368
369 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceiversOfType(
370 cricket::MediaType media_type) {
371 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100372 for (const auto& receiver : pc()->GetReceivers()) {
Steve Anton74255ff2018-01-24 18:32:57 -0800373 if (receiver->media_type() == media_type) {
374 receivers.push_back(receiver);
375 }
376 }
377 return receivers;
deadbeef1dcb1642017-03-29 21:08:16 -0700378 }
379
Seth Hampson2f0d7022018-02-20 11:54:42 -0800380 rtc::scoped_refptr<RtpTransceiverInterface> GetFirstTransceiverOfType(
381 cricket::MediaType media_type) {
382 for (auto transceiver : pc()->GetTransceivers()) {
383 if (transceiver->receiver()->media_type() == media_type) {
384 return transceiver;
385 }
386 }
387 return nullptr;
388 }
389
deadbeef1dcb1642017-03-29 21:08:16 -0700390 bool SignalingStateStable() {
391 return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable;
392 }
393
394 void CreateDataChannel() { CreateDataChannel(nullptr); }
395
396 void CreateDataChannel(const webrtc::DataChannelInit* init) {
Steve Antonda6c0952017-10-23 11:41:54 -0700397 CreateDataChannel(kDataChannelLabel, init);
398 }
399
400 void CreateDataChannel(const std::string& label,
401 const webrtc::DataChannelInit* init) {
402 data_channel_ = pc()->CreateDataChannel(label, init);
deadbeef1dcb1642017-03-29 21:08:16 -0700403 ASSERT_TRUE(data_channel_.get() != nullptr);
404 data_observer_.reset(new MockDataChannelObserver(data_channel_));
405 }
406
407 DataChannelInterface* data_channel() { return data_channel_; }
408 const MockDataChannelObserver* data_observer() const {
409 return data_observer_.get();
410 }
411
412 int audio_frames_received() const {
413 return fake_audio_capture_module_->frames_received();
414 }
415
416 // Takes minimum of video frames received for each track.
417 //
418 // Can be used like:
419 // EXPECT_GE(expected_frames, min_video_frames_received_per_track());
420 //
421 // To ensure that all video tracks received at least a certain number of
422 // frames.
423 int min_video_frames_received_per_track() const {
424 int min_frames = INT_MAX;
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200425 if (fake_video_renderers_.empty()) {
426 return 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700427 }
deadbeef1dcb1642017-03-29 21:08:16 -0700428
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200429 for (const auto& pair : fake_video_renderers_) {
430 min_frames = std::min(min_frames, pair.second->num_rendered_frames());
deadbeef1dcb1642017-03-29 21:08:16 -0700431 }
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200432 return min_frames;
deadbeef1dcb1642017-03-29 21:08:16 -0700433 }
434
435 // Returns a MockStatsObserver in a state after stats gathering finished,
436 // which can be used to access the gathered stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700437 rtc::scoped_refptr<MockStatsObserver> OldGetStatsForTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700438 webrtc::MediaStreamTrackInterface* track) {
439 rtc::scoped_refptr<MockStatsObserver> observer(
440 new rtc::RefCountedObject<MockStatsObserver>());
441 EXPECT_TRUE(peer_connection_->GetStats(
442 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard));
443 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
444 return observer;
445 }
446
447 // Version that doesn't take a track "filter", and gathers all stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700448 rtc::scoped_refptr<MockStatsObserver> OldGetStats() {
449 return OldGetStatsForTrack(nullptr);
450 }
451
452 // Synchronously gets stats and returns them. If it times out, fails the test
453 // and returns null.
454 rtc::scoped_refptr<const webrtc::RTCStatsReport> NewGetStats() {
455 rtc::scoped_refptr<webrtc::MockRTCStatsCollectorCallback> callback(
456 new rtc::RefCountedObject<webrtc::MockRTCStatsCollectorCallback>());
457 peer_connection_->GetStats(callback);
458 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
459 return callback->report();
deadbeef1dcb1642017-03-29 21:08:16 -0700460 }
461
462 int rendered_width() {
463 EXPECT_FALSE(fake_video_renderers_.empty());
464 return fake_video_renderers_.empty()
465 ? 0
466 : fake_video_renderers_.begin()->second->width();
467 }
468
469 int rendered_height() {
470 EXPECT_FALSE(fake_video_renderers_.empty());
471 return fake_video_renderers_.empty()
472 ? 0
473 : fake_video_renderers_.begin()->second->height();
474 }
475
476 double rendered_aspect_ratio() {
477 if (rendered_height() == 0) {
478 return 0.0;
479 }
480 return static_cast<double>(rendered_width()) / rendered_height();
481 }
482
483 webrtc::VideoRotation rendered_rotation() {
484 EXPECT_FALSE(fake_video_renderers_.empty());
485 return fake_video_renderers_.empty()
486 ? webrtc::kVideoRotation_0
487 : fake_video_renderers_.begin()->second->rotation();
488 }
489
490 int local_rendered_width() {
491 return local_video_renderer_ ? local_video_renderer_->width() : 0;
492 }
493
494 int local_rendered_height() {
495 return local_video_renderer_ ? local_video_renderer_->height() : 0;
496 }
497
498 double local_rendered_aspect_ratio() {
499 if (local_rendered_height() == 0) {
500 return 0.0;
501 }
502 return static_cast<double>(local_rendered_width()) /
503 local_rendered_height();
504 }
505
506 size_t number_of_remote_streams() {
507 if (!pc()) {
508 return 0;
509 }
510 return pc()->remote_streams()->count();
511 }
512
513 StreamCollectionInterface* remote_streams() const {
514 if (!pc()) {
515 ADD_FAILURE();
516 return nullptr;
517 }
518 return pc()->remote_streams();
519 }
520
521 StreamCollectionInterface* local_streams() {
522 if (!pc()) {
523 ADD_FAILURE();
524 return nullptr;
525 }
526 return pc()->local_streams();
527 }
528
529 webrtc::PeerConnectionInterface::SignalingState signaling_state() {
530 return pc()->signaling_state();
531 }
532
533 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() {
534 return pc()->ice_connection_state();
535 }
536
Jonas Olsson7a6739e2019-01-15 16:31:55 +0100537 webrtc::PeerConnectionInterface::IceConnectionState
538 standardized_ice_connection_state() {
539 return pc()->standardized_ice_connection_state();
540 }
541
deadbeef1dcb1642017-03-29 21:08:16 -0700542 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() {
543 return pc()->ice_gathering_state();
544 }
545
546 // Returns a MockRtpReceiverObserver for each RtpReceiver returned by
547 // GetReceivers. They're updated automatically when a remote offer/answer
548 // from the fake signaling channel is applied, or when
549 // ResetRtpReceiverObservers below is called.
550 const std::vector<std::unique_ptr<MockRtpReceiverObserver>>&
551 rtp_receiver_observers() {
552 return rtp_receiver_observers_;
553 }
554
555 void ResetRtpReceiverObservers() {
556 rtp_receiver_observers_.clear();
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100557 for (const rtc::scoped_refptr<RtpReceiverInterface>& receiver :
558 pc()->GetReceivers()) {
deadbeef1dcb1642017-03-29 21:08:16 -0700559 std::unique_ptr<MockRtpReceiverObserver> observer(
560 new MockRtpReceiverObserver(receiver->media_type()));
561 receiver->SetObserver(observer.get());
562 rtp_receiver_observers_.push_back(std::move(observer));
563 }
564 }
565
Qingsi Wangecd30542019-05-22 14:34:56 -0700566 rtc::FakeNetworkManager* network_manager() const {
Steve Antonede9ca52017-10-16 13:04:27 -0700567 return fake_network_manager_.get();
568 }
569 cricket::PortAllocator* port_allocator() const { return port_allocator_; }
570
Qingsi Wang7685e862018-06-11 20:15:46 -0700571 webrtc::FakeRtcEventLogFactory* event_log_factory() const {
572 return event_log_factory_;
573 }
574
Qingsi Wangc129c352019-04-18 10:41:58 -0700575 const cricket::Candidate& last_candidate_gathered() const {
576 return last_candidate_gathered_;
577 }
Eldar Relloda13ea22019-06-01 12:23:43 +0300578 const cricket::IceCandidateErrorEvent& error_event() const {
579 return error_event_;
580 }
Qingsi Wangc129c352019-04-18 10:41:58 -0700581
Qingsi Wangecd30542019-05-22 14:34:56 -0700582 // Sets the mDNS responder for the owned fake network manager and keeps a
583 // reference to the responder.
584 void SetMdnsResponder(
585 std::unique_ptr<webrtc::FakeMdnsResponder> mdns_responder) {
586 RTC_DCHECK(mdns_responder != nullptr);
587 mdns_responder_ = mdns_responder.get();
588 network_manager()->set_mdns_responder(std::move(mdns_responder));
589 }
590
Eldar Rello5ab79e62019-10-09 18:29:44 +0300591 // Returns null on failure.
592 std::unique_ptr<SessionDescriptionInterface> CreateOfferAndWait() {
593 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
594 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
595 pc()->CreateOffer(observer, offer_answer_options_);
596 return WaitForDescriptionFromObserver(observer);
597 }
Eldar Rellod9ebe012020-03-18 20:41:45 +0200598 bool Rollback() {
599 return SetRemoteDescription(
600 webrtc::CreateSessionDescription(SdpType::kRollback, ""));
601 }
Eldar Rello5ab79e62019-10-09 18:29:44 +0300602
Harald Alvestrandcc6ae442021-01-18 08:06:23 +0000603 // Functions for querying stats.
604 void StartWatchingDelayStats() {
605 // Get the baseline numbers for audio_packets and audio_delay.
606 auto received_stats = NewGetStats();
607 auto track_stats =
608 received_stats->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>()[0];
609 ASSERT_TRUE(track_stats->relative_packet_arrival_delay.is_defined());
610 auto rtp_stats =
611 received_stats->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>()[0];
612 ASSERT_TRUE(rtp_stats->packets_received.is_defined());
613 ASSERT_TRUE(rtp_stats->track_id.is_defined());
614 audio_track_stats_id_ = track_stats->id();
615 ASSERT_TRUE(received_stats->Get(audio_track_stats_id_));
616 rtp_stats_id_ = rtp_stats->id();
617 ASSERT_EQ(audio_track_stats_id_, *rtp_stats->track_id);
618 audio_packets_stat_ = *rtp_stats->packets_received;
619 audio_delay_stat_ = *track_stats->relative_packet_arrival_delay;
620 }
621
622 void UpdateDelayStats(std::string tag, int desc_size) {
623 auto report = NewGetStats();
624 auto track_stats =
625 report->GetAs<webrtc::RTCMediaStreamTrackStats>(audio_track_stats_id_);
626 ASSERT_TRUE(track_stats);
627 auto rtp_stats =
628 report->GetAs<webrtc::RTCInboundRTPStreamStats>(rtp_stats_id_);
629 ASSERT_TRUE(rtp_stats);
630 auto delta_packets = *rtp_stats->packets_received - audio_packets_stat_;
631 auto delta_rpad =
632 *track_stats->relative_packet_arrival_delay - audio_delay_stat_;
633 auto recent_delay = delta_packets > 0 ? delta_rpad / delta_packets : -1;
634 // An average relative packet arrival delay over the renegotiation of
635 // > 100 ms indicates that something is dramatically wrong, and will impact
636 // quality for sure.
637 ASSERT_GT(0.1, recent_delay) << tag << " size " << desc_size;
638 // Increment trailing counters
639 audio_packets_stat_ = *rtp_stats->packets_received;
640 audio_delay_stat_ = *track_stats->relative_packet_arrival_delay;
641 }
642
deadbeef1dcb1642017-03-29 21:08:16 -0700643 private:
644 explicit PeerConnectionWrapper(const std::string& debug_name)
645 : debug_name_(debug_name) {}
646
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800647 bool Init(
648 const PeerConnectionFactory::Options* options,
649 const PeerConnectionInterface::RTCConfiguration* config,
650 webrtc::PeerConnectionDependencies dependencies,
651 rtc::Thread* network_thread,
652 rtc::Thread* worker_thread,
653 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory,
Johannes Kron3e983682020-03-29 22:17:00 +0200654 bool reset_encoder_factory,
655 bool reset_decoder_factory) {
deadbeef1dcb1642017-03-29 21:08:16 -0700656 // There's an error in this test code if Init ends up being called twice.
657 RTC_DCHECK(!peer_connection_);
658 RTC_DCHECK(!peer_connection_factory_);
659
660 fake_network_manager_.reset(new rtc::FakeNetworkManager());
Steve Antonede9ca52017-10-16 13:04:27 -0700661 fake_network_manager_->AddInterface(kDefaultLocalAddress);
deadbeef1dcb1642017-03-29 21:08:16 -0700662
663 std::unique_ptr<cricket::PortAllocator> port_allocator(
664 new cricket::BasicPortAllocator(fake_network_manager_.get()));
Steve Antonede9ca52017-10-16 13:04:27 -0700665 port_allocator_ = port_allocator.get();
deadbeef1dcb1642017-03-29 21:08:16 -0700666 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
667 if (!fake_audio_capture_module_) {
668 return false;
669 }
deadbeef1dcb1642017-03-29 21:08:16 -0700670 rtc::Thread* const signaling_thread = rtc::Thread::Current();
Qingsi Wang7685e862018-06-11 20:15:46 -0700671
672 webrtc::PeerConnectionFactoryDependencies pc_factory_dependencies;
673 pc_factory_dependencies.network_thread = network_thread;
674 pc_factory_dependencies.worker_thread = worker_thread;
675 pc_factory_dependencies.signaling_thread = signaling_thread;
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200676 pc_factory_dependencies.task_queue_factory =
677 webrtc::CreateDefaultTaskQueueFactory();
Erik Språngceb44952020-09-22 11:36:35 +0200678 pc_factory_dependencies.trials = std::make_unique<FieldTrialBasedConfig>();
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200679 cricket::MediaEngineDependencies media_deps;
680 media_deps.task_queue_factory =
681 pc_factory_dependencies.task_queue_factory.get();
682 media_deps.adm = fake_audio_capture_module_;
683 webrtc::SetMediaEngineDefaults(&media_deps);
Johannes Kron3e983682020-03-29 22:17:00 +0200684
685 if (reset_encoder_factory) {
686 media_deps.video_encoder_factory.reset();
687 }
688 if (reset_decoder_factory) {
689 media_deps.video_decoder_factory.reset();
690 }
691
Per Åhgrencc73ed32020-04-26 23:56:17 +0200692 if (!media_deps.audio_processing) {
693 // If the standard Creation method for APM returns a null pointer, instead
694 // use the builder for testing to create an APM object.
695 media_deps.audio_processing = AudioProcessingBuilderForTesting().Create();
696 }
697
Erik Språngceb44952020-09-22 11:36:35 +0200698 media_deps.trials = pc_factory_dependencies.trials.get();
699
Qingsi Wang7685e862018-06-11 20:15:46 -0700700 pc_factory_dependencies.media_engine =
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200701 cricket::CreateMediaEngine(std::move(media_deps));
Qingsi Wang7685e862018-06-11 20:15:46 -0700702 pc_factory_dependencies.call_factory = webrtc::CreateCallFactory();
703 if (event_log_factory) {
704 event_log_factory_ = event_log_factory.get();
705 pc_factory_dependencies.event_log_factory = std::move(event_log_factory);
706 } else {
707 pc_factory_dependencies.event_log_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200708 std::make_unique<webrtc::RtcEventLogFactory>(
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200709 pc_factory_dependencies.task_queue_factory.get());
Qingsi Wang7685e862018-06-11 20:15:46 -0700710 }
711 peer_connection_factory_ = webrtc::CreateModularPeerConnectionFactory(
712 std::move(pc_factory_dependencies));
713
deadbeef1dcb1642017-03-29 21:08:16 -0700714 if (!peer_connection_factory_) {
715 return false;
716 }
717 if (options) {
718 peer_connection_factory_->SetOptions(*options);
719 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800720 if (config) {
721 sdp_semantics_ = config->sdp_semantics;
722 }
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700723
724 dependencies.allocator = std::move(port_allocator);
Niels Möllerf06f9232018-08-07 12:32:18 +0200725 peer_connection_ = CreatePeerConnection(config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700726 return peer_connection_.get() != nullptr;
727 }
728
729 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(
deadbeef1dcb1642017-03-29 21:08:16 -0700730 const PeerConnectionInterface::RTCConfiguration* config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700731 webrtc::PeerConnectionDependencies dependencies) {
deadbeef1dcb1642017-03-29 21:08:16 -0700732 PeerConnectionInterface::RTCConfiguration modified_config;
733 // If |config| is null, this will result in a default configuration being
734 // used.
735 if (config) {
736 modified_config = *config;
737 }
738 // Disable resolution adaptation; we don't want it interfering with the
739 // test results.
740 // TODO(deadbeef): Do something more robust. Since we're testing for aspect
741 // ratios and not specific resolutions, is this even necessary?
742 modified_config.set_cpu_adaptation(false);
743
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700744 dependencies.observer = this;
deadbeef1dcb1642017-03-29 21:08:16 -0700745 return peer_connection_factory_->CreatePeerConnection(
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700746 modified_config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700747 }
748
749 void set_signaling_message_receiver(
750 SignalingMessageReceiver* signaling_message_receiver) {
751 signaling_message_receiver_ = signaling_message_receiver;
752 }
753
754 void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; }
755
Steve Antonede9ca52017-10-16 13:04:27 -0700756 void set_signal_ice_candidates(bool signal) {
757 signal_ice_candidates_ = signal;
758 }
759
deadbeef1dcb1642017-03-29 21:08:16 -0700760 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
Niels Möller5c7efe72018-05-11 10:34:46 +0200761 webrtc::FakePeriodicVideoSource::Config config) {
deadbeef1dcb1642017-03-29 21:08:16 -0700762 // Set max frame rate to 10fps to reduce the risk of test flakiness.
763 // TODO(deadbeef): Do something more robust.
Niels Möller5c7efe72018-05-11 10:34:46 +0200764 config.frame_interval_ms = 100;
deadbeef1dcb1642017-03-29 21:08:16 -0700765
Niels Möller5c7efe72018-05-11 10:34:46 +0200766 video_track_sources_.emplace_back(
Niels Möller0f405822018-05-17 09:16:41 +0200767 new rtc::RefCountedObject<webrtc::FakePeriodicVideoTrackSource>(
768 config, false /* remote */));
deadbeef1dcb1642017-03-29 21:08:16 -0700769 rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
Niels Möller5c7efe72018-05-11 10:34:46 +0200770 peer_connection_factory_->CreateVideoTrack(
771 rtc::CreateRandomUuid(), video_track_sources_.back()));
deadbeef1dcb1642017-03-29 21:08:16 -0700772 if (!local_video_renderer_) {
773 local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
774 }
775 return track;
776 }
777
778 void HandleIncomingOffer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100779 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer";
Steve Antona3a92c22017-12-07 10:27:41 -0800780 std::unique_ptr<SessionDescriptionInterface> desc =
781 webrtc::CreateSessionDescription(SdpType::kOffer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700782 if (received_sdp_munger_) {
783 received_sdp_munger_(desc->description());
784 }
785
786 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
787 // Setting a remote description may have changed the number of receivers,
788 // so reset the receiver observers.
789 ResetRtpReceiverObservers();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800790 if (remote_offer_handler_) {
791 remote_offer_handler_();
792 }
deadbeef1dcb1642017-03-29 21:08:16 -0700793 auto answer = CreateAnswer();
794 ASSERT_NE(nullptr, answer);
795 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
796 }
797
798 void HandleIncomingAnswer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100799 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
Steve Antona3a92c22017-12-07 10:27:41 -0800800 std::unique_ptr<SessionDescriptionInterface> desc =
801 webrtc::CreateSessionDescription(SdpType::kAnswer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700802 if (received_sdp_munger_) {
803 received_sdp_munger_(desc->description());
804 }
805
806 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
807 // Set the RtpReceiverObserver after receivers are created.
808 ResetRtpReceiverObservers();
809 }
810
811 // Returns null on failure.
deadbeef1dcb1642017-03-29 21:08:16 -0700812 std::unique_ptr<SessionDescriptionInterface> CreateAnswer() {
813 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
814 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
815 pc()->CreateAnswer(observer, offer_answer_options_);
816 return WaitForDescriptionFromObserver(observer);
817 }
818
819 std::unique_ptr<SessionDescriptionInterface> WaitForDescriptionFromObserver(
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100820 MockCreateSessionDescriptionObserver* observer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700821 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
822 if (!observer->result()) {
823 return nullptr;
824 }
825 auto description = observer->MoveDescription();
826 if (generated_sdp_munger_) {
827 generated_sdp_munger_(description->description());
828 }
829 return description;
830 }
831
832 // Setting the local description and sending the SDP message over the fake
833 // signaling channel are combined into the same method because the SDP
834 // message needs to be sent as soon as SetLocalDescription finishes, without
835 // waiting for the observer to be called. This ensures that ICE candidates
836 // don't outrace the description.
837 bool SetLocalDescriptionAndSendSdpMessage(
838 std::unique_ptr<SessionDescriptionInterface> desc) {
839 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
840 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100841 RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage";
Steve Antona3a92c22017-12-07 10:27:41 -0800842 SdpType type = desc->GetType();
deadbeef1dcb1642017-03-29 21:08:16 -0700843 std::string sdp;
844 EXPECT_TRUE(desc->ToString(&sdp));
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700845 RTC_LOG(LS_INFO) << debug_name_ << ": local SDP contents=\n" << sdp;
deadbeef1dcb1642017-03-29 21:08:16 -0700846 pc()->SetLocalDescription(observer, desc.release());
Harald Alvestrand6060df52020-08-11 09:54:02 +0200847 RemoveUnusedVideoRenderers();
deadbeef1dcb1642017-03-29 21:08:16 -0700848 // As mentioned above, we need to send the message immediately after
849 // SetLocalDescription.
850 SendSdpMessage(type, sdp);
851 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
852 return true;
853 }
854
855 bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
856 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
857 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100858 RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription";
deadbeef1dcb1642017-03-29 21:08:16 -0700859 pc()->SetRemoteDescription(observer, desc.release());
Harald Alvestrand6060df52020-08-11 09:54:02 +0200860 RemoveUnusedVideoRenderers();
deadbeef1dcb1642017-03-29 21:08:16 -0700861 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
862 return observer->result();
863 }
864
Seth Hampson2f0d7022018-02-20 11:54:42 -0800865 // This is a work around to remove unused fake_video_renderers from
866 // transceivers that have either stopped or are no longer receiving.
867 void RemoveUnusedVideoRenderers() {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200868 if (sdp_semantics_ != SdpSemantics::kUnifiedPlan) {
869 return;
870 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800871 auto transceivers = pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +0200872 std::set<std::string> active_renderers;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800873 for (auto& transceiver : transceivers) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200874 // Note - we don't check for direction here. This function is called
875 // before direction is set, and in that case, we should not remove
876 // the renderer.
877 if (transceiver->receiver()->media_type() == cricket::MEDIA_TYPE_VIDEO) {
878 active_renderers.insert(transceiver->receiver()->track()->id());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800879 }
Harald Alvestrand6060df52020-08-11 09:54:02 +0200880 }
881 for (auto it = fake_video_renderers_.begin();
882 it != fake_video_renderers_.end();) {
883 // Remove fake video renderers belonging to any non-active transceivers.
884 if (!active_renderers.count(it->first)) {
885 it = fake_video_renderers_.erase(it);
886 } else {
887 it++;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800888 }
889 }
890 }
891
deadbeef1dcb1642017-03-29 21:08:16 -0700892 // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by
893 // default).
Steve Antona3a92c22017-12-07 10:27:41 -0800894 void SendSdpMessage(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700895 if (signaling_delay_ms_ == 0) {
896 RelaySdpMessageIfReceiverExists(type, msg);
897 } else {
898 invoker_.AsyncInvokeDelayed<void>(
899 RTC_FROM_HERE, rtc::Thread::Current(),
Niels Möller4bab23f2021-01-18 09:24:33 +0100900 [this, type, msg] { RelaySdpMessageIfReceiverExists(type, msg); },
deadbeef1dcb1642017-03-29 21:08:16 -0700901 signaling_delay_ms_);
902 }
903 }
904
Steve Antona3a92c22017-12-07 10:27:41 -0800905 void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700906 if (signaling_message_receiver_) {
907 signaling_message_receiver_->ReceiveSdpMessage(type, msg);
908 }
909 }
910
911 // Simulate trickling an ICE candidate with delay |signaling_delay_ms_| (0 by
912 // default).
913 void SendIceMessage(const std::string& sdp_mid,
914 int sdp_mline_index,
915 const std::string& msg) {
916 if (signaling_delay_ms_ == 0) {
917 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
918 } else {
919 invoker_.AsyncInvokeDelayed<void>(
920 RTC_FROM_HERE, rtc::Thread::Current(),
Niels Möller4bab23f2021-01-18 09:24:33 +0100921 [this, sdp_mid, sdp_mline_index, msg] {
922 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
923 },
deadbeef1dcb1642017-03-29 21:08:16 -0700924 signaling_delay_ms_);
925 }
926 }
927
928 void RelayIceMessageIfReceiverExists(const std::string& sdp_mid,
929 int sdp_mline_index,
930 const std::string& msg) {
931 if (signaling_message_receiver_) {
932 signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index,
933 msg);
934 }
935 }
936
937 // SignalingMessageReceiver callbacks.
Steve Antona3a92c22017-12-07 10:27:41 -0800938 void ReceiveSdpMessage(SdpType type, const std::string& msg) override {
939 if (type == SdpType::kOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700940 HandleIncomingOffer(msg);
941 } else {
942 HandleIncomingAnswer(msg);
943 }
944 }
945
946 void ReceiveIceMessage(const std::string& sdp_mid,
947 int sdp_mline_index,
948 const std::string& msg) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100949 RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage";
deadbeef1dcb1642017-03-29 21:08:16 -0700950 std::unique_ptr<webrtc::IceCandidateInterface> candidate(
951 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr));
952 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
953 }
954
955 // PeerConnectionObserver callbacks.
956 void OnSignalingChange(
957 webrtc::PeerConnectionInterface::SignalingState new_state) override {
958 EXPECT_EQ(pc()->signaling_state(), new_state);
Eldar Rello5ab79e62019-10-09 18:29:44 +0300959 peer_connection_signaling_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700960 }
Steve Anton15324772018-01-16 10:26:49 -0800961 void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
962 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
963 streams) override {
964 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
965 rtc::scoped_refptr<VideoTrackInterface> video_track(
966 static_cast<VideoTrackInterface*>(receiver->track().get()));
967 ASSERT_TRUE(fake_video_renderers_.find(video_track->id()) ==
deadbeef1dcb1642017-03-29 21:08:16 -0700968 fake_video_renderers_.end());
Steve Anton15324772018-01-16 10:26:49 -0800969 fake_video_renderers_[video_track->id()] =
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200970 std::make_unique<FakeVideoTrackRenderer>(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -0700971 }
972 }
Steve Anton15324772018-01-16 10:26:49 -0800973 void OnRemoveTrack(
974 rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
975 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
976 auto it = fake_video_renderers_.find(receiver->track()->id());
Harald Alvestrand6060df52020-08-11 09:54:02 +0200977 if (it != fake_video_renderers_.end()) {
978 fake_video_renderers_.erase(it);
979 } else {
980 RTC_LOG(LS_ERROR) << "OnRemoveTrack called for non-active renderer";
981 }
Steve Anton15324772018-01-16 10:26:49 -0800982 }
983 }
deadbeef1dcb1642017-03-29 21:08:16 -0700984 void OnRenegotiationNeeded() override {}
985 void OnIceConnectionChange(
986 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
987 EXPECT_EQ(pc()->ice_connection_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700988 ice_connection_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700989 }
Jonas Olssonacd8ae72019-02-25 15:26:24 +0100990 void OnStandardizedIceConnectionChange(
991 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
992 standardized_ice_connection_state_history_.push_back(new_state);
993 }
Jonas Olsson635474e2018-10-18 15:58:17 +0200994 void OnConnectionChange(
995 webrtc::PeerConnectionInterface::PeerConnectionState new_state) override {
996 peer_connection_state_history_.push_back(new_state);
997 }
998
deadbeef1dcb1642017-03-29 21:08:16 -0700999 void OnIceGatheringChange(
1000 webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
deadbeef1dcb1642017-03-29 21:08:16 -07001001 EXPECT_EQ(pc()->ice_gathering_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -07001002 ice_gathering_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -07001003 }
Alex Drake00c7ecf2019-08-06 10:54:47 -07001004
1005 void OnIceSelectedCandidatePairChanged(
1006 const cricket::CandidatePairChangeEvent& event) {
1007 ice_candidate_pair_change_history_.push_back(event);
1008 }
Alex Drake43faee02019-08-12 16:27:34 -07001009
deadbeef1dcb1642017-03-29 21:08:16 -07001010 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001011 RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate";
deadbeef1dcb1642017-03-29 21:08:16 -07001012
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001013 if (remote_async_resolver_) {
1014 const auto& local_candidate = candidate->candidate();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001015 if (local_candidate.address().IsUnresolvedIP()) {
1016 RTC_DCHECK(local_candidate.type() == cricket::LOCAL_PORT_TYPE);
1017 rtc::SocketAddress resolved_addr(local_candidate.address());
Qingsi Wangecd30542019-05-22 14:34:56 -07001018 const auto resolved_ip = mdns_responder_->GetMappedAddressForName(
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001019 local_candidate.address().hostname());
1020 RTC_DCHECK(!resolved_ip.IsNil());
1021 resolved_addr.SetResolvedIP(resolved_ip);
1022 EXPECT_CALL(*remote_async_resolver_, GetResolvedAddress(_, _))
1023 .WillOnce(DoAll(SetArgPointee<1>(resolved_addr), Return(true)));
1024 EXPECT_CALL(*remote_async_resolver_, Destroy(_));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001025 }
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001026 }
1027
deadbeef1dcb1642017-03-29 21:08:16 -07001028 std::string ice_sdp;
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001029 EXPECT_TRUE(candidate->ToString(&ice_sdp));
Steve Antonede9ca52017-10-16 13:04:27 -07001030 if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) {
deadbeef1dcb1642017-03-29 21:08:16 -07001031 // Remote party may be deleted.
1032 return;
1033 }
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001034 SendIceMessage(candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp);
Qingsi Wangc129c352019-04-18 10:41:58 -07001035 last_candidate_gathered_ = candidate->candidate();
deadbeef1dcb1642017-03-29 21:08:16 -07001036 }
Eldar Rello0095d372019-12-02 22:22:07 +02001037 void OnIceCandidateError(const std::string& address,
1038 int port,
Eldar Relloda13ea22019-06-01 12:23:43 +03001039 const std::string& url,
1040 int error_code,
1041 const std::string& error_text) override {
Eldar Rello0095d372019-12-02 22:22:07 +02001042 error_event_ = cricket::IceCandidateErrorEvent(address, port, url,
Eldar Relloda13ea22019-06-01 12:23:43 +03001043 error_code, error_text);
1044 }
deadbeef1dcb1642017-03-29 21:08:16 -07001045 void OnDataChannel(
1046 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001047 RTC_LOG(LS_INFO) << debug_name_ << ": OnDataChannel";
deadbeef1dcb1642017-03-29 21:08:16 -07001048 data_channel_ = data_channel;
1049 data_observer_.reset(new MockDataChannelObserver(data_channel));
1050 }
1051
deadbeef1dcb1642017-03-29 21:08:16 -07001052 std::string debug_name_;
1053
1054 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
Qingsi Wangecd30542019-05-22 14:34:56 -07001055 // Reference to the mDNS responder owned by |fake_network_manager_| after set.
1056 webrtc::FakeMdnsResponder* mdns_responder_ = nullptr;
deadbeef1dcb1642017-03-29 21:08:16 -07001057
1058 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
1059 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
1060 peer_connection_factory_;
1061
Steve Antonede9ca52017-10-16 13:04:27 -07001062 cricket::PortAllocator* port_allocator_;
deadbeef1dcb1642017-03-29 21:08:16 -07001063 // Needed to keep track of number of frames sent.
1064 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
1065 // Needed to keep track of number of frames received.
1066 std::map<std::string, std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
1067 fake_video_renderers_;
1068 // Needed to ensure frames aren't received for removed tracks.
1069 std::vector<std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
1070 removed_fake_video_renderers_;
deadbeef1dcb1642017-03-29 21:08:16 -07001071
1072 // For remote peer communication.
1073 SignalingMessageReceiver* signaling_message_receiver_ = nullptr;
1074 int signaling_delay_ms_ = 0;
Steve Antonede9ca52017-10-16 13:04:27 -07001075 bool signal_ice_candidates_ = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07001076 cricket::Candidate last_candidate_gathered_;
Eldar Relloda13ea22019-06-01 12:23:43 +03001077 cricket::IceCandidateErrorEvent error_event_;
deadbeef1dcb1642017-03-29 21:08:16 -07001078
Niels Möller5c7efe72018-05-11 10:34:46 +02001079 // Store references to the video sources we've created, so that we can stop
deadbeef1dcb1642017-03-29 21:08:16 -07001080 // them, if required.
Niels Möller5c7efe72018-05-11 10:34:46 +02001081 std::vector<rtc::scoped_refptr<webrtc::VideoTrackSource>>
1082 video_track_sources_;
deadbeef1dcb1642017-03-29 21:08:16 -07001083 // |local_video_renderer_| attached to the first created local video track.
1084 std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
1085
Seth Hampson2f0d7022018-02-20 11:54:42 -08001086 SdpSemantics sdp_semantics_;
deadbeef1dcb1642017-03-29 21:08:16 -07001087 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_;
1088 std::function<void(cricket::SessionDescription*)> received_sdp_munger_;
1089 std::function<void(cricket::SessionDescription*)> generated_sdp_munger_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001090 std::function<void()> remote_offer_handler_;
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001091 rtc::MockAsyncResolver* remote_async_resolver_ = nullptr;
deadbeef1dcb1642017-03-29 21:08:16 -07001092 rtc::scoped_refptr<DataChannelInterface> data_channel_;
1093 std::unique_ptr<MockDataChannelObserver> data_observer_;
1094
1095 std::vector<std::unique_ptr<MockRtpReceiverObserver>> rtp_receiver_observers_;
1096
Steve Antonede9ca52017-10-16 13:04:27 -07001097 std::vector<PeerConnectionInterface::IceConnectionState>
1098 ice_connection_state_history_;
Jonas Olssonacd8ae72019-02-25 15:26:24 +01001099 std::vector<PeerConnectionInterface::IceConnectionState>
1100 standardized_ice_connection_state_history_;
Jonas Olsson635474e2018-10-18 15:58:17 +02001101 std::vector<PeerConnectionInterface::PeerConnectionState>
1102 peer_connection_state_history_;
Steve Antonede9ca52017-10-16 13:04:27 -07001103 std::vector<PeerConnectionInterface::IceGatheringState>
1104 ice_gathering_state_history_;
Alex Drake00c7ecf2019-08-06 10:54:47 -07001105 std::vector<cricket::CandidatePairChangeEvent>
1106 ice_candidate_pair_change_history_;
Eldar Rello5ab79e62019-10-09 18:29:44 +03001107 std::vector<PeerConnectionInterface::SignalingState>
1108 peer_connection_signaling_state_history_;
Qingsi Wang7685e862018-06-11 20:15:46 -07001109 webrtc::FakeRtcEventLogFactory* event_log_factory_;
1110
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00001111 // Variables for tracking delay stats on an audio track
1112 int audio_packets_stat_ = 0;
1113 double audio_delay_stat_ = 0.0;
1114 std::string rtp_stats_id_;
1115 std::string audio_track_stats_id_;
1116
deadbeef1dcb1642017-03-29 21:08:16 -07001117 rtc::AsyncInvoker invoker_;
1118
Seth Hampson2f0d7022018-02-20 11:54:42 -08001119 friend class PeerConnectionIntegrationBaseTest;
deadbeef1dcb1642017-03-29 21:08:16 -07001120};
1121
Elad Alon99c3fe52017-10-13 16:29:40 +02001122class MockRtcEventLogOutput : public webrtc::RtcEventLogOutput {
1123 public:
1124 virtual ~MockRtcEventLogOutput() = default;
Danil Chapovalov3a353122020-05-15 11:16:53 +02001125 MOCK_METHOD(bool, IsActive, (), (const, override));
1126 MOCK_METHOD(bool, Write, (const std::string&), (override));
Elad Alon99c3fe52017-10-13 16:29:40 +02001127};
1128
Seth Hampson2f0d7022018-02-20 11:54:42 -08001129// This helper object is used for both specifying how many audio/video frames
1130// are expected to be received for a caller/callee. It provides helper functions
1131// to specify these expectations. The object initially starts in a state of no
1132// expectations.
1133class MediaExpectations {
1134 public:
1135 enum ExpectFrames {
1136 kExpectSomeFrames,
1137 kExpectNoFrames,
1138 kNoExpectation,
1139 };
1140
1141 void ExpectBidirectionalAudioAndVideo() {
1142 ExpectBidirectionalAudio();
1143 ExpectBidirectionalVideo();
1144 }
1145
1146 void ExpectBidirectionalAudio() {
1147 CallerExpectsSomeAudio();
1148 CalleeExpectsSomeAudio();
1149 }
1150
1151 void ExpectNoAudio() {
1152 CallerExpectsNoAudio();
1153 CalleeExpectsNoAudio();
1154 }
1155
1156 void ExpectBidirectionalVideo() {
1157 CallerExpectsSomeVideo();
1158 CalleeExpectsSomeVideo();
1159 }
1160
1161 void ExpectNoVideo() {
1162 CallerExpectsNoVideo();
1163 CalleeExpectsNoVideo();
1164 }
1165
1166 void CallerExpectsSomeAudioAndVideo() {
1167 CallerExpectsSomeAudio();
1168 CallerExpectsSomeVideo();
1169 }
1170
1171 void CalleeExpectsSomeAudioAndVideo() {
1172 CalleeExpectsSomeAudio();
1173 CalleeExpectsSomeVideo();
1174 }
1175
1176 // Caller's audio functions.
1177 void CallerExpectsSomeAudio(
1178 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1179 caller_audio_expectation_ = kExpectSomeFrames;
1180 caller_audio_frames_expected_ = expected_audio_frames;
1181 }
1182
1183 void CallerExpectsNoAudio() {
1184 caller_audio_expectation_ = kExpectNoFrames;
1185 caller_audio_frames_expected_ = 0;
1186 }
1187
1188 // Caller's video functions.
1189 void CallerExpectsSomeVideo(
1190 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1191 caller_video_expectation_ = kExpectSomeFrames;
1192 caller_video_frames_expected_ = expected_video_frames;
1193 }
1194
1195 void CallerExpectsNoVideo() {
1196 caller_video_expectation_ = kExpectNoFrames;
1197 caller_video_frames_expected_ = 0;
1198 }
1199
1200 // Callee's audio functions.
1201 void CalleeExpectsSomeAudio(
1202 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1203 callee_audio_expectation_ = kExpectSomeFrames;
1204 callee_audio_frames_expected_ = expected_audio_frames;
1205 }
1206
1207 void CalleeExpectsNoAudio() {
1208 callee_audio_expectation_ = kExpectNoFrames;
1209 callee_audio_frames_expected_ = 0;
1210 }
1211
1212 // Callee's video functions.
1213 void CalleeExpectsSomeVideo(
1214 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1215 callee_video_expectation_ = kExpectSomeFrames;
1216 callee_video_frames_expected_ = expected_video_frames;
1217 }
1218
1219 void CalleeExpectsNoVideo() {
1220 callee_video_expectation_ = kExpectNoFrames;
1221 callee_video_frames_expected_ = 0;
1222 }
1223
1224 ExpectFrames caller_audio_expectation_ = kNoExpectation;
1225 ExpectFrames caller_video_expectation_ = kNoExpectation;
1226 ExpectFrames callee_audio_expectation_ = kNoExpectation;
1227 ExpectFrames callee_video_expectation_ = kNoExpectation;
1228 int caller_audio_frames_expected_ = 0;
1229 int caller_video_frames_expected_ = 0;
1230 int callee_audio_frames_expected_ = 0;
1231 int callee_video_frames_expected_ = 0;
1232};
1233
Qingsi Wang25ec8882019-11-15 12:33:05 -08001234class MockIceTransport : public webrtc::IceTransportInterface {
1235 public:
1236 MockIceTransport(const std::string& name, int component)
1237 : internal_(std::make_unique<cricket::FakeIceTransport>(
1238 name,
1239 component,
1240 nullptr /* network_thread */)) {}
1241 ~MockIceTransport() = default;
1242 cricket::IceTransportInternal* internal() { return internal_.get(); }
1243
1244 private:
1245 std::unique_ptr<cricket::FakeIceTransport> internal_;
1246};
1247
1248class MockIceTransportFactory : public IceTransportFactory {
1249 public:
1250 ~MockIceTransportFactory() override = default;
1251 rtc::scoped_refptr<IceTransportInterface> CreateIceTransport(
1252 const std::string& transport_name,
1253 int component,
1254 IceTransportInit init) {
1255 RecordIceTransportCreated();
1256 return new rtc::RefCountedObject<MockIceTransport>(transport_name,
1257 component);
1258 }
Danil Chapovalov3a353122020-05-15 11:16:53 +02001259 MOCK_METHOD(void, RecordIceTransportCreated, ());
Qingsi Wang25ec8882019-11-15 12:33:05 -08001260};
1261
deadbeef1dcb1642017-03-29 21:08:16 -07001262// Tests two PeerConnections connecting to each other end-to-end, using a
1263// virtual network, fake A/V capture and fake encoder/decoders. The
1264// PeerConnections share the threads/socket servers, but use separate versions
1265// of everything else (including "PeerConnectionFactory"s).
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001266class PeerConnectionIntegrationBaseTest : public ::testing::Test {
deadbeef1dcb1642017-03-29 21:08:16 -07001267 public:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001268 explicit PeerConnectionIntegrationBaseTest(SdpSemantics sdp_semantics)
1269 : sdp_semantics_(sdp_semantics),
1270 ss_(new rtc::VirtualSocketServer()),
Steve Antonede9ca52017-10-16 13:04:27 -07001271 fss_(new rtc::FirewallSocketServer(ss_.get())),
1272 network_thread_(new rtc::Thread(fss_.get())),
Niels Möller2a707032020-06-16 16:39:13 +02001273 worker_thread_(rtc::Thread::Create()) {
Sebastian Jansson8a793a02018-03-13 15:21:48 +01001274 network_thread_->SetName("PCNetworkThread", this);
1275 worker_thread_->SetName("PCWorkerThread", this);
deadbeef1dcb1642017-03-29 21:08:16 -07001276 RTC_CHECK(network_thread_->Start());
1277 RTC_CHECK(worker_thread_->Start());
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001278 webrtc::metrics::Reset();
deadbeef1dcb1642017-03-29 21:08:16 -07001279 }
1280
Seth Hampson2f0d7022018-02-20 11:54:42 -08001281 ~PeerConnectionIntegrationBaseTest() {
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00001282 // The PeerConnections should be deleted before the TurnCustomizers.
Seth Hampsonaed71642018-06-11 07:41:32 -07001283 // A TurnPort is created with a raw pointer to a TurnCustomizer. The
1284 // TurnPort has the same lifetime as the PeerConnection, so it's expected
1285 // that the TurnCustomizer outlives the life of the PeerConnection or else
1286 // when Send() is called it will hit a seg fault.
deadbeef1dcb1642017-03-29 21:08:16 -07001287 if (caller_) {
1288 caller_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001289 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001290 }
1291 if (callee_) {
1292 callee_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001293 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001294 }
Seth Hampsonaed71642018-06-11 07:41:32 -07001295
1296 // If turn servers were created for the test they need to be destroyed on
1297 // the network thread.
1298 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
1299 turn_servers_.clear();
1300 turn_customizers_.clear();
1301 });
deadbeef1dcb1642017-03-29 21:08:16 -07001302 }
1303
1304 bool SignalingStateStable() {
1305 return caller_->SignalingStateStable() && callee_->SignalingStateStable();
1306 }
1307
deadbeef71452802017-05-07 17:21:01 -07001308 bool DtlsConnected() {
Alex Loiko9289eda2018-11-23 16:18:59 +00001309 // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS
1310 // are connected. This is an important distinction. Once we have separate
1311 // ICE and DTLS state, this check needs to use the DTLS state.
1312 return (callee()->ice_connection_state() ==
1313 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1314 callee()->ice_connection_state() ==
1315 webrtc::PeerConnectionInterface::kIceConnectionCompleted) &&
1316 (caller()->ice_connection_state() ==
1317 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1318 caller()->ice_connection_state() ==
1319 webrtc::PeerConnectionInterface::kIceConnectionCompleted);
deadbeef71452802017-05-07 17:21:01 -07001320 }
1321
Qingsi Wang7685e862018-06-11 20:15:46 -07001322 // When |event_log_factory| is null, the default implementation of the event
1323 // log factory will be used.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001324 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWrapper(
1325 const std::string& debug_name,
Seth Hampson2f0d7022018-02-20 11:54:42 -08001326 const PeerConnectionFactory::Options* options,
1327 const RTCConfiguration* config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001328 webrtc::PeerConnectionDependencies dependencies,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001329 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory,
Johannes Kron3e983682020-03-29 22:17:00 +02001330 bool reset_encoder_factory,
1331 bool reset_decoder_factory) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001332 RTCConfiguration modified_config;
1333 if (config) {
1334 modified_config = *config;
1335 }
Steve Anton3acffc32018-04-12 17:21:03 -07001336 modified_config.sdp_semantics = sdp_semantics_;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001337 if (!dependencies.cert_generator) {
1338 dependencies.cert_generator =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001339 std::make_unique<FakeRTCCertificateGenerator>();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001340 }
1341 std::unique_ptr<PeerConnectionWrapper> client(
1342 new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001343
Niels Möllerf06f9232018-08-07 12:32:18 +02001344 if (!client->Init(options, &modified_config, std::move(dependencies),
1345 network_thread_.get(), worker_thread_.get(),
Niels Möller2a707032020-06-16 16:39:13 +02001346 std::move(event_log_factory), reset_encoder_factory,
Johannes Kron3e983682020-03-29 22:17:00 +02001347 reset_decoder_factory)) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001348 return nullptr;
1349 }
1350 return client;
1351 }
1352
Qingsi Wang7685e862018-06-11 20:15:46 -07001353 std::unique_ptr<PeerConnectionWrapper>
1354 CreatePeerConnectionWrapperWithFakeRtcEventLog(
1355 const std::string& debug_name,
Qingsi Wang7685e862018-06-11 20:15:46 -07001356 const PeerConnectionFactory::Options* options,
1357 const RTCConfiguration* config,
1358 webrtc::PeerConnectionDependencies dependencies) {
Danil Chapovalov4f281f12021-01-18 13:29:00 +01001359 return CreatePeerConnectionWrapper(
1360 debug_name, options, config, std::move(dependencies),
1361 std::make_unique<webrtc::FakeRtcEventLogFactory>(),
1362 /*reset_encoder_factory=*/false,
1363 /*reset_decoder_factory=*/false);
Qingsi Wang7685e862018-06-11 20:15:46 -07001364 }
1365
deadbeef1dcb1642017-03-29 21:08:16 -07001366 bool CreatePeerConnectionWrappers() {
1367 return CreatePeerConnectionWrappersWithConfig(
1368 PeerConnectionInterface::RTCConfiguration(),
1369 PeerConnectionInterface::RTCConfiguration());
1370 }
1371
Steve Anton3acffc32018-04-12 17:21:03 -07001372 bool CreatePeerConnectionWrappersWithSdpSemantics(
1373 SdpSemantics caller_semantics,
1374 SdpSemantics callee_semantics) {
1375 // Can't specify the sdp_semantics in the passed-in configuration since it
1376 // will be overwritten by CreatePeerConnectionWrapper with whatever is
1377 // stored in sdp_semantics_. So get around this by modifying the instance
1378 // variable before calling CreatePeerConnectionWrapper for the caller and
1379 // callee PeerConnections.
1380 SdpSemantics original_semantics = sdp_semantics_;
1381 sdp_semantics_ = caller_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001382 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001383 "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001384 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001385 /*reset_encoder_factory=*/false,
1386 /*reset_decoder_factory=*/false);
Steve Anton3acffc32018-04-12 17:21:03 -07001387 sdp_semantics_ = callee_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001388 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001389 "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001390 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001391 /*reset_encoder_factory=*/false,
1392 /*reset_decoder_factory=*/false);
Steve Anton3acffc32018-04-12 17:21:03 -07001393 sdp_semantics_ = original_semantics;
1394 return caller_ && callee_;
1395 }
1396
deadbeef1dcb1642017-03-29 21:08:16 -07001397 bool CreatePeerConnectionWrappersWithConfig(
1398 const PeerConnectionInterface::RTCConfiguration& caller_config,
1399 const PeerConnectionInterface::RTCConfiguration& callee_config) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001400 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001401 "Caller", nullptr, &caller_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001402 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001403 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001404 /*reset_decoder_factory=*/false);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001405 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001406 "Callee", nullptr, &callee_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001407 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001408 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001409 /*reset_decoder_factory=*/false);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001410 return caller_ && callee_;
1411 }
1412
1413 bool CreatePeerConnectionWrappersWithConfigAndDeps(
1414 const PeerConnectionInterface::RTCConfiguration& caller_config,
1415 webrtc::PeerConnectionDependencies caller_dependencies,
1416 const PeerConnectionInterface::RTCConfiguration& callee_config,
1417 webrtc::PeerConnectionDependencies callee_dependencies) {
Niels Möller2a707032020-06-16 16:39:13 +02001418 caller_ =
1419 CreatePeerConnectionWrapper("Caller", nullptr, &caller_config,
1420 std::move(caller_dependencies), nullptr,
1421 /*reset_encoder_factory=*/false,
1422 /*reset_decoder_factory=*/false);
1423 callee_ =
1424 CreatePeerConnectionWrapper("Callee", nullptr, &callee_config,
1425 std::move(callee_dependencies), nullptr,
1426 /*reset_encoder_factory=*/false,
1427 /*reset_decoder_factory=*/false);
deadbeef1dcb1642017-03-29 21:08:16 -07001428 return caller_ && callee_;
1429 }
1430
1431 bool CreatePeerConnectionWrappersWithOptions(
1432 const PeerConnectionFactory::Options& caller_options,
1433 const PeerConnectionFactory::Options& callee_options) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001434 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001435 "Caller", &caller_options, nullptr,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001436 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001437 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001438 /*reset_decoder_factory=*/false);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001439 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001440 "Callee", &callee_options, nullptr,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001441 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001442 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001443 /*reset_decoder_factory=*/false);
Qingsi Wang7685e862018-06-11 20:15:46 -07001444 return caller_ && callee_;
1445 }
1446
1447 bool CreatePeerConnectionWrappersWithFakeRtcEventLog() {
1448 PeerConnectionInterface::RTCConfiguration default_config;
1449 caller_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001450 "Caller", nullptr, &default_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001451 webrtc::PeerConnectionDependencies(nullptr));
1452 callee_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001453 "Callee", nullptr, &default_config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001454 webrtc::PeerConnectionDependencies(nullptr));
deadbeef1dcb1642017-03-29 21:08:16 -07001455 return caller_ && callee_;
1456 }
1457
Seth Hampson2f0d7022018-02-20 11:54:42 -08001458 std::unique_ptr<PeerConnectionWrapper>
1459 CreatePeerConnectionWrapperWithAlternateKey() {
deadbeef1dcb1642017-03-29 21:08:16 -07001460 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
1461 new FakeRTCCertificateGenerator());
1462 cert_generator->use_alternate_key();
1463
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001464 webrtc::PeerConnectionDependencies dependencies(nullptr);
1465 dependencies.cert_generator = std::move(cert_generator);
Niels Möller2a707032020-06-16 16:39:13 +02001466 return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr,
1467 std::move(dependencies), nullptr,
1468 /*reset_encoder_factory=*/false,
1469 /*reset_decoder_factory=*/false);
Johannes Kron3e983682020-03-29 22:17:00 +02001470 }
1471
1472 bool CreateOneDirectionalPeerConnectionWrappers(bool caller_to_callee) {
1473 caller_ = CreatePeerConnectionWrapper(
1474 "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001475 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001476 /*reset_encoder_factory=*/!caller_to_callee,
1477 /*reset_decoder_factory=*/caller_to_callee);
1478 callee_ = CreatePeerConnectionWrapper(
1479 "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001480 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001481 /*reset_encoder_factory=*/caller_to_callee,
1482 /*reset_decoder_factory=*/!caller_to_callee);
1483 return caller_ && callee_;
deadbeef1dcb1642017-03-29 21:08:16 -07001484 }
1485
Seth Hampsonaed71642018-06-11 07:41:32 -07001486 cricket::TestTurnServer* CreateTurnServer(
1487 rtc::SocketAddress internal_address,
1488 rtc::SocketAddress external_address,
1489 cricket::ProtocolType type = cricket::ProtocolType::PROTO_UDP,
1490 const std::string& common_name = "test turn server") {
1491 rtc::Thread* thread = network_thread();
1492 std::unique_ptr<cricket::TestTurnServer> turn_server =
1493 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnServer>>(
1494 RTC_FROM_HERE,
1495 [thread, internal_address, external_address, type, common_name] {
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001496 return std::make_unique<cricket::TestTurnServer>(
Seth Hampsonaed71642018-06-11 07:41:32 -07001497 thread, internal_address, external_address, type,
1498 /*ignore_bad_certs=*/true, common_name);
1499 });
1500 turn_servers_.push_back(std::move(turn_server));
1501 // Interactions with the turn server should be done on the network thread.
1502 return turn_servers_.back().get();
1503 }
1504
1505 cricket::TestTurnCustomizer* CreateTurnCustomizer() {
1506 std::unique_ptr<cricket::TestTurnCustomizer> turn_customizer =
1507 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnCustomizer>>(
1508 RTC_FROM_HERE,
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001509 [] { return std::make_unique<cricket::TestTurnCustomizer>(); });
Seth Hampsonaed71642018-06-11 07:41:32 -07001510 turn_customizers_.push_back(std::move(turn_customizer));
1511 // Interactions with the turn customizer should be done on the network
1512 // thread.
1513 return turn_customizers_.back().get();
1514 }
1515
1516 // Checks that the function counters for a TestTurnCustomizer are greater than
1517 // 0.
1518 void ExpectTurnCustomizerCountersIncremented(
1519 cricket::TestTurnCustomizer* turn_customizer) {
1520 unsigned int allow_channel_data_counter =
1521 network_thread()->Invoke<unsigned int>(
1522 RTC_FROM_HERE, [turn_customizer] {
1523 return turn_customizer->allow_channel_data_cnt_;
1524 });
1525 EXPECT_GT(allow_channel_data_counter, 0u);
1526 unsigned int modify_counter = network_thread()->Invoke<unsigned int>(
1527 RTC_FROM_HERE,
1528 [turn_customizer] { return turn_customizer->modify_cnt_; });
1529 EXPECT_GT(modify_counter, 0u);
1530 }
1531
deadbeef1dcb1642017-03-29 21:08:16 -07001532 // Once called, SDP blobs and ICE candidates will be automatically signaled
1533 // between PeerConnections.
1534 void ConnectFakeSignaling() {
1535 caller_->set_signaling_message_receiver(callee_.get());
1536 callee_->set_signaling_message_receiver(caller_.get());
1537 }
1538
Steve Antonede9ca52017-10-16 13:04:27 -07001539 // Once called, SDP blobs will be automatically signaled between
1540 // PeerConnections. Note that ICE candidates will not be signaled unless they
1541 // are in the exchanged SDP blobs.
1542 void ConnectFakeSignalingForSdpOnly() {
1543 ConnectFakeSignaling();
1544 SetSignalIceCandidates(false);
1545 }
1546
deadbeef1dcb1642017-03-29 21:08:16 -07001547 void SetSignalingDelayMs(int delay_ms) {
1548 caller_->set_signaling_delay_ms(delay_ms);
1549 callee_->set_signaling_delay_ms(delay_ms);
1550 }
1551
Steve Antonede9ca52017-10-16 13:04:27 -07001552 void SetSignalIceCandidates(bool signal) {
1553 caller_->set_signal_ice_candidates(signal);
1554 callee_->set_signal_ice_candidates(signal);
1555 }
1556
deadbeef1dcb1642017-03-29 21:08:16 -07001557 // Messages may get lost on the unreliable DataChannel, so we send multiple
1558 // times to avoid test flakiness.
1559 void SendRtpDataWithRetries(webrtc::DataChannelInterface* dc,
1560 const std::string& data,
1561 int retries) {
1562 for (int i = 0; i < retries; ++i) {
1563 dc->Send(DataBuffer(data));
1564 }
1565 }
1566
1567 rtc::Thread* network_thread() { return network_thread_.get(); }
1568
1569 rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); }
1570
1571 PeerConnectionWrapper* caller() { return caller_.get(); }
1572
1573 // Set the |caller_| to the |wrapper| passed in and return the
1574 // original |caller_|.
1575 PeerConnectionWrapper* SetCallerPcWrapperAndReturnCurrent(
1576 PeerConnectionWrapper* wrapper) {
1577 PeerConnectionWrapper* old = caller_.release();
1578 caller_.reset(wrapper);
1579 return old;
1580 }
1581
1582 PeerConnectionWrapper* callee() { return callee_.get(); }
1583
1584 // Set the |callee_| to the |wrapper| passed in and return the
1585 // original |callee_|.
1586 PeerConnectionWrapper* SetCalleePcWrapperAndReturnCurrent(
1587 PeerConnectionWrapper* wrapper) {
1588 PeerConnectionWrapper* old = callee_.release();
1589 callee_.reset(wrapper);
1590 return old;
1591 }
1592
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001593 void SetPortAllocatorFlags(uint32_t caller_flags, uint32_t callee_flags) {
Niels Möller4bab23f2021-01-18 09:24:33 +01001594 network_thread()->Invoke<void>(RTC_FROM_HERE, [this, caller_flags] {
1595 caller()->port_allocator()->set_flags(caller_flags);
1596 });
1597 network_thread()->Invoke<void>(RTC_FROM_HERE, [this, callee_flags] {
1598 callee()->port_allocator()->set_flags(callee_flags);
1599 });
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001600 }
1601
Steve Antonede9ca52017-10-16 13:04:27 -07001602 rtc::FirewallSocketServer* firewall() const { return fss_.get(); }
1603
Seth Hampson2f0d7022018-02-20 11:54:42 -08001604 // Expects the provided number of new frames to be received within
1605 // kMaxWaitForFramesMs. The new expected frames are specified in
1606 // |media_expectations|. Returns false if any of the expectations were
1607 // not met.
1608 bool ExpectNewFrames(const MediaExpectations& media_expectations) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02001609 // Make sure there are no bogus tracks confusing the issue.
1610 caller()->RemoveUnusedVideoRenderers();
1611 callee()->RemoveUnusedVideoRenderers();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001612 // First initialize the expected frame counts based upon the current
1613 // frame count.
1614 int total_caller_audio_frames_expected = caller()->audio_frames_received();
1615 if (media_expectations.caller_audio_expectation_ ==
1616 MediaExpectations::kExpectSomeFrames) {
1617 total_caller_audio_frames_expected +=
1618 media_expectations.caller_audio_frames_expected_;
1619 }
1620 int total_caller_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001621 caller()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001622 if (media_expectations.caller_video_expectation_ ==
1623 MediaExpectations::kExpectSomeFrames) {
1624 total_caller_video_frames_expected +=
1625 media_expectations.caller_video_frames_expected_;
1626 }
1627 int total_callee_audio_frames_expected = callee()->audio_frames_received();
1628 if (media_expectations.callee_audio_expectation_ ==
1629 MediaExpectations::kExpectSomeFrames) {
1630 total_callee_audio_frames_expected +=
1631 media_expectations.callee_audio_frames_expected_;
1632 }
1633 int total_callee_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001634 callee()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001635 if (media_expectations.callee_video_expectation_ ==
1636 MediaExpectations::kExpectSomeFrames) {
1637 total_callee_video_frames_expected +=
1638 media_expectations.callee_video_frames_expected_;
1639 }
deadbeef1dcb1642017-03-29 21:08:16 -07001640
Seth Hampson2f0d7022018-02-20 11:54:42 -08001641 // Wait for the expected frames.
deadbeef1dcb1642017-03-29 21:08:16 -07001642 EXPECT_TRUE_WAIT(caller()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001643 total_caller_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001644 caller()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001645 total_caller_video_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001646 callee()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001647 total_callee_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001648 callee()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001649 total_callee_video_frames_expected,
1650 kMaxWaitForFramesMs);
1651 bool expectations_correct =
1652 caller()->audio_frames_received() >=
1653 total_caller_audio_frames_expected &&
1654 caller()->min_video_frames_received_per_track() >=
1655 total_caller_video_frames_expected &&
1656 callee()->audio_frames_received() >=
1657 total_callee_audio_frames_expected &&
1658 callee()->min_video_frames_received_per_track() >=
1659 total_callee_video_frames_expected;
deadbeef1dcb1642017-03-29 21:08:16 -07001660
Seth Hampson2f0d7022018-02-20 11:54:42 -08001661 // After the combined wait, print out a more detailed message upon
1662 // failure.
deadbeef1dcb1642017-03-29 21:08:16 -07001663 EXPECT_GE(caller()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001664 total_caller_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001665 EXPECT_GE(caller()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001666 total_caller_video_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001667 EXPECT_GE(callee()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001668 total_callee_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001669 EXPECT_GE(callee()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001670 total_callee_video_frames_expected);
1671
1672 // We want to make sure nothing unexpected was received.
1673 if (media_expectations.caller_audio_expectation_ ==
1674 MediaExpectations::kExpectNoFrames) {
1675 EXPECT_EQ(caller()->audio_frames_received(),
1676 total_caller_audio_frames_expected);
1677 if (caller()->audio_frames_received() !=
1678 total_caller_audio_frames_expected) {
1679 expectations_correct = false;
1680 }
1681 }
1682 if (media_expectations.caller_video_expectation_ ==
1683 MediaExpectations::kExpectNoFrames) {
1684 EXPECT_EQ(caller()->min_video_frames_received_per_track(),
1685 total_caller_video_frames_expected);
1686 if (caller()->min_video_frames_received_per_track() !=
1687 total_caller_video_frames_expected) {
1688 expectations_correct = false;
1689 }
1690 }
1691 if (media_expectations.callee_audio_expectation_ ==
1692 MediaExpectations::kExpectNoFrames) {
1693 EXPECT_EQ(callee()->audio_frames_received(),
1694 total_callee_audio_frames_expected);
1695 if (callee()->audio_frames_received() !=
1696 total_callee_audio_frames_expected) {
1697 expectations_correct = false;
1698 }
1699 }
1700 if (media_expectations.callee_video_expectation_ ==
1701 MediaExpectations::kExpectNoFrames) {
1702 EXPECT_EQ(callee()->min_video_frames_received_per_track(),
1703 total_callee_video_frames_expected);
1704 if (callee()->min_video_frames_received_per_track() !=
1705 total_callee_video_frames_expected) {
1706 expectations_correct = false;
1707 }
1708 }
1709 return expectations_correct;
deadbeef1dcb1642017-03-29 21:08:16 -07001710 }
1711
Steve Antond91969e2019-05-30 12:27:03 -07001712 void ClosePeerConnections() {
1713 caller()->pc()->Close();
1714 callee()->pc()->Close();
1715 }
1716
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001717 void TestNegotiatedCipherSuite(
1718 const PeerConnectionFactory::Options& caller_options,
1719 const PeerConnectionFactory::Options& callee_options,
1720 int expected_cipher_suite) {
deadbeef1dcb1642017-03-29 21:08:16 -07001721 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options,
1722 callee_options));
deadbeef1dcb1642017-03-29 21:08:16 -07001723 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001724 caller()->AddAudioVideoTracks();
1725 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001726 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001727 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001728 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite),
deadbeefd8ad7882017-04-18 16:01:17 -07001729 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001730 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001731 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1732 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1733 expected_cipher_suite));
deadbeef1dcb1642017-03-29 21:08:16 -07001734 }
1735
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001736 void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
1737 bool remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001738 bool aes_ctr_enabled,
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001739 int expected_cipher_suite) {
1740 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001741 caller_options.crypto_options.srtp.enable_gcm_crypto_suites =
1742 local_gcm_enabled;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001743 caller_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher =
1744 aes_ctr_enabled;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001745 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001746 callee_options.crypto_options.srtp.enable_gcm_crypto_suites =
1747 remote_gcm_enabled;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001748 callee_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher =
1749 aes_ctr_enabled;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001750 TestNegotiatedCipherSuite(caller_options, callee_options,
1751 expected_cipher_suite);
1752 }
1753
Seth Hampson2f0d7022018-02-20 11:54:42 -08001754 protected:
Steve Anton3acffc32018-04-12 17:21:03 -07001755 SdpSemantics sdp_semantics_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001756
deadbeef1dcb1642017-03-29 21:08:16 -07001757 private:
1758 // |ss_| is used by |network_thread_| so it must be destroyed later.
deadbeef1dcb1642017-03-29 21:08:16 -07001759 std::unique_ptr<rtc::VirtualSocketServer> ss_;
Steve Antonede9ca52017-10-16 13:04:27 -07001760 std::unique_ptr<rtc::FirewallSocketServer> fss_;
deadbeef1dcb1642017-03-29 21:08:16 -07001761 // |network_thread_| and |worker_thread_| are used by both
1762 // |caller_| and |callee_| so they must be destroyed
1763 // later.
1764 std::unique_ptr<rtc::Thread> network_thread_;
1765 std::unique_ptr<rtc::Thread> worker_thread_;
Seth Hampsonaed71642018-06-11 07:41:32 -07001766 // The turn servers and turn customizers should be accessed & deleted on the
1767 // network thread to avoid a race with the socket read/write that occurs
1768 // on the network thread.
1769 std::vector<std::unique_ptr<cricket::TestTurnServer>> turn_servers_;
1770 std::vector<std::unique_ptr<cricket::TestTurnCustomizer>> turn_customizers_;
deadbeef1dcb1642017-03-29 21:08:16 -07001771 std::unique_ptr<PeerConnectionWrapper> caller_;
1772 std::unique_ptr<PeerConnectionWrapper> callee_;
1773};
1774
Seth Hampson2f0d7022018-02-20 11:54:42 -08001775class PeerConnectionIntegrationTest
1776 : public PeerConnectionIntegrationBaseTest,
1777 public ::testing::WithParamInterface<SdpSemantics> {
1778 protected:
1779 PeerConnectionIntegrationTest()
1780 : PeerConnectionIntegrationBaseTest(GetParam()) {}
1781};
1782
Yves Gerey100fe632020-01-17 19:15:53 +01001783// Fake clock must be set before threads are started to prevent race on
1784// Set/GetClockForTesting().
1785// To achieve that, multiple inheritance is used as a mixin pattern
1786// where order of construction is finely controlled.
1787// This also ensures peerconnection is closed before switching back to non-fake
1788// clock, avoiding other races and DCHECK failures such as in rtp_sender.cc.
1789class FakeClockForTest : public rtc::ScopedFakeClock {
1790 protected:
1791 FakeClockForTest() {
1792 // Some things use a time of "0" as a special value, so we need to start out
1793 // the fake clock at a nonzero time.
1794 // TODO(deadbeef): Fix this.
Danil Chapovalov0c626af2020-02-10 11:16:00 +01001795 AdvanceTime(webrtc::TimeDelta::Seconds(1));
Yves Gerey100fe632020-01-17 19:15:53 +01001796 }
1797
1798 // Explicit handle.
1799 ScopedFakeClock& FakeClock() { return *this; }
1800};
1801
1802// Ensure FakeClockForTest is constructed first (see class for rationale).
1803class PeerConnectionIntegrationTestWithFakeClock
1804 : public FakeClockForTest,
1805 public PeerConnectionIntegrationTest {};
1806
Seth Hampson2f0d7022018-02-20 11:54:42 -08001807class PeerConnectionIntegrationTestPlanB
1808 : public PeerConnectionIntegrationBaseTest {
1809 protected:
1810 PeerConnectionIntegrationTestPlanB()
1811 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
1812};
1813
1814class PeerConnectionIntegrationTestUnifiedPlan
1815 : public PeerConnectionIntegrationBaseTest {
1816 protected:
1817 PeerConnectionIntegrationTestUnifiedPlan()
1818 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
1819};
1820
deadbeef1dcb1642017-03-29 21:08:16 -07001821// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
1822// includes testing that the callback is invoked if an observer is connected
1823// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001824TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001825 RtpReceiverObserverOnFirstPacketReceived) {
1826 ASSERT_TRUE(CreatePeerConnectionWrappers());
1827 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001828 caller()->AddAudioVideoTracks();
1829 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001830 // Start offer/answer exchange and wait for it to complete.
1831 caller()->CreateAndSetAndSignalOffer();
1832 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1833 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001834 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1835 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001836 // Wait for all "first packet received" callbacks to be fired.
1837 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -08001838 absl::c_all_of(caller()->rtp_receiver_observers(),
1839 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1840 return o->first_packet_received();
1841 }),
deadbeef1dcb1642017-03-29 21:08:16 -07001842 kMaxWaitForFramesMs);
1843 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -08001844 absl::c_all_of(callee()->rtp_receiver_observers(),
1845 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1846 return o->first_packet_received();
1847 }),
deadbeef1dcb1642017-03-29 21:08:16 -07001848 kMaxWaitForFramesMs);
1849 // If new observers are set after the first packet was already received, the
1850 // callback should still be invoked.
1851 caller()->ResetRtpReceiverObservers();
1852 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001853 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1854 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001855 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -08001856 absl::c_all_of(caller()->rtp_receiver_observers(),
1857 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1858 return o->first_packet_received();
1859 }));
deadbeef1dcb1642017-03-29 21:08:16 -07001860 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -08001861 absl::c_all_of(callee()->rtp_receiver_observers(),
1862 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1863 return o->first_packet_received();
1864 }));
deadbeef1dcb1642017-03-29 21:08:16 -07001865}
1866
1867class DummyDtmfObserver : public DtmfSenderObserverInterface {
1868 public:
1869 DummyDtmfObserver() : completed_(false) {}
1870
1871 // Implements DtmfSenderObserverInterface.
1872 void OnToneChange(const std::string& tone) override {
1873 tones_.push_back(tone);
1874 if (tone.empty()) {
1875 completed_ = true;
1876 }
1877 }
1878
1879 const std::vector<std::string>& tones() const { return tones_; }
1880 bool completed() const { return completed_; }
1881
1882 private:
1883 bool completed_;
1884 std::vector<std::string> tones_;
1885};
1886
1887// Assumes |sender| already has an audio track added and the offer/answer
1888// exchange is done.
1889void TestDtmfFromSenderToReceiver(PeerConnectionWrapper* sender,
1890 PeerConnectionWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -08001891 // We should be able to get a DTMF sender from the local sender.
1892 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
1893 sender->pc()->GetSenders().at(0)->GetDtmfSender();
1894 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -07001895 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -07001896 dtmf_sender->RegisterObserver(&observer);
1897
1898 // Test the DtmfSender object just created.
1899 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
1900 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
1901
1902 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
1903 std::vector<std::string> tones = {"1", "a", ""};
1904 EXPECT_EQ(tones, observer.tones());
1905 dtmf_sender->UnregisterObserver();
1906 // TODO(deadbeef): Verify the tones were actually received end-to-end.
1907}
1908
1909// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
1910// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001911TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -07001912 ASSERT_TRUE(CreatePeerConnectionWrappers());
1913 ConnectFakeSignaling();
1914 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -08001915 caller()->AddAudioTrack();
1916 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001917 caller()->CreateAndSetAndSignalOffer();
1918 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -07001919 // DTLS must finish before the DTMF sender can be used reliably.
1920 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001921 TestDtmfFromSenderToReceiver(caller(), callee());
1922 TestDtmfFromSenderToReceiver(callee(), caller());
1923}
1924
1925// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
1926// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001927TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -07001928 ASSERT_TRUE(CreatePeerConnectionWrappers());
1929 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +01001930
deadbeef1dcb1642017-03-29 21:08:16 -07001931 // Do normal offer/answer and wait for some frames to be received in each
1932 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001933 caller()->AddAudioVideoTracks();
1934 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001935 caller()->CreateAndSetAndSignalOffer();
1936 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001937 MediaExpectations media_expectations;
1938 media_expectations.ExpectBidirectionalAudioAndVideo();
1939 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Ying Wangef3998f2019-12-09 13:06:53 +01001940 EXPECT_METRIC_LE(
1941 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1942 webrtc::kEnumCounterKeyProtocolDtls));
1943 EXPECT_METRIC_EQ(
1944 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1945 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -07001946}
1947
1948// Uses SDES instead of DTLS for key agreement.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001949TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
deadbeef1dcb1642017-03-29 21:08:16 -07001950 PeerConnectionInterface::RTCConfiguration sdes_config;
1951 sdes_config.enable_dtls_srtp.emplace(false);
1952 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
1953 ConnectFakeSignaling();
1954
1955 // Do normal offer/answer and wait for some frames to be received in each
1956 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001957 caller()->AddAudioVideoTracks();
1958 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001959 caller()->CreateAndSetAndSignalOffer();
1960 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001961 MediaExpectations media_expectations;
1962 media_expectations.ExpectBidirectionalAudioAndVideo();
1963 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Ying Wangef3998f2019-12-09 13:06:53 +01001964 EXPECT_METRIC_LE(
1965 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1966 webrtc::kEnumCounterKeyProtocolSdes));
1967 EXPECT_METRIC_EQ(
1968 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1969 webrtc::kEnumCounterKeyProtocolDtls));
deadbeef1dcb1642017-03-29 21:08:16 -07001970}
1971
Steve Anton9a44b2d2019-07-12 12:58:30 -07001972// Basic end-to-end test specifying the |enable_encrypted_rtp_header_extensions|
1973// option to offer encrypted versions of all header extensions alongside the
1974// unencrypted versions.
1975TEST_P(PeerConnectionIntegrationTest,
1976 EndToEndCallWithEncryptedRtpHeaderExtensions) {
1977 CryptoOptions crypto_options;
1978 crypto_options.srtp.enable_encrypted_rtp_header_extensions = true;
1979 PeerConnectionInterface::RTCConfiguration config;
1980 config.crypto_options = crypto_options;
1981 // Note: This allows offering >14 RTP header extensions.
1982 config.offer_extmap_allow_mixed = true;
1983 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
1984 ConnectFakeSignaling();
1985
1986 // Do normal offer/answer and wait for some frames to be received in each
1987 // direction.
1988 caller()->AddAudioVideoTracks();
1989 callee()->AddAudioVideoTracks();
1990 caller()->CreateAndSetAndSignalOffer();
1991 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1992 MediaExpectations media_expectations;
1993 media_expectations.ExpectBidirectionalAudioAndVideo();
1994 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1995}
1996
deadbeef1dcb1642017-03-29 21:08:16 -07001997// This test sets up a call between two parties with a source resolution of
1998// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001999TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002000 Send1280By720ResolutionAndReceive16To9AspectRatio) {
2001 ASSERT_TRUE(CreatePeerConnectionWrappers());
2002 ConnectFakeSignaling();
2003
Niels Möller5c7efe72018-05-11 10:34:46 +02002004 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
2005 webrtc::FakePeriodicVideoSource::Config config;
2006 config.width = 1280;
2007 config.height = 720;
Johannes Kron965e7942018-09-13 15:36:20 +02002008 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +02002009 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
2010 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -07002011
2012 // Do normal offer/answer and wait for at least one frame to be received in
2013 // each direction.
2014 caller()->CreateAndSetAndSignalOffer();
2015 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2016 callee()->min_video_frames_received_per_track() > 0,
2017 kMaxWaitForFramesMs);
2018
2019 // Check rendered aspect ratio.
2020 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
2021 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
2022 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
2023 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
2024}
2025
2026// This test sets up an one-way call, with media only from caller to
2027// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002028TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -07002029 ASSERT_TRUE(CreatePeerConnectionWrappers());
2030 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002031 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002032 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002033 MediaExpectations media_expectations;
2034 media_expectations.CalleeExpectsSomeAudioAndVideo();
2035 media_expectations.CallerExpectsNoAudio();
2036 media_expectations.CallerExpectsNoVideo();
2037 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002038}
2039
Johannes Kron3e983682020-03-29 22:17:00 +02002040// Tests that send only works without the caller having a decoder factory and
2041// the callee having an encoder factory.
2042TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSendOnlyVideo) {
2043 ASSERT_TRUE(
2044 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
2045 ConnectFakeSignaling();
2046 // Add one-directional video, from caller to callee.
2047 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2048 caller()->CreateLocalVideoTrack();
2049 caller()->AddTrack(caller_track);
2050 PeerConnectionInterface::RTCOfferAnswerOptions options;
2051 options.offer_to_receive_video = 0;
2052 caller()->SetOfferAnswerOptions(options);
2053 caller()->CreateAndSetAndSignalOffer();
2054 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2055 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2056
2057 // Expect video to be received in one direction.
2058 MediaExpectations media_expectations;
2059 media_expectations.CallerExpectsNoVideo();
2060 media_expectations.CalleeExpectsSomeVideo();
2061
2062 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2063}
2064
2065// Tests that receive only works without the caller having an encoder factory
2066// and the callee having a decoder factory.
2067TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithReceiveOnlyVideo) {
2068 ASSERT_TRUE(
2069 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/false));
2070 ConnectFakeSignaling();
2071 // Add one-directional video, from callee to caller.
2072 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2073 callee()->CreateLocalVideoTrack();
2074 callee()->AddTrack(callee_track);
2075 PeerConnectionInterface::RTCOfferAnswerOptions options;
2076 options.offer_to_receive_video = 1;
2077 caller()->SetOfferAnswerOptions(options);
2078 caller()->CreateAndSetAndSignalOffer();
2079 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2080 ASSERT_EQ(caller()->pc()->GetReceivers().size(), 1u);
2081
2082 // Expect video to be received in one direction.
2083 MediaExpectations media_expectations;
2084 media_expectations.CallerExpectsSomeVideo();
2085 media_expectations.CalleeExpectsNoVideo();
2086
2087 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2088}
2089
2090TEST_P(PeerConnectionIntegrationTest,
2091 EndToEndCallAddReceiveVideoToSendOnlyCall) {
2092 ASSERT_TRUE(CreatePeerConnectionWrappers());
2093 ConnectFakeSignaling();
2094 // Add one-directional video, from caller to callee.
2095 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2096 caller()->CreateLocalVideoTrack();
2097 caller()->AddTrack(caller_track);
2098 caller()->CreateAndSetAndSignalOffer();
2099 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2100
2101 // Add receive video.
2102 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2103 callee()->CreateLocalVideoTrack();
2104 callee()->AddTrack(callee_track);
2105 caller()->CreateAndSetAndSignalOffer();
2106 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2107
2108 // Ensure that video frames are received end-to-end.
2109 MediaExpectations media_expectations;
2110 media_expectations.ExpectBidirectionalVideo();
2111 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2112}
2113
2114TEST_P(PeerConnectionIntegrationTest,
2115 EndToEndCallAddSendVideoToReceiveOnlyCall) {
2116 ASSERT_TRUE(CreatePeerConnectionWrappers());
2117 ConnectFakeSignaling();
2118 // Add one-directional video, from callee to caller.
2119 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2120 callee()->CreateLocalVideoTrack();
2121 callee()->AddTrack(callee_track);
2122 caller()->CreateAndSetAndSignalOffer();
2123 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2124
2125 // Add send video.
2126 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2127 caller()->CreateLocalVideoTrack();
2128 caller()->AddTrack(caller_track);
2129 caller()->CreateAndSetAndSignalOffer();
2130 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2131
2132 // Expect video to be received in one direction.
2133 MediaExpectations media_expectations;
2134 media_expectations.ExpectBidirectionalVideo();
2135 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2136}
2137
2138TEST_P(PeerConnectionIntegrationTest,
2139 EndToEndCallRemoveReceiveVideoFromSendReceiveCall) {
2140 ASSERT_TRUE(CreatePeerConnectionWrappers());
2141 ConnectFakeSignaling();
2142 // Add send video, from caller to callee.
2143 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2144 caller()->CreateLocalVideoTrack();
2145 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
2146 caller()->AddTrack(caller_track);
2147 // Add receive video, from callee to caller.
2148 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2149 callee()->CreateLocalVideoTrack();
2150
2151 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
2152 callee()->AddTrack(callee_track);
2153 caller()->CreateAndSetAndSignalOffer();
2154 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2155
2156 // Remove receive video (i.e., callee sender track).
2157 callee()->pc()->RemoveTrack(callee_sender);
2158
2159 caller()->CreateAndSetAndSignalOffer();
2160 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2161
2162 // Expect one-directional video.
2163 MediaExpectations media_expectations;
2164 media_expectations.CallerExpectsNoVideo();
2165 media_expectations.CalleeExpectsSomeVideo();
2166
2167 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2168}
2169
2170TEST_P(PeerConnectionIntegrationTest,
2171 EndToEndCallRemoveSendVideoFromSendReceiveCall) {
2172 ASSERT_TRUE(CreatePeerConnectionWrappers());
2173 ConnectFakeSignaling();
2174 // Add send video, from caller to callee.
2175 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2176 caller()->CreateLocalVideoTrack();
2177 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
2178 caller()->AddTrack(caller_track);
2179 // Add receive video, from callee to caller.
2180 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2181 callee()->CreateLocalVideoTrack();
2182
2183 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
2184 callee()->AddTrack(callee_track);
2185 caller()->CreateAndSetAndSignalOffer();
2186 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2187
2188 // Remove send video (i.e., caller sender track).
2189 caller()->pc()->RemoveTrack(caller_sender);
2190
2191 caller()->CreateAndSetAndSignalOffer();
2192 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2193
2194 // Expect one-directional video.
2195 MediaExpectations media_expectations;
2196 media_expectations.CalleeExpectsNoVideo();
2197 media_expectations.CallerExpectsSomeVideo();
2198
2199 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2200}
2201
deadbeef1dcb1642017-03-29 21:08:16 -07002202// This test sets up a audio call initially, with the callee rejecting video
2203// initially. Then later the callee decides to upgrade to audio/video, and
2204// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002205TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -07002206 ASSERT_TRUE(CreatePeerConnectionWrappers());
2207 ConnectFakeSignaling();
2208 // Initially, offer an audio/video stream from the caller, but refuse to
2209 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -08002210 caller()->AddAudioVideoTracks();
2211 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002212 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2213 PeerConnectionInterface::RTCOfferAnswerOptions options;
2214 options.offer_to_receive_video = 0;
2215 callee()->SetOfferAnswerOptions(options);
2216 } else {
2217 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002218 callee()
2219 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2220 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002221 });
2222 }
deadbeef1dcb1642017-03-29 21:08:16 -07002223 // Do offer/answer and make sure audio is still received end-to-end.
2224 caller()->CreateAndSetAndSignalOffer();
2225 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002226 {
2227 MediaExpectations media_expectations;
2228 media_expectations.ExpectBidirectionalAudio();
2229 media_expectations.ExpectNoVideo();
2230 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2231 }
deadbeef1dcb1642017-03-29 21:08:16 -07002232 // Sanity check that the callee's description has a rejected video section.
2233 ASSERT_NE(nullptr, callee()->pc()->local_description());
2234 const ContentInfo* callee_video_content =
2235 GetFirstVideoContent(callee()->pc()->local_description()->description());
2236 ASSERT_NE(nullptr, callee_video_content);
2237 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002238
deadbeef1dcb1642017-03-29 21:08:16 -07002239 // Now negotiate with video and ensure negotiation succeeds, with video
2240 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -08002241 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002242 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2243 PeerConnectionInterface::RTCOfferAnswerOptions options;
2244 options.offer_to_receive_video = 1;
2245 callee()->SetOfferAnswerOptions(options);
2246 } else {
2247 callee()->SetRemoteOfferHandler(nullptr);
2248 caller()->SetRemoteOfferHandler([this] {
2249 // The caller creates a new transceiver to receive video on when receiving
2250 // the offer, but by default it is send only.
2251 auto transceivers = caller()->pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +02002252 ASSERT_EQ(2U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002253 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
Harald Alvestrand6060df52020-08-11 09:54:02 +02002254 transceivers[1]->receiver()->media_type());
2255 transceivers[1]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
2256 transceivers[1]->SetDirectionWithError(
2257 RtpTransceiverDirection::kSendRecv);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002258 });
2259 }
deadbeef1dcb1642017-03-29 21:08:16 -07002260 callee()->CreateAndSetAndSignalOffer();
2261 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002262 {
2263 // Expect additional audio frames to be received after the upgrade.
2264 MediaExpectations media_expectations;
2265 media_expectations.ExpectBidirectionalAudioAndVideo();
2266 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2267 }
deadbeef1dcb1642017-03-29 21:08:16 -07002268}
2269
deadbeef4389b4d2017-09-07 09:07:36 -07002270// Simpler than the above test; just add an audio track to an established
2271// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002272TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -07002273 ASSERT_TRUE(CreatePeerConnectionWrappers());
2274 ConnectFakeSignaling();
2275 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -08002276 caller()->AddVideoTrack();
2277 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07002278 caller()->CreateAndSetAndSignalOffer();
2279 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2280 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08002281 caller()->AddAudioTrack();
2282 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07002283 caller()->CreateAndSetAndSignalOffer();
2284 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2285 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002286 MediaExpectations media_expectations;
2287 media_expectations.ExpectBidirectionalAudioAndVideo();
2288 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -07002289}
2290
deadbeef1dcb1642017-03-29 21:08:16 -07002291// This test sets up a call that's transferred to a new caller with a different
2292// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002293TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -07002294 ASSERT_TRUE(CreatePeerConnectionWrappers());
2295 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002296 caller()->AddAudioVideoTracks();
2297 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002298 caller()->CreateAndSetAndSignalOffer();
2299 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2300
2301 // Keep the original peer around which will still send packets to the
2302 // receiving client. These SRTP packets will be dropped.
2303 std::unique_ptr<PeerConnectionWrapper> original_peer(
2304 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002305 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07002306 // TODO(deadbeef): Why do we call Close here? That goes against the comment
2307 // directly above.
2308 original_peer->pc()->Close();
2309
2310 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002311 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002312 caller()->CreateAndSetAndSignalOffer();
2313 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2314 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002315 MediaExpectations media_expectations;
2316 media_expectations.ExpectBidirectionalAudioAndVideo();
2317 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002318}
2319
2320// This test sets up a call that's transferred to a new callee with a different
2321// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002322TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -07002323 ASSERT_TRUE(CreatePeerConnectionWrappers());
2324 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002325 caller()->AddAudioVideoTracks();
2326 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002327 caller()->CreateAndSetAndSignalOffer();
2328 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2329
2330 // Keep the original peer around which will still send packets to the
2331 // receiving client. These SRTP packets will be dropped.
2332 std::unique_ptr<PeerConnectionWrapper> original_peer(
2333 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002334 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07002335 // TODO(deadbeef): Why do we call Close here? That goes against the comment
2336 // directly above.
2337 original_peer->pc()->Close();
2338
2339 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002340 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002341 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2342 caller()->CreateAndSetAndSignalOffer();
2343 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2344 // Wait for some additional frames to be transmitted end-to-end.
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
2350// This test sets up a non-bundled call and negotiates bundling at the same
2351// time as starting an ICE restart. When bundling is in effect in the restart,
2352// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002353TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -07002354 ASSERT_TRUE(CreatePeerConnectionWrappers());
2355 ConnectFakeSignaling();
2356
Steve Anton15324772018-01-16 10:26:49 -08002357 caller()->AddAudioVideoTracks();
2358 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002359 // Remove the bundle group from the SDP received by the callee.
2360 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2361 desc->RemoveGroupByName("BUNDLE");
2362 });
2363 caller()->CreateAndSetAndSignalOffer();
2364 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002365 {
2366 MediaExpectations media_expectations;
2367 media_expectations.ExpectBidirectionalAudioAndVideo();
2368 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2369 }
deadbeef1dcb1642017-03-29 21:08:16 -07002370 // Now stop removing the BUNDLE group, and trigger an ICE restart.
2371 callee()->SetReceivedSdpMunger(nullptr);
2372 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2373 caller()->CreateAndSetAndSignalOffer();
2374 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2375
2376 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002377 {
2378 MediaExpectations media_expectations;
2379 media_expectations.ExpectBidirectionalAudioAndVideo();
2380 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2381 }
deadbeef1dcb1642017-03-29 21:08:16 -07002382}
2383
2384// Test CVO (Coordination of Video Orientation). If a video source is rotated
2385// and both peers support the CVO RTP header extension, the actual video frames
2386// don't need to be encoded in different resolutions, since the rotation is
2387// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002388TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002389 ASSERT_TRUE(CreatePeerConnectionWrappers());
2390 ConnectFakeSignaling();
2391 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002392 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002393 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002394 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002395 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2396
2397 // Wait for video frames to be received by both sides.
2398 caller()->CreateAndSetAndSignalOffer();
2399 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2400 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2401 callee()->min_video_frames_received_per_track() > 0,
2402 kMaxWaitForFramesMs);
2403
2404 // Ensure that the aspect ratio is unmodified.
2405 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2406 // not just assumed.
2407 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
2408 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
2409 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
2410 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
2411 // Ensure that the CVO bits were surfaced to the renderer.
2412 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
2413 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
2414}
2415
2416// Test that when the CVO extension isn't supported, video is rotated the
2417// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002418TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002419 ASSERT_TRUE(CreatePeerConnectionWrappers());
2420 ConnectFakeSignaling();
2421 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002422 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002423 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002424 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002425 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2426
2427 // Remove the CVO extension from the offered SDP.
2428 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2429 cricket::VideoContentDescription* video =
2430 GetFirstVideoContentDescription(desc);
2431 video->ClearRtpHeaderExtensions();
2432 });
2433 // Wait for video frames to be received by both sides.
2434 caller()->CreateAndSetAndSignalOffer();
2435 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2436 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2437 callee()->min_video_frames_received_per_track() > 0,
2438 kMaxWaitForFramesMs);
2439
2440 // Expect that the aspect ratio is inversed to account for the 90/270 degree
2441 // rotation.
2442 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2443 // not just assumed.
2444 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
2445 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
2446 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
2447 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
2448 // Expect that each endpoint is unaware of the rotation of the other endpoint.
2449 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
2450 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
2451}
2452
deadbeef1dcb1642017-03-29 21:08:16 -07002453// Test that if the answerer rejects the audio m= section, no audio is sent or
2454// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002455TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002456 ASSERT_TRUE(CreatePeerConnectionWrappers());
2457 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002458 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002459 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2460 // Only add video track for callee, and set offer_to_receive_audio to 0, so
2461 // it will reject the audio m= section completely.
2462 PeerConnectionInterface::RTCOfferAnswerOptions options;
2463 options.offer_to_receive_audio = 0;
2464 callee()->SetOfferAnswerOptions(options);
2465 } else {
2466 // Stopping the audio RtpTransceiver will cause the media section to be
2467 // rejected in the answer.
2468 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002469 callee()
2470 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
2471 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002472 });
2473 }
Steve Anton15324772018-01-16 10:26:49 -08002474 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002475 // Do offer/answer and wait for successful end-to-end video frames.
2476 caller()->CreateAndSetAndSignalOffer();
2477 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002478 MediaExpectations media_expectations;
2479 media_expectations.ExpectBidirectionalVideo();
2480 media_expectations.ExpectNoAudio();
2481 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2482
deadbeef1dcb1642017-03-29 21:08:16 -07002483 // Sanity check that the callee's description has a rejected audio section.
2484 ASSERT_NE(nullptr, callee()->pc()->local_description());
2485 const ContentInfo* callee_audio_content =
2486 GetFirstAudioContent(callee()->pc()->local_description()->description());
2487 ASSERT_NE(nullptr, callee_audio_content);
2488 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002489 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002490 // The caller's transceiver should have stopped after receiving the answer,
2491 // and thus no longer listed in transceivers.
2492 EXPECT_EQ(nullptr,
2493 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002494 }
deadbeef1dcb1642017-03-29 21:08:16 -07002495}
2496
2497// Test that if the answerer rejects the video m= section, no video is sent or
2498// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002499TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002500 ASSERT_TRUE(CreatePeerConnectionWrappers());
2501 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002502 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002503 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2504 // Only add audio track for callee, and set offer_to_receive_video to 0, so
2505 // it will reject the video m= section completely.
2506 PeerConnectionInterface::RTCOfferAnswerOptions options;
2507 options.offer_to_receive_video = 0;
2508 callee()->SetOfferAnswerOptions(options);
2509 } else {
2510 // Stopping the video RtpTransceiver will cause the media section to be
2511 // rejected in the answer.
2512 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002513 callee()
2514 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2515 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002516 });
2517 }
Steve Anton15324772018-01-16 10:26:49 -08002518 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002519 // Do offer/answer and wait for successful end-to-end audio frames.
2520 caller()->CreateAndSetAndSignalOffer();
2521 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002522 MediaExpectations media_expectations;
2523 media_expectations.ExpectBidirectionalAudio();
2524 media_expectations.ExpectNoVideo();
2525 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2526
deadbeef1dcb1642017-03-29 21:08:16 -07002527 // Sanity check that the callee's description has a rejected video section.
2528 ASSERT_NE(nullptr, callee()->pc()->local_description());
2529 const ContentInfo* callee_video_content =
2530 GetFirstVideoContent(callee()->pc()->local_description()->description());
2531 ASSERT_NE(nullptr, callee_video_content);
2532 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002533 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002534 // The caller's transceiver should have stopped after receiving the answer,
2535 // and thus is no longer present.
2536 EXPECT_EQ(nullptr,
2537 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002538 }
deadbeef1dcb1642017-03-29 21:08:16 -07002539}
2540
2541// Test that if the answerer rejects both audio and video m= sections, nothing
2542// bad happens.
2543// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
2544// test anything but the fact that negotiation succeeds, which doesn't mean
2545// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002546TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -07002547 ASSERT_TRUE(CreatePeerConnectionWrappers());
2548 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002549 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002550 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2551 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
2552 // will reject both audio and video m= sections.
2553 PeerConnectionInterface::RTCOfferAnswerOptions options;
2554 options.offer_to_receive_audio = 0;
2555 options.offer_to_receive_video = 0;
2556 callee()->SetOfferAnswerOptions(options);
2557 } else {
2558 callee()->SetRemoteOfferHandler([this] {
2559 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +01002560 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002561 transceiver->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002562 }
2563 });
2564 }
deadbeef1dcb1642017-03-29 21:08:16 -07002565 // Do offer/answer and wait for stable signaling state.
2566 caller()->CreateAndSetAndSignalOffer();
2567 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002568
deadbeef1dcb1642017-03-29 21:08:16 -07002569 // Sanity check that the callee's description has rejected m= sections.
2570 ASSERT_NE(nullptr, callee()->pc()->local_description());
2571 const ContentInfo* callee_audio_content =
2572 GetFirstAudioContent(callee()->pc()->local_description()->description());
2573 ASSERT_NE(nullptr, callee_audio_content);
2574 EXPECT_TRUE(callee_audio_content->rejected);
2575 const ContentInfo* callee_video_content =
2576 GetFirstVideoContent(callee()->pc()->local_description()->description());
2577 ASSERT_NE(nullptr, callee_video_content);
2578 EXPECT_TRUE(callee_video_content->rejected);
2579}
2580
2581// This test sets up an audio and video call between two parties. After the
2582// call runs for a while, the caller sends an updated offer with video being
2583// rejected. Once the re-negotiation is done, the video flow should stop and
2584// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002585TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07002586 ASSERT_TRUE(CreatePeerConnectionWrappers());
2587 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002588 caller()->AddAudioVideoTracks();
2589 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002590 caller()->CreateAndSetAndSignalOffer();
2591 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002592 {
2593 MediaExpectations media_expectations;
2594 media_expectations.ExpectBidirectionalAudioAndVideo();
2595 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2596 }
deadbeef1dcb1642017-03-29 21:08:16 -07002597 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002598 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2599 caller()->SetGeneratedSdpMunger(
2600 [](cricket::SessionDescription* description) {
2601 for (cricket::ContentInfo& content : description->contents()) {
2602 if (cricket::IsVideoContent(&content)) {
2603 content.rejected = true;
2604 }
2605 }
2606 });
2607 } else {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002608 caller()
2609 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2610 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002611 }
deadbeef1dcb1642017-03-29 21:08:16 -07002612 caller()->CreateAndSetAndSignalOffer();
2613 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2614
2615 // Sanity check that the caller's description has a rejected video section.
2616 ASSERT_NE(nullptr, caller()->pc()->local_description());
2617 const ContentInfo* caller_video_content =
2618 GetFirstVideoContent(caller()->pc()->local_description()->description());
2619 ASSERT_NE(nullptr, caller_video_content);
2620 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -07002621 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002622 {
2623 MediaExpectations media_expectations;
2624 media_expectations.ExpectBidirectionalAudio();
2625 media_expectations.ExpectNoVideo();
2626 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2627 }
deadbeef1dcb1642017-03-29 21:08:16 -07002628}
2629
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -07002630// Do one offer/answer with audio, another that disables it (rejecting the m=
2631// section), and another that re-enables it. Regression test for:
2632// bugs.webrtc.org/6023
2633TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
2634 ASSERT_TRUE(CreatePeerConnectionWrappers());
2635 ConnectFakeSignaling();
2636
2637 // Add audio track, do normal offer/answer.
2638 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2639 caller()->CreateLocalAudioTrack();
2640 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2641 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2642 caller()->CreateAndSetAndSignalOffer();
2643 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2644
2645 // Remove audio track, and set offer_to_receive_audio to false to cause the
2646 // m= section to be completely disabled, not just "recvonly".
2647 caller()->pc()->RemoveTrack(sender);
2648 PeerConnectionInterface::RTCOfferAnswerOptions options;
2649 options.offer_to_receive_audio = 0;
2650 caller()->SetOfferAnswerOptions(options);
2651 caller()->CreateAndSetAndSignalOffer();
2652 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2653
2654 // Add the audio track again, expecting negotiation to succeed and frames to
2655 // flow.
2656 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2657 options.offer_to_receive_audio = 1;
2658 caller()->SetOfferAnswerOptions(options);
2659 caller()->CreateAndSetAndSignalOffer();
2660 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2661
2662 MediaExpectations media_expectations;
2663 media_expectations.CalleeExpectsSomeAudio();
2664 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2665}
2666
deadbeef1dcb1642017-03-29 21:08:16 -07002667// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
2668// is needed to support legacy endpoints.
2669// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
2670// add a test for an end-to-end test without MID signaling either (basically,
2671// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002672TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -07002673 ASSERT_TRUE(CreatePeerConnectionWrappers());
2674 ConnectFakeSignaling();
2675 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08002676 caller()->AddAudioVideoTracks();
2677 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07002678 // Remove SSRCs and MSIDs from the received offer SDP.
2679 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07002680 caller()->CreateAndSetAndSignalOffer();
2681 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002682 MediaExpectations media_expectations;
2683 media_expectations.ExpectBidirectionalAudioAndVideo();
2684 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002685}
2686
Seth Hampson5897a6e2018-04-03 11:16:33 -07002687// Basic end-to-end test, without SSRC signaling. This means that the track
2688// was created properly and frames are delivered when the MSIDs are communicated
2689// with a=msid lines and no a=ssrc lines.
2690TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2691 EndToEndCallWithoutSsrcSignaling) {
2692 const char kStreamId[] = "streamId";
2693 ASSERT_TRUE(CreatePeerConnectionWrappers());
2694 ConnectFakeSignaling();
2695 // Add just audio tracks.
2696 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
2697 callee()->AddAudioTrack();
2698
2699 // Remove SSRCs from the received offer SDP.
2700 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
2701 caller()->CreateAndSetAndSignalOffer();
2702 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2703 MediaExpectations media_expectations;
2704 media_expectations.ExpectBidirectionalAudio();
2705 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2706}
2707
Johannes Kron3e983682020-03-29 22:17:00 +02002708TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2709 EndToEndCallAddReceiveVideoToSendOnlyCall) {
2710 ASSERT_TRUE(CreatePeerConnectionWrappers());
2711 ConnectFakeSignaling();
2712 // Add one-directional video, from caller to callee.
2713 rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
2714 caller()->CreateLocalVideoTrack();
2715
2716 RtpTransceiverInit video_transceiver_init;
2717 video_transceiver_init.stream_ids = {"video1"};
2718 video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly;
2719 auto video_sender =
2720 caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue();
2721 caller()->CreateAndSetAndSignalOffer();
2722 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2723
2724 // Add receive direction.
Harald Alvestrand6060df52020-08-11 09:54:02 +02002725 video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);
Johannes Kron3e983682020-03-29 22:17:00 +02002726
2727 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2728 callee()->CreateLocalVideoTrack();
2729
2730 callee()->AddTrack(callee_track);
2731 caller()->CreateAndSetAndSignalOffer();
2732 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2733 // Ensure that video frames are received end-to-end.
2734 MediaExpectations media_expectations;
2735 media_expectations.ExpectBidirectionalVideo();
2736 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2737}
2738
Steve Antondf527fd2018-04-27 15:52:03 -07002739// Tests that video flows between multiple video tracks when SSRCs are not
2740// signaled. This exercises the MID RTP header extension which is needed to
2741// demux the incoming video tracks.
2742TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2743 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
2744 ASSERT_TRUE(CreatePeerConnectionWrappers());
2745 ConnectFakeSignaling();
2746 caller()->AddVideoTrack();
2747 caller()->AddVideoTrack();
2748 callee()->AddVideoTrack();
2749 callee()->AddVideoTrack();
2750
2751 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2752 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2753 caller()->CreateAndSetAndSignalOffer();
2754 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2755 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2756 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2757
2758 // Expect video to be received in both directions on both tracks.
2759 MediaExpectations media_expectations;
2760 media_expectations.ExpectBidirectionalVideo();
2761 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2762}
2763
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -07002764// Used for the test below.
2765void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
2766 RemoveSsrcsAndKeepMsids(desc);
2767 desc->RemoveGroupByName("BUNDLE");
2768 for (ContentInfo& content : desc->contents()) {
2769 cricket::MediaContentDescription* media = content.media_description();
2770 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
2771 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
2772 [](const RtpExtension& extension) {
2773 return extension.uri ==
2774 RtpExtension::kMidUri;
2775 }),
2776 extensions.end());
2777 media->set_rtp_header_extensions(extensions);
2778 }
2779}
2780
2781// Tests that video flows between multiple video tracks when BUNDLE is not used,
2782// SSRCs are not signaled and the MID RTP header extension is not used. This
2783// relies on demuxing by payload type, which normally doesn't work if you have
2784// multiple media sections using the same payload type, but which should work as
2785// long as the media sections aren't bundled.
2786// Regression test for: http://crbug.com/webrtc/12023
2787TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2788 EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid) {
2789 ASSERT_TRUE(CreatePeerConnectionWrappers());
2790 ConnectFakeSignaling();
2791 caller()->AddVideoTrack();
2792 caller()->AddVideoTrack();
2793 callee()->AddVideoTrack();
2794 callee()->AddVideoTrack();
2795 caller()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
2796 callee()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
2797 caller()->CreateAndSetAndSignalOffer();
2798 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2799 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2800 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2801 // Make sure we are not bundled.
2802 ASSERT_NE(caller()->pc()->GetSenders()[0]->dtls_transport(),
2803 caller()->pc()->GetSenders()[1]->dtls_transport());
2804
2805 // Expect video to be received in both directions on both tracks.
2806 MediaExpectations media_expectations;
2807 media_expectations.ExpectBidirectionalVideo();
2808 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2809}
2810
2811// Used for the test below.
2812void ModifyPayloadTypesAndRemoveMidExtension(
2813 cricket::SessionDescription* desc) {
2814 int pt = 96;
2815 for (ContentInfo& content : desc->contents()) {
2816 cricket::MediaContentDescription* media = content.media_description();
2817 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
2818 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
2819 [](const RtpExtension& extension) {
2820 return extension.uri ==
2821 RtpExtension::kMidUri;
2822 }),
2823 extensions.end());
2824 media->set_rtp_header_extensions(extensions);
2825 cricket::VideoContentDescription* video = media->as_video();
2826 ASSERT_TRUE(video != nullptr);
2827 std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
2828 video->set_codecs(codecs);
2829 }
2830}
2831
2832// Tests that two video tracks can be demultiplexed by payload type alone, by
2833// using different payload types for the same codec in different m= sections.
2834// This practice is discouraged but historically has been supported.
2835// Regression test for: http://crbug.com/webrtc/12029
2836TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2837 EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType) {
2838 ASSERT_TRUE(CreatePeerConnectionWrappers());
2839 ConnectFakeSignaling();
2840 caller()->AddVideoTrack();
2841 caller()->AddVideoTrack();
2842 callee()->AddVideoTrack();
2843 callee()->AddVideoTrack();
2844 caller()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
2845 callee()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
2846 // We can't remove SSRCs from the generated SDP because then no send streams
2847 // would be created.
2848 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2849 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2850 caller()->CreateAndSetAndSignalOffer();
2851 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2852 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2853 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2854 // Make sure we are bundled.
2855 ASSERT_EQ(caller()->pc()->GetSenders()[0]->dtls_transport(),
2856 caller()->pc()->GetSenders()[1]->dtls_transport());
2857
2858 // Expect video to be received in both directions on both tracks.
2859 MediaExpectations media_expectations;
2860 media_expectations.ExpectBidirectionalVideo();
2861 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2862}
2863
Henrik Boström5b147782018-12-04 11:25:05 +01002864TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
2865 ASSERT_TRUE(CreatePeerConnectionWrappers());
2866 ConnectFakeSignaling();
2867 caller()->AddAudioTrack();
2868 caller()->AddVideoTrack();
2869 caller()->CreateAndSetAndSignalOffer();
2870 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2871 auto callee_receivers = callee()->pc()->GetReceivers();
2872 ASSERT_EQ(2u, callee_receivers.size());
2873 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
2874 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
2875}
2876
2877TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
2878 ASSERT_TRUE(CreatePeerConnectionWrappers());
2879 ConnectFakeSignaling();
2880 caller()->AddAudioTrack();
2881 caller()->AddVideoTrack();
2882 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2883 caller()->CreateAndSetAndSignalOffer();
2884 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2885 auto callee_receivers = callee()->pc()->GetReceivers();
2886 ASSERT_EQ(2u, callee_receivers.size());
2887 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
2888 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
2889 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
2890 callee_receivers[1]->stream_ids()[0]);
2891 EXPECT_EQ(callee_receivers[0]->streams()[0],
2892 callee_receivers[1]->streams()[0]);
2893}
2894
deadbeef1dcb1642017-03-29 21:08:16 -07002895// Test that if two video tracks are sent (from caller to callee, in this test),
2896// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002897TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07002898 ASSERT_TRUE(CreatePeerConnectionWrappers());
2899 ConnectFakeSignaling();
2900 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08002901 caller()->AddAudioVideoTracks();
2902 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002903 caller()->CreateAndSetAndSignalOffer();
2904 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08002905 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002906
2907 MediaExpectations media_expectations;
2908 media_expectations.CalleeExpectsSomeAudioAndVideo();
2909 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002910}
2911
2912static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
2913 bool first = true;
2914 for (cricket::ContentInfo& content : desc->contents()) {
2915 if (first) {
2916 first = false;
2917 continue;
2918 }
2919 content.bundle_only = true;
2920 }
2921 first = true;
2922 for (cricket::TransportInfo& transport : desc->transport_infos()) {
2923 if (first) {
2924 first = false;
2925 continue;
2926 }
2927 transport.description.ice_ufrag.clear();
2928 transport.description.ice_pwd.clear();
2929 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
2930 transport.description.identity_fingerprint.reset(nullptr);
2931 }
2932}
2933
2934// Test that if applying a true "max bundle" offer, which uses ports of 0,
2935// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
2936// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
2937// successfully and media flows.
2938// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
2939// TODO(deadbeef): Won't need this test once we start generating actual
2940// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002941TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002942 EndToEndCallWithSpecCompliantMaxBundleOffer) {
2943 ASSERT_TRUE(CreatePeerConnectionWrappers());
2944 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002945 caller()->AddAudioVideoTracks();
2946 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002947 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
2948 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
2949 // but the first m= section.
2950 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
2951 caller()->CreateAndSetAndSignalOffer();
2952 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002953 MediaExpectations media_expectations;
2954 media_expectations.ExpectBidirectionalAudioAndVideo();
2955 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002956}
2957
2958// Test that we can receive the audio output level from a remote audio track.
2959// TODO(deadbeef): Use a fake audio source and verify that the output level is
2960// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002961TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002962 ASSERT_TRUE(CreatePeerConnectionWrappers());
2963 ConnectFakeSignaling();
2964 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002965 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002966 caller()->CreateAndSetAndSignalOffer();
2967 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2968
2969 // Get the audio output level stats. Note that the level is not available
2970 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07002971 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002972 kMaxWaitForFramesMs);
2973}
2974
2975// Test that an audio input level is reported.
2976// TODO(deadbeef): Use a fake audio source and verify that the input level is
2977// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002978TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002979 ASSERT_TRUE(CreatePeerConnectionWrappers());
2980 ConnectFakeSignaling();
2981 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002982 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002983 caller()->CreateAndSetAndSignalOffer();
2984 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2985
2986 // Get the audio input level stats. The level should be available very
2987 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07002988 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002989 kMaxWaitForStatsMs);
2990}
2991
2992// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002993TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002994 ASSERT_TRUE(CreatePeerConnectionWrappers());
2995 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002996 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002997 // Do offer/answer, wait for the callee to receive some frames.
2998 caller()->CreateAndSetAndSignalOffer();
2999 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003000
3001 MediaExpectations media_expectations;
3002 media_expectations.CalleeExpectsSomeAudioAndVideo();
3003 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003004
3005 // Get a handle to the remote tracks created, so they can be used as GetStats
3006 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01003007 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08003008 // We received frames, so we definitely should have nonzero "received bytes"
3009 // stats at this point.
3010 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
3011 0);
3012 }
deadbeef1dcb1642017-03-29 21:08:16 -07003013}
3014
3015// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003016TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07003017 ASSERT_TRUE(CreatePeerConnectionWrappers());
3018 ConnectFakeSignaling();
3019 auto audio_track = caller()->CreateLocalAudioTrack();
3020 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08003021 caller()->AddTrack(audio_track);
3022 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07003023 // Do offer/answer, wait for the callee to receive some frames.
3024 caller()->CreateAndSetAndSignalOffer();
3025 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003026 MediaExpectations media_expectations;
3027 media_expectations.CalleeExpectsSomeAudioAndVideo();
3028 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003029
3030 // The callee received frames, so we definitely should have nonzero "sent
3031 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07003032 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
3033 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
3034}
3035
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003036// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003037TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003038 ASSERT_TRUE(CreatePeerConnectionWrappers());
3039 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003040 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003041
Steve Anton15324772018-01-16 10:26:49 -08003042 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003043
3044 // Do offer/answer, wait for the callee to receive some frames.
3045 caller()->CreateAndSetAndSignalOffer();
3046 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3047
3048 // Get the remote audio track created on the receiver, so they can be used as
3049 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08003050 auto receivers = callee()->pc()->GetReceivers();
3051 ASSERT_EQ(1u, receivers.size());
3052 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003053
3054 // Get the audio output level stats. Note that the level is not available
3055 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07003056 EXPECT_TRUE_WAIT(
3057 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
3058 0,
3059 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003060}
3061
Steve Antona41959e2018-11-28 11:15:33 -08003062// Test that the track ID is associated with all local and remote SSRC stats
3063// using the old GetStats() and more than 1 audio and more than 1 video track.
3064// This is a regression test for crbug.com/906988
3065TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3066 OldGetStatsAssociatesTrackIdForManyMediaSections) {
3067 ASSERT_TRUE(CreatePeerConnectionWrappers());
3068 ConnectFakeSignaling();
3069 auto audio_sender_1 = caller()->AddAudioTrack();
3070 auto video_sender_1 = caller()->AddVideoTrack();
3071 auto audio_sender_2 = caller()->AddAudioTrack();
3072 auto video_sender_2 = caller()->AddVideoTrack();
3073 caller()->CreateAndSetAndSignalOffer();
3074 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3075
3076 MediaExpectations media_expectations;
3077 media_expectations.CalleeExpectsSomeAudioAndVideo();
3078 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
3079
3080 std::vector<std::string> track_ids = {
3081 audio_sender_1->track()->id(), video_sender_1->track()->id(),
3082 audio_sender_2->track()->id(), video_sender_2->track()->id()};
3083
3084 auto caller_stats = caller()->OldGetStats();
3085 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
3086 auto callee_stats = callee()->OldGetStats();
3087 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
3088}
3089
Steve Antonffa6ce42018-11-30 09:26:08 -08003090// Test that the new GetStats() returns stats for all outgoing/incoming streams
3091// with the correct track IDs if there are more than one audio and more than one
3092// video senders/receivers.
3093TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
3094 ASSERT_TRUE(CreatePeerConnectionWrappers());
3095 ConnectFakeSignaling();
3096 auto audio_sender_1 = caller()->AddAudioTrack();
3097 auto video_sender_1 = caller()->AddVideoTrack();
3098 auto audio_sender_2 = caller()->AddAudioTrack();
3099 auto video_sender_2 = caller()->AddVideoTrack();
3100 caller()->CreateAndSetAndSignalOffer();
3101 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3102
3103 MediaExpectations media_expectations;
3104 media_expectations.CalleeExpectsSomeAudioAndVideo();
3105 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
3106
3107 std::vector<std::string> track_ids = {
3108 audio_sender_1->track()->id(), video_sender_1->track()->id(),
3109 audio_sender_2->track()->id(), video_sender_2->track()->id()};
3110
3111 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
3112 caller()->NewGetStats();
3113 ASSERT_TRUE(caller_report);
3114 auto outbound_stream_stats =
3115 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
Henrik Boströma0ff50c2020-05-05 15:54:46 +02003116 ASSERT_EQ(outbound_stream_stats.size(), 4u);
Steve Antonffa6ce42018-11-30 09:26:08 -08003117 std::vector<std::string> outbound_track_ids;
3118 for (const auto& stat : outbound_stream_stats) {
3119 ASSERT_TRUE(stat->bytes_sent.is_defined());
3120 EXPECT_LT(0u, *stat->bytes_sent);
Rasmus Brandt2efae772019-06-27 14:29:34 +02003121 if (*stat->kind == "video") {
3122 ASSERT_TRUE(stat->key_frames_encoded.is_defined());
3123 EXPECT_GT(*stat->key_frames_encoded, 0u);
3124 ASSERT_TRUE(stat->frames_encoded.is_defined());
3125 EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
3126 }
Steve Antonffa6ce42018-11-30 09:26:08 -08003127 ASSERT_TRUE(stat->track_id.is_defined());
3128 const auto* track_stat =
3129 caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
3130 ASSERT_TRUE(track_stat);
3131 outbound_track_ids.push_back(*track_stat->track_identifier);
3132 }
3133 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
3134
3135 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
3136 callee()->NewGetStats();
3137 ASSERT_TRUE(callee_report);
3138 auto inbound_stream_stats =
3139 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
3140 ASSERT_EQ(4u, inbound_stream_stats.size());
3141 std::vector<std::string> inbound_track_ids;
3142 for (const auto& stat : inbound_stream_stats) {
3143 ASSERT_TRUE(stat->bytes_received.is_defined());
3144 EXPECT_LT(0u, *stat->bytes_received);
Rasmus Brandt2efae772019-06-27 14:29:34 +02003145 if (*stat->kind == "video") {
3146 ASSERT_TRUE(stat->key_frames_decoded.is_defined());
3147 EXPECT_GT(*stat->key_frames_decoded, 0u);
3148 ASSERT_TRUE(stat->frames_decoded.is_defined());
3149 EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
3150 }
Steve Antonffa6ce42018-11-30 09:26:08 -08003151 ASSERT_TRUE(stat->track_id.is_defined());
3152 const auto* track_stat =
3153 callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
3154 ASSERT_TRUE(track_stat);
3155 inbound_track_ids.push_back(*track_stat->track_identifier);
3156 }
3157 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
3158}
3159
3160// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07003161// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
3162// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003163TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07003164 GetStatsForUnsignaledStreamWithNewStatsApi) {
3165 ASSERT_TRUE(CreatePeerConnectionWrappers());
3166 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003167 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07003168 // Remove SSRCs and MSIDs from the received offer SDP.
3169 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3170 caller()->CreateAndSetAndSignalOffer();
3171 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003172 MediaExpectations media_expectations;
3173 media_expectations.CalleeExpectsSomeAudio(1);
3174 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07003175
3176 // We received a frame, so we should have nonzero "bytes received" stats for
3177 // the unsignaled stream, if stats are working for it.
3178 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
3179 callee()->NewGetStats();
3180 ASSERT_NE(nullptr, report);
3181 auto inbound_stream_stats =
3182 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
3183 ASSERT_EQ(1U, inbound_stream_stats.size());
3184 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
3185 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07003186 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
3187}
3188
Taylor Brandstettera4653442018-06-19 09:44:26 -07003189// Same as above but for the legacy stats implementation.
3190TEST_P(PeerConnectionIntegrationTest,
3191 GetStatsForUnsignaledStreamWithOldStatsApi) {
3192 ASSERT_TRUE(CreatePeerConnectionWrappers());
3193 ConnectFakeSignaling();
3194 caller()->AddAudioTrack();
3195 // Remove SSRCs and MSIDs from the received offer SDP.
3196 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3197 caller()->CreateAndSetAndSignalOffer();
3198 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3199
3200 // Note that, since the old stats implementation associates SSRCs with tracks
3201 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
3202 // associated track ID. So we can't use the track "selector" argument.
3203 //
3204 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
3205 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003206 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07003207 kDefaultTimeout);
3208}
3209
zhihuangf8164932017-05-19 13:09:47 -07003210// Test that we can successfully get the media related stats (audio level
3211// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003212TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07003213 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
3214 ASSERT_TRUE(CreatePeerConnectionWrappers());
3215 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003216 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07003217 // Remove SSRCs and MSIDs from the received offer SDP.
3218 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3219 caller()->CreateAndSetAndSignalOffer();
3220 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003221 MediaExpectations media_expectations;
3222 media_expectations.CalleeExpectsSomeAudio(1);
3223 media_expectations.CalleeExpectsSomeVideo(1);
3224 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07003225
3226 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
3227 callee()->NewGetStats();
3228 ASSERT_NE(nullptr, report);
3229
3230 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3231 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
3232 ASSERT_GE(audio_index, 0);
3233 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07003234}
3235
deadbeef4e2deab2017-09-20 13:56:21 -07003236// Helper for test below.
3237void ModifySsrcs(cricket::SessionDescription* desc) {
3238 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07003239 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08003240 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07003241 for (uint32_t& ssrc : stream.ssrcs) {
3242 ssrc = rtc::CreateRandomId();
3243 }
3244 }
3245 }
3246}
3247
3248// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
3249// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
3250// This should result in two "RTCInboundRTPStreamStats", but only one
3251// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
3252// being reset to 0 once the SSRC change occurs.
3253//
3254// Regression test for this bug:
3255// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
3256//
3257// The bug causes the track stats to only represent one of the two streams:
3258// whichever one has the higher SSRC. So with this bug, there was a 50% chance
3259// that the track stat counters would reset to 0 when the new stream is
3260// received, and a 50% chance that they'll stop updating (while
3261// "concealed_samples" continues increasing, due to silence being generated for
3262// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003263TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08003264 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07003265 ASSERT_TRUE(CreatePeerConnectionWrappers());
3266 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003267 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07003268 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
3269 // that doesn't signal SSRCs (from the callee's perspective).
3270 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3271 caller()->CreateAndSetAndSignalOffer();
3272 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3273 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003274 {
3275 MediaExpectations media_expectations;
3276 media_expectations.CalleeExpectsSomeAudio(50);
3277 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3278 }
deadbeef4e2deab2017-09-20 13:56:21 -07003279 // Some audio frames were received, so we should have nonzero "samples
3280 // received" for the track.
3281 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
3282 callee()->NewGetStats();
3283 ASSERT_NE(nullptr, report);
3284 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3285 ASSERT_EQ(1U, track_stats.size());
3286 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
3287 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
3288 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
3289
3290 // Create a new offer and munge it to cause the caller to use a new SSRC.
3291 caller()->SetGeneratedSdpMunger(ModifySsrcs);
3292 caller()->CreateAndSetAndSignalOffer();
3293 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3294 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
3295 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003296 {
3297 MediaExpectations media_expectations;
3298 media_expectations.CalleeExpectsSomeAudio(25);
3299 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3300 }
deadbeef4e2deab2017-09-20 13:56:21 -07003301
3302 report = callee()->NewGetStats();
3303 ASSERT_NE(nullptr, report);
3304 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3305 ASSERT_EQ(1U, track_stats.size());
3306 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
3307 // The "total samples received" stat should only be greater than it was
3308 // before.
3309 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
3310 // Right now, the new SSRC will cause the counters to reset to 0.
3311 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
3312
3313 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08003314 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07003315 // good sign that we're seeing stats from the old stream that's no longer
3316 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08003317 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07003318 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
3319 EXPECT_LT(*track_stats[0]->concealed_samples,
3320 *track_stats[0]->total_samples_received *
3321 kAcceptableConcealedSamplesPercentage);
3322
3323 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
3324 // sanity check that the SSRC really changed.
3325 // TODO(deadbeef): This isn't working right now, because we're not returning
3326 // *any* stats for the inactive stream. Uncomment when the bug is completely
3327 // fixed.
3328 // auto inbound_stream_stats =
3329 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
3330 // ASSERT_EQ(2U, inbound_stream_stats.size());
3331}
3332
deadbeef1dcb1642017-03-29 21:08:16 -07003333// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003334TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07003335 PeerConnectionFactory::Options dtls_10_options;
3336 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3337 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
3338 dtls_10_options));
3339 ConnectFakeSignaling();
3340 // Do normal offer/answer and wait for some frames to be received in each
3341 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003342 caller()->AddAudioVideoTracks();
3343 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003344 caller()->CreateAndSetAndSignalOffer();
3345 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003346 MediaExpectations media_expectations;
3347 media_expectations.ExpectBidirectionalAudioAndVideo();
3348 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003349}
3350
3351// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003352TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07003353 PeerConnectionFactory::Options dtls_10_options;
3354 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3355 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
3356 dtls_10_options));
3357 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003358 caller()->AddAudioVideoTracks();
3359 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003360 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003361 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07003362 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07003363 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07003364 kDefaultTimeout);
3365 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07003366 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003367 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01003368 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
3369 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
3370 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07003371}
3372
3373// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003374TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07003375 PeerConnectionFactory::Options dtls_12_options;
3376 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3377 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
3378 dtls_12_options));
3379 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003380 caller()->AddAudioVideoTracks();
3381 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003382 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003383 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07003384 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07003385 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07003386 kDefaultTimeout);
3387 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07003388 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003389 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01003390 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
3391 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
3392 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07003393}
3394
3395// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
3396// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003397TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07003398 PeerConnectionFactory::Options caller_options;
3399 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3400 PeerConnectionFactory::Options callee_options;
3401 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3402 ASSERT_TRUE(
3403 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
3404 ConnectFakeSignaling();
3405 // Do normal offer/answer and wait for some frames to be received in each
3406 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003407 caller()->AddAudioVideoTracks();
3408 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003409 caller()->CreateAndSetAndSignalOffer();
3410 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003411 MediaExpectations media_expectations;
3412 media_expectations.ExpectBidirectionalAudioAndVideo();
3413 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003414}
3415
3416// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
3417// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003418TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07003419 PeerConnectionFactory::Options caller_options;
3420 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3421 PeerConnectionFactory::Options callee_options;
3422 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3423 ASSERT_TRUE(
3424 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
3425 ConnectFakeSignaling();
3426 // Do normal offer/answer and wait for some frames to be received in each
3427 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003428 caller()->AddAudioVideoTracks();
3429 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003430 caller()->CreateAndSetAndSignalOffer();
3431 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003432 MediaExpectations media_expectations;
3433 media_expectations.ExpectBidirectionalAudioAndVideo();
3434 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003435}
3436
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003437// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
3438// works as expected; the cipher should only be used if enabled by both sides.
3439TEST_P(PeerConnectionIntegrationTest,
3440 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
3441 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003442 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003443 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003444 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
3445 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003446 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
3447 TestNegotiatedCipherSuite(caller_options, callee_options,
3448 expected_cipher_suite);
3449}
3450
3451TEST_P(PeerConnectionIntegrationTest,
3452 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
3453 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003454 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
3455 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003456 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003457 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003458 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
3459 TestNegotiatedCipherSuite(caller_options, callee_options,
3460 expected_cipher_suite);
3461}
3462
3463TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
3464 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003465 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003466 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003467 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003468 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
3469 TestNegotiatedCipherSuite(caller_options, callee_options,
3470 expected_cipher_suite);
3471}
3472
deadbeef1dcb1642017-03-29 21:08:16 -07003473// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003474TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07003475 bool local_gcm_enabled = false;
3476 bool remote_gcm_enabled = false;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003477 bool aes_ctr_enabled = true;
deadbeef1dcb1642017-03-29 21:08:16 -07003478 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
3479 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003480 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07003481}
3482
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003483// Test that a GCM cipher is used if both ends support it and non-GCM is
3484// disabled.
3485TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07003486 bool local_gcm_enabled = true;
3487 bool remote_gcm_enabled = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003488 bool aes_ctr_enabled = false;
deadbeef1dcb1642017-03-29 21:08:16 -07003489 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
3490 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003491 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07003492}
3493
deadbeef7914b8c2017-04-21 03:23:33 -07003494// Verify that media can be transmitted end-to-end when GCM crypto suites are
3495// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
3496// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
3497// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003498TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07003499 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003500 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003501 gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false;
deadbeef7914b8c2017-04-21 03:23:33 -07003502 ASSERT_TRUE(
3503 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
3504 ConnectFakeSignaling();
3505 // Do normal offer/answer and wait for some frames to be received in each
3506 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003507 caller()->AddAudioVideoTracks();
3508 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003509 caller()->CreateAndSetAndSignalOffer();
3510 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003511 MediaExpectations media_expectations;
3512 media_expectations.ExpectBidirectionalAudioAndVideo();
3513 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003514}
3515
deadbeef1dcb1642017-03-29 21:08:16 -07003516// This test sets up a call between two parties with audio, video and an RTP
3517// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003518TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003519 PeerConnectionInterface::RTCConfiguration rtc_config;
3520 rtc_config.enable_rtp_data_channel = true;
3521 rtc_config.enable_dtls_srtp = false;
3522 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003523 ConnectFakeSignaling();
3524 // Expect that data channel created on caller side will show up for callee as
3525 // well.
3526 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003527 caller()->AddAudioVideoTracks();
3528 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003529 caller()->CreateAndSetAndSignalOffer();
3530 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3531 // Ensure the existence of the RTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003532 MediaExpectations media_expectations;
3533 media_expectations.ExpectBidirectionalAudioAndVideo();
3534 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003535 ASSERT_NE(nullptr, caller()->data_channel());
3536 ASSERT_NE(nullptr, callee()->data_channel());
3537 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3538 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3539
3540 // Ensure data can be sent in both directions.
3541 std::string data = "hello world";
3542 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3543 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3544 kDefaultTimeout);
3545 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3546 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3547 kDefaultTimeout);
3548}
3549
Eldar Rellod9ebe012020-03-18 20:41:45 +02003550TEST_P(PeerConnectionIntegrationTest, RtpDataChannelWorksAfterRollback) {
3551 PeerConnectionInterface::RTCConfiguration rtc_config;
3552 rtc_config.enable_rtp_data_channel = true;
3553 rtc_config.enable_dtls_srtp = false;
3554 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
3555 ConnectFakeSignaling();
3556 auto data_channel = caller()->pc()->CreateDataChannel("label_1", nullptr);
3557 ASSERT_TRUE(data_channel.get() != nullptr);
3558 caller()->CreateAndSetAndSignalOffer();
3559 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3560
3561 caller()->CreateDataChannel("label_2", nullptr);
3562 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
3563 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
3564 caller()->pc()->SetLocalDescription(observer,
3565 caller()->CreateOfferAndWait().release());
3566 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3567 caller()->Rollback();
3568
3569 std::string data = "hello world";
3570 SendRtpDataWithRetries(data_channel, data, 5);
3571 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3572 kDefaultTimeout);
3573}
3574
deadbeef1dcb1642017-03-29 21:08:16 -07003575// Ensure that an RTP data channel is signaled as closed for the caller when
3576// the callee rejects it in a subsequent offer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003577TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003578 RtpDataChannelSignaledClosedInCalleeOffer) {
3579 // Same procedure as above test.
Niels Möllerf06f9232018-08-07 12:32:18 +02003580 PeerConnectionInterface::RTCConfiguration rtc_config;
3581 rtc_config.enable_rtp_data_channel = true;
3582 rtc_config.enable_dtls_srtp = false;
3583 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003584 ConnectFakeSignaling();
3585 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003586 caller()->AddAudioVideoTracks();
3587 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003588 caller()->CreateAndSetAndSignalOffer();
3589 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3590 ASSERT_NE(nullptr, caller()->data_channel());
3591 ASSERT_NE(nullptr, callee()->data_channel());
3592 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3593 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3594
3595 // Close the data channel on the callee, and do an updated offer/answer.
3596 callee()->data_channel()->Close();
3597 callee()->CreateAndSetAndSignalOffer();
3598 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3599 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3600 EXPECT_FALSE(callee()->data_observer()->IsOpen());
3601}
3602
3603// Tests that data is buffered in an RTP data channel until an observer is
3604// registered for it.
3605//
3606// NOTE: RTP data channels can receive data before the underlying
3607// transport has detected that a channel is writable and thus data can be
3608// received before the data channel state changes to open. That is hard to test
3609// but the same buffering is expected to be used in that case.
Yves Gerey100fe632020-01-17 19:15:53 +01003610//
3611// Use fake clock and simulated network delay so that we predictably can wait
3612// until an SCTP message has been delivered without "sleep()"ing.
3613TEST_P(PeerConnectionIntegrationTestWithFakeClock,
deadbeef1dcb1642017-03-29 21:08:16 -07003614 DataBufferedUntilRtpDataChannelObserverRegistered) {
deadbeef1dcb1642017-03-29 21:08:16 -07003615 virtual_socket_server()->set_delay_mean(5); // 5 ms per hop.
3616 virtual_socket_server()->UpdateDelayDistribution();
3617
Niels Möllerf06f9232018-08-07 12:32:18 +02003618 PeerConnectionInterface::RTCConfiguration rtc_config;
3619 rtc_config.enable_rtp_data_channel = true;
3620 rtc_config.enable_dtls_srtp = false;
3621 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003622 ConnectFakeSignaling();
3623 caller()->CreateDataChannel();
3624 caller()->CreateAndSetAndSignalOffer();
3625 ASSERT_TRUE(caller()->data_channel() != nullptr);
3626 ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr,
Yves Gerey100fe632020-01-17 19:15:53 +01003627 kDefaultTimeout, FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003628 ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(),
Yves Gerey100fe632020-01-17 19:15:53 +01003629 kDefaultTimeout, FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003630 ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen,
3631 callee()->data_channel()->state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01003632 FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003633
3634 // Unregister the observer which is normally automatically registered.
3635 callee()->data_channel()->UnregisterObserver();
3636 // Send data and advance fake clock until it should have been received.
3637 std::string data = "hello world";
3638 caller()->data_channel()->Send(DataBuffer(data));
Yves Gerey100fe632020-01-17 19:15:53 +01003639 SIMULATED_WAIT(false, 50, FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003640
3641 // Attach data channel and expect data to be received immediately. Note that
3642 // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any
3643 // further, but data can be received even if the callback is asynchronous.
3644 MockDataChannelObserver new_observer(callee()->data_channel());
3645 EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01003646 FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003647}
3648
3649// This test sets up a call between two parties with audio, video and but only
3650// the caller client supports RTP data channels.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003651TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003652 PeerConnectionInterface::RTCConfiguration rtc_config_1;
3653 rtc_config_1.enable_rtp_data_channel = true;
deadbeef1dcb1642017-03-29 21:08:16 -07003654 // Must disable DTLS to make negotiation succeed.
Niels Möllerf06f9232018-08-07 12:32:18 +02003655 rtc_config_1.enable_dtls_srtp = false;
3656 PeerConnectionInterface::RTCConfiguration rtc_config_2;
3657 rtc_config_2.enable_dtls_srtp = false;
3658 rtc_config_2.enable_dtls_srtp = false;
3659 ASSERT_TRUE(
3660 CreatePeerConnectionWrappersWithConfig(rtc_config_1, rtc_config_2));
deadbeef1dcb1642017-03-29 21:08:16 -07003661 ConnectFakeSignaling();
3662 caller()->CreateDataChannel();
Harald Alvestrandf3736ed2019-04-08 13:09:30 +02003663 ASSERT_TRUE(caller()->data_channel() != nullptr);
Steve Anton15324772018-01-16 10:26:49 -08003664 caller()->AddAudioVideoTracks();
3665 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003666 caller()->CreateAndSetAndSignalOffer();
3667 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3668 // The caller should still have a data channel, but it should be closed, and
3669 // one should ever have been created for the callee.
3670 EXPECT_TRUE(caller()->data_channel() != nullptr);
3671 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3672 EXPECT_EQ(nullptr, callee()->data_channel());
3673}
3674
3675// This test sets up a call between two parties with audio, and video. When
3676// audio and video is setup and flowing, an RTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003677TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003678 PeerConnectionInterface::RTCConfiguration rtc_config;
3679 rtc_config.enable_rtp_data_channel = true;
3680 rtc_config.enable_dtls_srtp = false;
3681 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003682 ConnectFakeSignaling();
3683 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003684 caller()->AddAudioVideoTracks();
3685 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003686 caller()->CreateAndSetAndSignalOffer();
3687 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3688 // Create data channel and do new offer and answer.
3689 caller()->CreateDataChannel();
3690 caller()->CreateAndSetAndSignalOffer();
3691 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3692 ASSERT_NE(nullptr, caller()->data_channel());
3693 ASSERT_NE(nullptr, callee()->data_channel());
3694 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3695 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3696 // Ensure data can be sent in both directions.
3697 std::string data = "hello world";
3698 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3699 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3700 kDefaultTimeout);
3701 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3702 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3703 kDefaultTimeout);
3704}
3705
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01003706#ifdef WEBRTC_HAVE_SCTP
deadbeef1dcb1642017-03-29 21:08:16 -07003707
3708// This test sets up a call between two parties with audio, video and an SCTP
3709// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003710TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003711 ASSERT_TRUE(CreatePeerConnectionWrappers());
3712 ConnectFakeSignaling();
3713 // Expect that data channel created on caller side will show up for callee as
3714 // well.
3715 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003716 caller()->AddAudioVideoTracks();
3717 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003718 caller()->CreateAndSetAndSignalOffer();
3719 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3720 // Ensure the existence of the SCTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003721 MediaExpectations media_expectations;
3722 media_expectations.ExpectBidirectionalAudioAndVideo();
3723 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003724 // Caller data channel should already exist (it created one). Callee data
3725 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3726 ASSERT_NE(nullptr, caller()->data_channel());
3727 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3728 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3729 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3730
3731 // Ensure data can be sent in both directions.
3732 std::string data = "hello world";
3733 caller()->data_channel()->Send(DataBuffer(data));
3734 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3735 kDefaultTimeout);
3736 callee()->data_channel()->Send(DataBuffer(data));
3737 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3738 kDefaultTimeout);
3739}
3740
3741// Ensure that when the callee closes an SCTP data channel, the closing
3742// procedure results in the data channel being closed for the caller as well.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003743TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003744 // Same procedure as above test.
3745 ASSERT_TRUE(CreatePeerConnectionWrappers());
3746 ConnectFakeSignaling();
3747 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003748 caller()->AddAudioVideoTracks();
3749 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003750 caller()->CreateAndSetAndSignalOffer();
3751 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3752 ASSERT_NE(nullptr, caller()->data_channel());
3753 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3754 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3755 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3756
3757 // Close the data channel on the callee side, and wait for it to reach the
3758 // "closed" state on both sides.
3759 callee()->data_channel()->Close();
3760 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3761 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3762}
3763
Seth Hampson2f0d7022018-02-20 11:54:42 -08003764TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
Steve Antonda6c0952017-10-23 11:41:54 -07003765 ASSERT_TRUE(CreatePeerConnectionWrappers());
3766 ConnectFakeSignaling();
3767 webrtc::DataChannelInit init;
3768 init.id = 53;
3769 init.maxRetransmits = 52;
3770 caller()->CreateDataChannel("data-channel", &init);
Steve Anton15324772018-01-16 10:26:49 -08003771 caller()->AddAudioVideoTracks();
3772 callee()->AddAudioVideoTracks();
Steve Antonda6c0952017-10-23 11:41:54 -07003773 caller()->CreateAndSetAndSignalOffer();
3774 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton074dece2017-10-24 13:04:12 -07003775 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3776 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Harald Alvestrand5c4d2ee2019-04-01 12:58:15 +02003777 // Since "negotiated" is false, the "id" parameter should be ignored.
3778 EXPECT_NE(init.id, callee()->data_channel()->id());
Steve Antonda6c0952017-10-23 11:41:54 -07003779 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3780 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3781 EXPECT_FALSE(callee()->data_channel()->negotiated());
3782}
3783
deadbeef1dcb1642017-03-29 21:08:16 -07003784// Test usrsctp's ability to process unordered data stream, where data actually
3785// arrives out of order using simulated delays. Previously there have been some
3786// bugs in this area.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003787TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003788 // Introduce random network delays.
3789 // Otherwise it's not a true "unordered" test.
3790 virtual_socket_server()->set_delay_mean(20);
3791 virtual_socket_server()->set_delay_stddev(5);
3792 virtual_socket_server()->UpdateDelayDistribution();
3793 // Normal procedure, but with unordered data channel config.
3794 ASSERT_TRUE(CreatePeerConnectionWrappers());
3795 ConnectFakeSignaling();
3796 webrtc::DataChannelInit init;
3797 init.ordered = false;
3798 caller()->CreateDataChannel(&init);
3799 caller()->CreateAndSetAndSignalOffer();
3800 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3801 ASSERT_NE(nullptr, caller()->data_channel());
3802 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3803 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3804 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3805
3806 static constexpr int kNumMessages = 100;
3807 // Deliberately chosen to be larger than the MTU so messages get fragmented.
3808 static constexpr size_t kMaxMessageSize = 4096;
3809 // Create and send random messages.
3810 std::vector<std::string> sent_messages;
3811 for (int i = 0; i < kNumMessages; ++i) {
3812 size_t length =
3813 (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand)
3814 std::string message;
3815 ASSERT_TRUE(rtc::CreateRandomString(length, &message));
3816 caller()->data_channel()->Send(DataBuffer(message));
3817 callee()->data_channel()->Send(DataBuffer(message));
3818 sent_messages.push_back(message);
3819 }
3820
3821 // Wait for all messages to be received.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003822 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003823 caller()->data_observer()->received_message_count(),
3824 kDefaultTimeout);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003825 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003826 callee()->data_observer()->received_message_count(),
3827 kDefaultTimeout);
3828
3829 // Sort and compare to make sure none of the messages were corrupted.
3830 std::vector<std::string> caller_received_messages =
3831 caller()->data_observer()->messages();
3832 std::vector<std::string> callee_received_messages =
3833 callee()->data_observer()->messages();
Steve Anton64b626b2019-01-28 17:25:26 -08003834 absl::c_sort(sent_messages);
3835 absl::c_sort(caller_received_messages);
3836 absl::c_sort(callee_received_messages);
deadbeef1dcb1642017-03-29 21:08:16 -07003837 EXPECT_EQ(sent_messages, caller_received_messages);
3838 EXPECT_EQ(sent_messages, callee_received_messages);
3839}
3840
3841// This test sets up a call between two parties with audio, and video. When
3842// audio and video are setup and flowing, an SCTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003843TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07003844 ASSERT_TRUE(CreatePeerConnectionWrappers());
3845 ConnectFakeSignaling();
3846 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003847 caller()->AddAudioVideoTracks();
3848 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003849 caller()->CreateAndSetAndSignalOffer();
3850 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3851 // Create data channel and do new offer and answer.
3852 caller()->CreateDataChannel();
3853 caller()->CreateAndSetAndSignalOffer();
3854 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3855 // Caller data channel should already exist (it created one). Callee data
3856 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3857 ASSERT_NE(nullptr, caller()->data_channel());
3858 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3859 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3860 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3861 // Ensure data can be sent in both directions.
3862 std::string data = "hello world";
3863 caller()->data_channel()->Send(DataBuffer(data));
3864 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3865 kDefaultTimeout);
3866 callee()->data_channel()->Send(DataBuffer(data));
3867 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3868 kDefaultTimeout);
3869}
3870
deadbeef7914b8c2017-04-21 03:23:33 -07003871// Set up a connection initially just using SCTP data channels, later upgrading
3872// to audio/video, ensuring frames are received end-to-end. Effectively the
3873// inverse of the test above.
3874// This was broken in M57; see https://crbug.com/711243
Seth Hampson2f0d7022018-02-20 11:54:42 -08003875TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
deadbeef7914b8c2017-04-21 03:23:33 -07003876 ASSERT_TRUE(CreatePeerConnectionWrappers());
3877 ConnectFakeSignaling();
3878 // Do initial offer/answer with just data channel.
3879 caller()->CreateDataChannel();
3880 caller()->CreateAndSetAndSignalOffer();
3881 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3882 // Wait until data can be sent over the data channel.
3883 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3884 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3885 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3886
3887 // Do subsequent offer/answer with two-way audio and video. Audio and video
3888 // should end up bundled on the DTLS/ICE transport already used for data.
Steve Anton15324772018-01-16 10:26:49 -08003889 caller()->AddAudioVideoTracks();
3890 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003891 caller()->CreateAndSetAndSignalOffer();
3892 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003893 MediaExpectations media_expectations;
3894 media_expectations.ExpectBidirectionalAudioAndVideo();
3895 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003896}
3897
deadbeef8b7e9ad2017-05-25 09:38:55 -07003898static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
Harald Alvestrand5fc28b12019-05-13 13:36:16 +02003899 cricket::SctpDataContentDescription* dcd_offer =
3900 GetFirstSctpDataContentDescription(desc);
Harald Alvestrand17ea0682019-12-13 11:51:04 +01003901 // See https://crbug.com/webrtc/11211 - this function is a no-op
Steve Antonb1c1de12017-12-21 15:14:30 -08003902 ASSERT_TRUE(dcd_offer);
deadbeef8b7e9ad2017-05-25 09:38:55 -07003903 dcd_offer->set_use_sctpmap(false);
3904 dcd_offer->set_protocol("UDP/DTLS/SCTP");
3905}
3906
3907// Test that the data channel works when a spec-compliant SCTP m= section is
3908// offered (using "a=sctp-port" instead of "a=sctpmap", and using
3909// "UDP/DTLS/SCTP" as the protocol).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003910TEST_P(PeerConnectionIntegrationTest,
deadbeef8b7e9ad2017-05-25 09:38:55 -07003911 DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
3912 ASSERT_TRUE(CreatePeerConnectionWrappers());
3913 ConnectFakeSignaling();
3914 caller()->CreateDataChannel();
3915 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
3916 caller()->CreateAndSetAndSignalOffer();
3917 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3918 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3919 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3920 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3921
3922 // Ensure data can be sent in both directions.
3923 std::string data = "hello world";
3924 caller()->data_channel()->Send(DataBuffer(data));
3925 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3926 kDefaultTimeout);
3927 callee()->data_channel()->Send(DataBuffer(data));
3928 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3929 kDefaultTimeout);
3930}
3931
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01003932#endif // WEBRTC_HAVE_SCTP
deadbeef1dcb1642017-03-29 21:08:16 -07003933
3934// Test that the ICE connection and gathering states eventually reach
3935// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08003936TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07003937 ASSERT_TRUE(CreatePeerConnectionWrappers());
3938 ConnectFakeSignaling();
3939 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08003940 caller()->AddAudioVideoTracks();
3941 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003942 caller()->CreateAndSetAndSignalOffer();
3943 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3944 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3945 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
3946 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3947 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
3948 // After the best candidate pair is selected and all candidates are signaled,
3949 // the ICE connection state should reach "complete".
3950 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
3951 // answerer/"callee" by default) only reaches "connected". When this is
3952 // fixed, this test should be updated.
3953 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3954 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00003955 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3956 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07003957}
3958
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003959constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
3960 cricket::PORTALLOCATOR_DISABLE_RELAY |
3961 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003962
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003963// Use a mock resolver to resolve the hostname back to the original IP on both
3964// sides and check that the ICE connection connects.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003965TEST_P(PeerConnectionIntegrationTest,
3966 IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003967 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003968 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003969 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003970 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003971 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
3972 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003973
3974 // This also verifies that the injected AsyncResolverFactory is used by
3975 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003976 EXPECT_CALL(*caller_resolver_factory, Create())
3977 .WillOnce(Return(&caller_async_resolver));
3978 webrtc::PeerConnectionDependencies caller_deps(nullptr);
3979 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
3980
3981 EXPECT_CALL(*callee_resolver_factory, Create())
3982 .WillOnce(Return(&callee_async_resolver));
3983 webrtc::PeerConnectionDependencies callee_deps(nullptr);
3984 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
3985
3986 PeerConnectionInterface::RTCConfiguration config;
3987 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3988 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3989
3990 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
3991 config, std::move(caller_deps), config, std::move(callee_deps)));
3992
3993 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
3994 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
3995
3996 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07003997 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003998 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07003999 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004000 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004001
4002 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004003
4004 ConnectFakeSignaling();
4005 caller()->AddAudioVideoTracks();
4006 callee()->AddAudioVideoTracks();
4007 caller()->CreateAndSetAndSignalOffer();
4008 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4009 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4010 caller()->ice_connection_state(), kDefaultTimeout);
4011 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4012 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08004013
Ying Wangef3998f2019-12-09 13:06:53 +01004014 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
4015 "WebRTC.PeerConnection.CandidatePairType_UDP",
4016 webrtc::kIceCandidatePairHostNameHostName));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004017}
4018
Steve Antonede9ca52017-10-16 13:04:27 -07004019// Test that firewalling the ICE connection causes the clients to identify the
4020// disconnected state and then removing the firewall causes them to reconnect.
4021class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08004022 : public PeerConnectionIntegrationBaseTest,
4023 public ::testing::WithParamInterface<
4024 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07004025 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08004026 PeerConnectionIntegrationIceStatesTest()
4027 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
4028 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07004029 }
4030
4031 void StartStunServer(const SocketAddress& server_address) {
4032 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01004033 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07004034 }
4035
4036 bool TestIPv6() {
4037 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
4038 }
4039
4040 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004041 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
4042 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07004043 }
4044
4045 std::vector<SocketAddress> CallerAddresses() {
4046 std::vector<SocketAddress> addresses;
4047 addresses.push_back(SocketAddress("1.1.1.1", 0));
4048 if (TestIPv6()) {
4049 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
4050 }
4051 return addresses;
4052 }
4053
4054 std::vector<SocketAddress> CalleeAddresses() {
4055 std::vector<SocketAddress> addresses;
4056 addresses.push_back(SocketAddress("2.2.2.2", 0));
4057 if (TestIPv6()) {
4058 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
4059 }
4060 return addresses;
4061 }
4062
4063 void SetUpNetworkInterfaces() {
4064 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07004065 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
4066 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07004067
4068 // Add network addresses for test.
4069 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07004070 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07004071 }
4072 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07004073 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07004074 }
4075 }
4076
4077 private:
4078 uint32_t port_allocator_flags_;
4079 std::unique_ptr<cricket::TestStunServer> stun_server_;
4080};
4081
Yves Gerey100fe632020-01-17 19:15:53 +01004082// Ensure FakeClockForTest is constructed first (see class for rationale).
4083class PeerConnectionIntegrationIceStatesTestWithFakeClock
4084 : public FakeClockForTest,
4085 public PeerConnectionIntegrationIceStatesTest {};
4086
Steve Antonede9ca52017-10-16 13:04:27 -07004087// Tests that the PeerConnection goes through all the ICE gathering/connection
4088// states over the duration of the call. This includes Disconnected and Failed
4089// states, induced by putting a firewall between the peers and waiting for them
4090// to time out.
Yves Gerey100fe632020-01-17 19:15:53 +01004091TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock, VerifyIceStates) {
Steve Antonede9ca52017-10-16 13:04:27 -07004092 const SocketAddress kStunServerAddress =
4093 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
4094 StartStunServer(kStunServerAddress);
4095
4096 PeerConnectionInterface::RTCConfiguration config;
4097 PeerConnectionInterface::IceServer ice_stun_server;
4098 ice_stun_server.urls.push_back(
4099 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
4100 kStunServerAddress.PortAsString());
4101 config.servers.push_back(ice_stun_server);
4102
4103 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
4104 ConnectFakeSignaling();
4105 SetPortAllocatorFlags();
4106 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08004107 caller()->AddAudioVideoTracks();
4108 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004109
4110 // Initial state before anything happens.
4111 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
4112 caller()->ice_gathering_state());
4113 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
4114 caller()->ice_connection_state());
Jonas Olsson7a6739e2019-01-15 16:31:55 +01004115 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
4116 caller()->standardized_ice_connection_state());
Steve Antonede9ca52017-10-16 13:04:27 -07004117
4118 // Start the call by creating the offer, setting it as the local description,
4119 // then sending it to the peer who will respond with an answer. This happens
4120 // asynchronously so that we can watch the states as it runs in the
4121 // background.
4122 caller()->CreateAndSetAndSignalOffer();
4123
Steve Antona9b67ce2020-01-16 14:00:44 -08004124 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4125 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004126 FakeClock());
Steve Antona9b67ce2020-01-16 14:00:44 -08004127 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4128 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004129 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004130
4131 // Verify that the observer was notified of the intermediate transitions.
4132 EXPECT_THAT(caller()->ice_connection_state_history(),
4133 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
4134 PeerConnectionInterface::kIceConnectionConnected,
4135 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olssonacd8ae72019-02-25 15:26:24 +01004136 EXPECT_THAT(caller()->standardized_ice_connection_state_history(),
4137 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
4138 PeerConnectionInterface::kIceConnectionConnected,
4139 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olsson635474e2018-10-18 15:58:17 +02004140 EXPECT_THAT(
4141 caller()->peer_connection_state_history(),
4142 ElementsAre(PeerConnectionInterface::PeerConnectionState::kConnecting,
Jonas Olsson635474e2018-10-18 15:58:17 +02004143 PeerConnectionInterface::PeerConnectionState::kConnected));
Steve Antonede9ca52017-10-16 13:04:27 -07004144 EXPECT_THAT(caller()->ice_gathering_state_history(),
4145 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
4146 PeerConnectionInterface::kIceGatheringComplete));
4147
4148 // Block connections to/from the caller and wait for ICE to become
4149 // disconnected.
4150 for (const auto& caller_address : CallerAddresses()) {
4151 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4152 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01004153 RTC_LOG(LS_INFO) << "Firewall rules applied";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004154 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
4155 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004156 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004157 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
4158 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004159 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004160
4161 // Let ICE re-establish by removing the firewall rules.
4162 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01004163 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004164 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4165 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004166 FakeClock());
Jonas Olssonacd8ae72019-02-25 15:26:24 +01004167 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004168 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004169 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004170
4171 // According to RFC7675, if there is no response within 30 seconds then the
4172 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08004173 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07004174 constexpr int kConsentTimeout = 30000;
4175 for (const auto& caller_address : CallerAddresses()) {
4176 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4177 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01004178 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004179 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4180 caller()->ice_connection_state(), kConsentTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004181 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004182 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4183 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004184 kConsentTimeout, FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004185}
4186
4187// Tests that if the connection doesn't get set up properly we eventually reach
4188// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01004189TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
4190 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004191 // Block connections to/from the caller and wait for ICE to become
4192 // disconnected.
4193 for (const auto& caller_address : CallerAddresses()) {
4194 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4195 }
4196
4197 ASSERT_TRUE(CreatePeerConnectionWrappers());
4198 ConnectFakeSignaling();
4199 SetPortAllocatorFlags();
4200 SetUpNetworkInterfaces();
4201 caller()->AddAudioVideoTracks();
4202 caller()->CreateAndSetAndSignalOffer();
4203
4204 // According to RFC7675, if there is no response within 30 seconds then the
4205 // peer should consider the other side to have rejected the connection. This
4206 // is signaled by the state transitioning to "failed".
4207 constexpr int kConsentTimeout = 30000;
4208 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4209 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004210 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004211}
4212
4213// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
4214// and that the statistics in the metric observers are updated correctly.
4215TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) {
4216 ASSERT_TRUE(CreatePeerConnectionWrappers());
4217 ConnectFakeSignaling();
4218 SetPortAllocatorFlags();
4219 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08004220 caller()->AddAudioVideoTracks();
4221 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004222 caller()->CreateAndSetAndSignalOffer();
4223
4224 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08004225 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4226 caller()->ice_connection_state(), kDefaultTimeout);
4227 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4228 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07004229
Qingsi Wang7fc821d2018-07-12 12:54:53 -07004230 // TODO(bugs.webrtc.org/9456): Fix it.
4231 const int num_best_ipv4 = webrtc::metrics::NumEvents(
4232 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
4233 const int num_best_ipv6 = webrtc::metrics::NumEvents(
4234 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004235 if (TestIPv6()) {
4236 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
4237 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01004238 EXPECT_METRIC_EQ(0, num_best_ipv4);
4239 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004240 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01004241 EXPECT_METRIC_EQ(1, num_best_ipv4);
4242 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004243 }
4244
Ying Wangef3998f2019-12-09 13:06:53 +01004245 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
4246 "WebRTC.PeerConnection.CandidatePairType_UDP",
4247 webrtc::kIceCandidatePairHostHost));
4248 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
4249 "WebRTC.PeerConnection.CandidatePairType_UDP",
4250 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07004251}
4252
4253constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
4254 cricket::PORTALLOCATOR_DISABLE_STUN |
4255 cricket::PORTALLOCATOR_DISABLE_RELAY;
4256constexpr uint32_t kFlagsIPv6NoStun =
4257 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
4258 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
4259constexpr uint32_t kFlagsIPv4Stun =
4260 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
4261
Mirko Bonadeic84f6612019-01-31 12:20:57 +01004262INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004263 PeerConnectionIntegrationTest,
4264 PeerConnectionIntegrationIceStatesTest,
4265 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4266 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
4267 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
4268 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07004269
Yves Gerey100fe632020-01-17 19:15:53 +01004270INSTANTIATE_TEST_SUITE_P(
4271 PeerConnectionIntegrationTest,
4272 PeerConnectionIntegrationIceStatesTestWithFakeClock,
4273 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4274 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
4275 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
4276 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
4277
deadbeef1dcb1642017-03-29 21:08:16 -07004278// This test sets up a call between two parties with audio and video.
4279// During the call, the caller restarts ICE and the test verifies that
4280// new ICE candidates are generated and audio and video still can flow, and the
4281// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004282TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07004283 ASSERT_TRUE(CreatePeerConnectionWrappers());
4284 ConnectFakeSignaling();
4285 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08004286 caller()->AddAudioVideoTracks();
4287 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004288 caller()->CreateAndSetAndSignalOffer();
4289 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4290 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4291 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00004292 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4293 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07004294
4295 // To verify that the ICE restart actually occurs, get
4296 // ufrag/password/candidates before and after restart.
4297 // Create an SDP string of the first audio candidate for both clients.
4298 const webrtc::IceCandidateCollection* audio_candidates_caller =
4299 caller()->pc()->local_description()->candidates(0);
4300 const webrtc::IceCandidateCollection* audio_candidates_callee =
4301 callee()->pc()->local_description()->candidates(0);
4302 ASSERT_GT(audio_candidates_caller->count(), 0u);
4303 ASSERT_GT(audio_candidates_callee->count(), 0u);
4304 std::string caller_candidate_pre_restart;
4305 ASSERT_TRUE(
4306 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
4307 std::string callee_candidate_pre_restart;
4308 ASSERT_TRUE(
4309 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
4310 const cricket::SessionDescription* desc =
4311 caller()->pc()->local_description()->description();
4312 std::string caller_ufrag_pre_restart =
4313 desc->transport_infos()[0].description.ice_ufrag;
4314 desc = callee()->pc()->local_description()->description();
4315 std::string callee_ufrag_pre_restart =
4316 desc->transport_infos()[0].description.ice_ufrag;
4317
Alex Drake00c7ecf2019-08-06 10:54:47 -07004318 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07004319 // Have the caller initiate an ICE restart.
4320 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
4321 caller()->CreateAndSetAndSignalOffer();
4322 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4323 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4324 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00004325 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07004326 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4327
4328 // Grab the ufrags/candidates again.
4329 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
4330 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
4331 ASSERT_GT(audio_candidates_caller->count(), 0u);
4332 ASSERT_GT(audio_candidates_callee->count(), 0u);
4333 std::string caller_candidate_post_restart;
4334 ASSERT_TRUE(
4335 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
4336 std::string callee_candidate_post_restart;
4337 ASSERT_TRUE(
4338 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
4339 desc = caller()->pc()->local_description()->description();
4340 std::string caller_ufrag_post_restart =
4341 desc->transport_infos()[0].description.ice_ufrag;
4342 desc = callee()->pc()->local_description()->description();
4343 std::string callee_ufrag_post_restart =
4344 desc->transport_infos()[0].description.ice_ufrag;
4345 // Sanity check that an ICE restart was actually negotiated in SDP.
4346 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
4347 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
4348 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
4349 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07004350 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07004351
4352 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004353 MediaExpectations media_expectations;
4354 media_expectations.ExpectBidirectionalAudioAndVideo();
4355 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004356}
4357
4358// Verify that audio/video can be received end-to-end when ICE renomination is
4359// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004360TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07004361 PeerConnectionInterface::RTCConfiguration config;
4362 config.enable_ice_renomination = true;
4363 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
4364 ConnectFakeSignaling();
4365 // Do normal offer/answer and wait for some frames to be received in each
4366 // direction.
Steve Anton15324772018-01-16 10:26:49 -08004367 caller()->AddAudioVideoTracks();
4368 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004369 caller()->CreateAndSetAndSignalOffer();
4370 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4371 // Sanity check that ICE renomination was actually negotiated.
4372 const cricket::SessionDescription* desc =
4373 caller()->pc()->local_description()->description();
4374 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08004375 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07004376 }
4377 desc = callee()->pc()->local_description()->description();
4378 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08004379 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07004380 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08004381 MediaExpectations media_expectations;
4382 media_expectations.ExpectBidirectionalAudioAndVideo();
4383 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004384}
4385
Steve Anton6f25b092017-10-23 09:39:20 -07004386// With a max bundle policy and RTCP muxing, adding a new media description to
4387// the connection should not affect ICE at all because the new media will use
4388// the existing connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004389TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08004390 AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07004391 PeerConnectionInterface::RTCConfiguration config;
4392 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
4393 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
4394 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
4395 config, PeerConnectionInterface::RTCConfiguration()));
4396 ConnectFakeSignaling();
4397
Steve Anton15324772018-01-16 10:26:49 -08004398 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07004399 caller()->CreateAndSetAndSignalOffer();
4400 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07004401 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4402 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07004403
4404 caller()->clear_ice_connection_state_history();
4405
Steve Anton15324772018-01-16 10:26:49 -08004406 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07004407 caller()->CreateAndSetAndSignalOffer();
4408 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4409
4410 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
4411}
4412
deadbeef1dcb1642017-03-29 21:08:16 -07004413// This test sets up a call between two parties with audio and video. It then
4414// renegotiates setting the video m-line to "port 0", then later renegotiates
4415// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004416TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07004417 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
4418 ASSERT_TRUE(CreatePeerConnectionWrappers());
4419 ConnectFakeSignaling();
4420
4421 // Do initial negotiation, only sending media from the caller. Will result in
4422 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08004423 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004424 caller()->CreateAndSetAndSignalOffer();
4425 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4426
4427 // Negotiate again, disabling the video "m=" section (the callee will set the
4428 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08004429 if (sdp_semantics_ == SdpSemantics::kPlanB) {
4430 PeerConnectionInterface::RTCOfferAnswerOptions options;
4431 options.offer_to_receive_video = 0;
4432 callee()->SetOfferAnswerOptions(options);
4433 } else {
4434 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02004435 callee()
4436 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
4437 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08004438 });
4439 }
deadbeef1dcb1642017-03-29 21:08:16 -07004440 caller()->CreateAndSetAndSignalOffer();
4441 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4442 // Sanity check that video "m=" section was actually rejected.
4443 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
4444 callee()->pc()->local_description()->description());
4445 ASSERT_NE(nullptr, answer_video_content);
4446 ASSERT_TRUE(answer_video_content->rejected);
4447
4448 // Enable video and do negotiation again, making sure video is received
4449 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004450 if (sdp_semantics_ == SdpSemantics::kPlanB) {
4451 PeerConnectionInterface::RTCOfferAnswerOptions options;
4452 options.offer_to_receive_video = 1;
4453 callee()->SetOfferAnswerOptions(options);
4454 } else {
4455 // The caller's transceiver is stopped, so we need to add another track.
4456 auto caller_transceiver =
4457 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02004458 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08004459 caller()->AddVideoTrack();
4460 }
4461 callee()->AddVideoTrack();
4462 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07004463 caller()->CreateAndSetAndSignalOffer();
4464 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004465
deadbeef1dcb1642017-03-29 21:08:16 -07004466 // Verify the caller receives frames from the newly added stream, and the
4467 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004468 MediaExpectations media_expectations;
4469 media_expectations.CalleeExpectsSomeAudio();
4470 media_expectations.ExpectBidirectionalVideo();
4471 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004472}
4473
deadbeef1dcb1642017-03-29 21:08:16 -07004474// This tests that if we negotiate after calling CreateSender but before we
4475// have a track, then set a track later, frames from the newly-set track are
4476// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004477TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07004478 MediaFlowsAfterEarlyWarmupWithCreateSender) {
4479 ASSERT_TRUE(CreatePeerConnectionWrappers());
4480 ConnectFakeSignaling();
4481 auto caller_audio_sender =
4482 caller()->pc()->CreateSender("audio", "caller_stream");
4483 auto caller_video_sender =
4484 caller()->pc()->CreateSender("video", "caller_stream");
4485 auto callee_audio_sender =
4486 callee()->pc()->CreateSender("audio", "callee_stream");
4487 auto callee_video_sender =
4488 callee()->pc()->CreateSender("video", "callee_stream");
4489 caller()->CreateAndSetAndSignalOffer();
4490 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4491 // Wait for ICE to complete, without any tracks being set.
4492 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4493 caller()->ice_connection_state(), kMaxWaitForFramesMs);
4494 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4495 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4496 // Now set the tracks, and expect frames to immediately start flowing.
4497 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
4498 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
4499 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
4500 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08004501 MediaExpectations media_expectations;
4502 media_expectations.ExpectBidirectionalAudioAndVideo();
4503 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4504}
4505
4506// This tests that if we negotiate after calling AddTransceiver but before we
4507// have a track, then set a track later, frames from the newly-set tracks are
4508// received end-to-end.
4509TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
4510 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
4511 ASSERT_TRUE(CreatePeerConnectionWrappers());
4512 ConnectFakeSignaling();
4513 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
4514 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
4515 auto caller_audio_sender = audio_result.MoveValue()->sender();
4516 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
4517 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
4518 auto caller_video_sender = video_result.MoveValue()->sender();
4519 callee()->SetRemoteOfferHandler([this] {
4520 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02004521 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004522 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02004523 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004524 RtpTransceiverDirection::kSendRecv);
4525 });
4526 caller()->CreateAndSetAndSignalOffer();
4527 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4528 // Wait for ICE to complete, without any tracks being set.
4529 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4530 caller()->ice_connection_state(), kMaxWaitForFramesMs);
4531 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4532 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4533 // Now set the tracks, and expect frames to immediately start flowing.
4534 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
4535 auto callee_video_sender = callee()->pc()->GetSenders()[1];
4536 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
4537 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
4538 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
4539 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
4540 MediaExpectations media_expectations;
4541 media_expectations.ExpectBidirectionalAudioAndVideo();
4542 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004543}
4544
4545// This test verifies that a remote video track can be added via AddStream,
4546// and sent end-to-end. For this particular test, it's simply echoed back
4547// from the caller to the callee, rather than being forwarded to a third
4548// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004549TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07004550 ASSERT_TRUE(CreatePeerConnectionWrappers());
4551 ConnectFakeSignaling();
4552 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08004553 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07004554 caller()->CreateAndSetAndSignalOffer();
4555 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02004556 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07004557
4558 // Echo the stream back, and do a new offer/anwer (initiated by callee this
4559 // time).
4560 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
4561 callee()->CreateAndSetAndSignalOffer();
4562 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4563
Seth Hampson2f0d7022018-02-20 11:54:42 -08004564 MediaExpectations media_expectations;
4565 media_expectations.ExpectBidirectionalVideo();
4566 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004567}
4568
4569// Test that we achieve the expected end-to-end connection time, using a
4570// fake clock and simulated latency on the media and signaling paths.
4571// We use a TURN<->TURN connection because this is usually the quickest to
4572// set up initially, especially when we're confident the connection will work
4573// and can start sending media before we get a STUN response.
4574//
4575// With various optimizations enabled, here are the network delays we expect to
4576// be on the critical path:
4577// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
4578// signaling answer (with DTLS fingerprint).
4579// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
4580// using TURN<->TURN pair, and DTLS exchange is 4 packets,
4581// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01004582TEST_P(PeerConnectionIntegrationTestWithFakeClock,
4583 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07004584 static constexpr int media_hop_delay_ms = 50;
4585 static constexpr int signaling_trip_delay_ms = 500;
4586 // For explanation of these values, see comment above.
4587 static constexpr int required_media_hops = 9;
4588 static constexpr int required_signaling_trips = 2;
4589 // For internal delays (such as posting an event asychronously).
4590 static constexpr int allowed_internal_delay_ms = 20;
4591 static constexpr int total_connection_time_ms =
4592 media_hop_delay_ms * required_media_hops +
4593 signaling_trip_delay_ms * required_signaling_trips +
4594 allowed_internal_delay_ms;
4595
4596 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4597 3478};
4598 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4599 0};
4600 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4601 3478};
4602 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4603 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004604 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
4605 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004606
Seth Hampsonaed71642018-06-11 07:41:32 -07004607 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
4608 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07004609 // Bypass permission check on received packets so media can be sent before
4610 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07004611 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
4612 turn_server_1->set_enable_permission_checks(false);
4613 });
4614 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
4615 turn_server_2->set_enable_permission_checks(false);
4616 });
deadbeef1dcb1642017-03-29 21:08:16 -07004617
4618 PeerConnectionInterface::RTCConfiguration client_1_config;
4619 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4620 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4621 ice_server_1.username = "test";
4622 ice_server_1.password = "test";
4623 client_1_config.servers.push_back(ice_server_1);
4624 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4625 client_1_config.presume_writable_when_fully_relayed = true;
4626
4627 PeerConnectionInterface::RTCConfiguration client_2_config;
4628 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4629 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4630 ice_server_2.username = "test";
4631 ice_server_2.password = "test";
4632 client_2_config.servers.push_back(ice_server_2);
4633 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4634 client_2_config.presume_writable_when_fully_relayed = true;
4635
4636 ASSERT_TRUE(
4637 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4638 // Set up the simulated delays.
4639 SetSignalingDelayMs(signaling_trip_delay_ms);
4640 ConnectFakeSignaling();
4641 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
4642 virtual_socket_server()->UpdateDelayDistribution();
4643
4644 // Set "offer to receive audio/video" without adding any tracks, so we just
4645 // set up ICE/DTLS with no media.
4646 PeerConnectionInterface::RTCOfferAnswerOptions options;
4647 options.offer_to_receive_audio = 1;
4648 options.offer_to_receive_video = 1;
4649 caller()->SetOfferAnswerOptions(options);
4650 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07004651 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01004652 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07004653 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
4654 // If this is not done a DCHECK can be hit in ports.cc, because a large
4655 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07004656 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07004657}
4658
Jonas Orelandbdcee282017-10-10 14:01:40 +02004659// Verify that a TurnCustomizer passed in through RTCConfiguration
4660// is actually used by the underlying TURN candidate pair.
4661// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004662TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02004663 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4664 3478};
4665 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4666 0};
4667 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4668 3478};
4669 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4670 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004671 CreateTurnServer(turn_server_1_internal_address,
4672 turn_server_1_external_address);
4673 CreateTurnServer(turn_server_2_internal_address,
4674 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004675
4676 PeerConnectionInterface::RTCConfiguration client_1_config;
4677 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4678 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4679 ice_server_1.username = "test";
4680 ice_server_1.password = "test";
4681 client_1_config.servers.push_back(ice_server_1);
4682 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004683 auto* customizer1 = CreateTurnCustomizer();
4684 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004685
4686 PeerConnectionInterface::RTCConfiguration client_2_config;
4687 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4688 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4689 ice_server_2.username = "test";
4690 ice_server_2.password = "test";
4691 client_2_config.servers.push_back(ice_server_2);
4692 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004693 auto* customizer2 = CreateTurnCustomizer();
4694 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004695
4696 ASSERT_TRUE(
4697 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4698 ConnectFakeSignaling();
4699
4700 // Set "offer to receive audio/video" without adding any tracks, so we just
4701 // set up ICE/DTLS with no media.
4702 PeerConnectionInterface::RTCOfferAnswerOptions options;
4703 options.offer_to_receive_audio = 1;
4704 options.offer_to_receive_video = 1;
4705 caller()->SetOfferAnswerOptions(options);
4706 caller()->CreateAndSetAndSignalOffer();
4707 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4708
Seth Hampsonaed71642018-06-11 07:41:32 -07004709 ExpectTurnCustomizerCountersIncremented(customizer1);
4710 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004711}
4712
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004713// Verifies that you can use TCP instead of UDP to connect to a TURN server and
4714// send media between the caller and the callee.
4715TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
4716 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4717 3478};
4718 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4719
4720 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07004721 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4722 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004723
4724 webrtc::PeerConnectionInterface::IceServer ice_server;
4725 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
4726 ice_server.username = "test";
4727 ice_server.password = "test";
4728
4729 PeerConnectionInterface::RTCConfiguration client_1_config;
4730 client_1_config.servers.push_back(ice_server);
4731 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4732
4733 PeerConnectionInterface::RTCConfiguration client_2_config;
4734 client_2_config.servers.push_back(ice_server);
4735 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4736
4737 ASSERT_TRUE(
4738 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4739
4740 // Do normal offer/answer and wait for ICE to complete.
4741 ConnectFakeSignaling();
4742 caller()->AddAudioVideoTracks();
4743 callee()->AddAudioVideoTracks();
4744 caller()->CreateAndSetAndSignalOffer();
4745 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4746 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4747 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4748
4749 MediaExpectations media_expectations;
4750 media_expectations.ExpectBidirectionalAudioAndVideo();
4751 EXPECT_TRUE(ExpectNewFrames(media_expectations));
4752}
4753
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004754// Verify that a SSLCertificateVerifier passed in through
4755// PeerConnectionDependencies is actually used by the underlying SSL
4756// implementation to determine whether a certificate presented by the TURN
4757// server is accepted by the client. Note that openssladapter_unittest.cc
4758// contains more detailed, lower-level tests.
4759TEST_P(PeerConnectionIntegrationTest,
4760 SSLCertificateVerifierUsedForTurnConnections) {
4761 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4762 3478};
4763 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4764
4765 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4766 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004767 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4768 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004769
4770 webrtc::PeerConnectionInterface::IceServer ice_server;
4771 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4772 ice_server.username = "test";
4773 ice_server.password = "test";
4774
4775 PeerConnectionInterface::RTCConfiguration client_1_config;
4776 client_1_config.servers.push_back(ice_server);
4777 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4778
4779 PeerConnectionInterface::RTCConfiguration client_2_config;
4780 client_2_config.servers.push_back(ice_server);
4781 // Setting the type to kRelay forces the connection to go through a TURN
4782 // server.
4783 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4784
4785 // Get a copy to the pointer so we can verify calls later.
4786 rtc::TestCertificateVerifier* client_1_cert_verifier =
4787 new rtc::TestCertificateVerifier();
4788 client_1_cert_verifier->verify_certificate_ = true;
4789 rtc::TestCertificateVerifier* client_2_cert_verifier =
4790 new rtc::TestCertificateVerifier();
4791 client_2_cert_verifier->verify_certificate_ = true;
4792
4793 // Create the dependencies with the test certificate verifier.
4794 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4795 client_1_deps.tls_cert_verifier =
4796 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4797 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4798 client_2_deps.tls_cert_verifier =
4799 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4800
4801 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4802 client_1_config, std::move(client_1_deps), client_2_config,
4803 std::move(client_2_deps)));
4804 ConnectFakeSignaling();
4805
4806 // Set "offer to receive audio/video" without adding any tracks, so we just
4807 // set up ICE/DTLS with no media.
4808 PeerConnectionInterface::RTCOfferAnswerOptions options;
4809 options.offer_to_receive_audio = 1;
4810 options.offer_to_receive_video = 1;
4811 caller()->SetOfferAnswerOptions(options);
4812 caller()->CreateAndSetAndSignalOffer();
4813 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4814
4815 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4816 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004817}
4818
4819TEST_P(PeerConnectionIntegrationTest,
4820 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
4821 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4822 3478};
4823 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4824
4825 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4826 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004827 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4828 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004829
4830 webrtc::PeerConnectionInterface::IceServer ice_server;
4831 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4832 ice_server.username = "test";
4833 ice_server.password = "test";
4834
4835 PeerConnectionInterface::RTCConfiguration client_1_config;
4836 client_1_config.servers.push_back(ice_server);
4837 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4838
4839 PeerConnectionInterface::RTCConfiguration client_2_config;
4840 client_2_config.servers.push_back(ice_server);
4841 // Setting the type to kRelay forces the connection to go through a TURN
4842 // server.
4843 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4844
4845 // Get a copy to the pointer so we can verify calls later.
4846 rtc::TestCertificateVerifier* client_1_cert_verifier =
4847 new rtc::TestCertificateVerifier();
4848 client_1_cert_verifier->verify_certificate_ = false;
4849 rtc::TestCertificateVerifier* client_2_cert_verifier =
4850 new rtc::TestCertificateVerifier();
4851 client_2_cert_verifier->verify_certificate_ = false;
4852
4853 // Create the dependencies with the test certificate verifier.
4854 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4855 client_1_deps.tls_cert_verifier =
4856 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4857 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4858 client_2_deps.tls_cert_verifier =
4859 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4860
4861 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4862 client_1_config, std::move(client_1_deps), client_2_config,
4863 std::move(client_2_deps)));
4864 ConnectFakeSignaling();
4865
4866 // Set "offer to receive audio/video" without adding any tracks, so we just
4867 // set up ICE/DTLS with no media.
4868 PeerConnectionInterface::RTCOfferAnswerOptions options;
4869 options.offer_to_receive_audio = 1;
4870 options.offer_to_receive_video = 1;
4871 caller()->SetOfferAnswerOptions(options);
4872 caller()->CreateAndSetAndSignalOffer();
4873 bool wait_res = true;
4874 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
4875 // properly, should be able to just wait for a state of "failed" instead of
4876 // waiting a fixed 10 seconds.
4877 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
4878 ASSERT_FALSE(wait_res);
4879
4880 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4881 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004882}
4883
Qingsi Wang25ec8882019-11-15 12:33:05 -08004884// Test that the injected ICE transport factory is used to create ICE transports
4885// for WebRTC connections.
4886TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
4887 PeerConnectionInterface::RTCConfiguration default_config;
4888 PeerConnectionDependencies dependencies(nullptr);
4889 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
4890 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
4891 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02004892 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
4893 std::move(dependencies), nullptr,
4894 /*reset_encoder_factory=*/false,
4895 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08004896 ASSERT_TRUE(wrapper);
4897 wrapper->CreateDataChannel();
4898 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
4899 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
4900 wrapper->pc()->SetLocalDescription(observer,
4901 wrapper->CreateOfferAndWait().release());
4902}
4903
deadbeefc964d0b2017-04-03 10:03:35 -07004904// Test that audio and video flow end-to-end when codec names don't use the
4905// expected casing, given that they're supposed to be case insensitive. To test
4906// this, all but one codec is removed from each media description, and its
4907// casing is changed.
4908//
4909// In the past, this has regressed and caused crashes/black video, due to the
4910// fact that code at some layers was doing case-insensitive comparisons and
4911// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004912TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07004913 ASSERT_TRUE(CreatePeerConnectionWrappers());
4914 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004915 caller()->AddAudioVideoTracks();
4916 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07004917
4918 // Remove all but one audio/video codec (opus and VP8), and change the
4919 // casing of the caller's generated offer.
4920 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
4921 cricket::AudioContentDescription* audio =
4922 GetFirstAudioContentDescription(description);
4923 ASSERT_NE(nullptr, audio);
4924 auto audio_codecs = audio->codecs();
4925 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
4926 [](const cricket::AudioCodec& codec) {
4927 return codec.name != "opus";
4928 }),
4929 audio_codecs.end());
4930 ASSERT_EQ(1u, audio_codecs.size());
4931 audio_codecs[0].name = "OpUs";
4932 audio->set_codecs(audio_codecs);
4933
4934 cricket::VideoContentDescription* video =
4935 GetFirstVideoContentDescription(description);
4936 ASSERT_NE(nullptr, video);
4937 auto video_codecs = video->codecs();
4938 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
4939 [](const cricket::VideoCodec& codec) {
4940 return codec.name != "VP8";
4941 }),
4942 video_codecs.end());
4943 ASSERT_EQ(1u, video_codecs.size());
4944 video_codecs[0].name = "vP8";
4945 video->set_codecs(video_codecs);
4946 });
4947
4948 caller()->CreateAndSetAndSignalOffer();
4949 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4950
4951 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004952 MediaExpectations media_expectations;
4953 media_expectations.ExpectBidirectionalAudioAndVideo();
4954 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07004955}
4956
Jonas Oreland49ac5952018-09-26 16:04:32 +02004957TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07004958 ASSERT_TRUE(CreatePeerConnectionWrappers());
4959 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004960 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07004961 caller()->CreateAndSetAndSignalOffer();
4962 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07004963 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004964 MediaExpectations media_expectations;
4965 media_expectations.CalleeExpectsSomeAudio(1);
4966 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02004967 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07004968 auto receiver = callee()->pc()->GetReceivers()[0];
4969 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02004970 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07004971 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4972 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02004973 sources[0].source_id());
4974 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
4975}
4976
4977TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
4978 ASSERT_TRUE(CreatePeerConnectionWrappers());
4979 ConnectFakeSignaling();
4980 caller()->AddVideoTrack();
4981 caller()->CreateAndSetAndSignalOffer();
4982 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4983 // Wait for one video frame to be received by the callee.
4984 MediaExpectations media_expectations;
4985 media_expectations.CalleeExpectsSomeVideo(1);
4986 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4987 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
4988 auto receiver = callee()->pc()->GetReceivers()[0];
4989 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
4990 auto sources = receiver->GetSources();
4991 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02004992 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02004993 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
4994 sources[0].source_id());
4995 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07004996}
4997
deadbeef2f425aa2017-04-14 10:41:32 -07004998// Test that if a track is removed and added again with a different stream ID,
4999// the new stream ID is successfully communicated in SDP and media continues to
5000// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005001// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
5002// it will not reuse a transceiver that has already been sending. After creating
5003// a new transceiver it tries to create an offer with two senders of the same
5004// track ids and it fails.
5005TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07005006 ASSERT_TRUE(CreatePeerConnectionWrappers());
5007 ConnectFakeSignaling();
5008
deadbeef2f425aa2017-04-14 10:41:32 -07005009 // Add track using stream 1, do offer/answer.
5010 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
5011 caller()->CreateLocalAudioTrack();
5012 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07005013 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07005014 caller()->CreateAndSetAndSignalOffer();
5015 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005016 {
5017 MediaExpectations media_expectations;
5018 media_expectations.CalleeExpectsSomeAudio(1);
5019 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5020 }
deadbeef2f425aa2017-04-14 10:41:32 -07005021 // Remove the sender, and create a new one with the new stream.
5022 caller()->pc()->RemoveTrack(sender);
Steve Antond78323f2018-07-11 11:13:44 -07005023 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07005024 caller()->CreateAndSetAndSignalOffer();
5025 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5026 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005027 {
5028 MediaExpectations media_expectations;
5029 media_expectations.CalleeExpectsSomeAudio();
5030 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5031 }
deadbeef2f425aa2017-04-14 10:41:32 -07005032}
5033
Seth Hampson2f0d7022018-02-20 11:54:42 -08005034TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02005035 ASSERT_TRUE(CreatePeerConnectionWrappers());
5036 ConnectFakeSignaling();
5037
Mirko Bonadei317a1f02019-09-17 17:06:18 +02005038 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02005039 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
5040 ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true));
Elad Alon99c3fe52017-10-13 16:29:40 +02005041 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01005042 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
5043 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02005044
Steve Anton15324772018-01-16 10:26:49 -08005045 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02005046 caller()->CreateAndSetAndSignalOffer();
5047 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5048}
5049
Steve Antonede9ca52017-10-16 13:04:27 -07005050// Test that if candidates are only signaled by applying full session
5051// descriptions (instead of using AddIceCandidate), the peers can connect to
5052// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005053TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07005054 ASSERT_TRUE(CreatePeerConnectionWrappers());
5055 // Each side will signal the session descriptions but not candidates.
5056 ConnectFakeSignalingForSdpOnly();
5057
5058 // Add audio video track and exchange the initial offer/answer with media
5059 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08005060 caller()->AddAudioVideoTracks();
5061 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07005062 caller()->CreateAndSetAndSignalOffer();
5063
5064 // Wait for all candidates to be gathered on both the caller and callee.
5065 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
5066 caller()->ice_gathering_state(), kDefaultTimeout);
5067 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
5068 callee()->ice_gathering_state(), kDefaultTimeout);
5069
5070 // The candidates will now be included in the session description, so
5071 // signaling them will start the ICE connection.
5072 caller()->CreateAndSetAndSignalOffer();
5073 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5074
5075 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005076 MediaExpectations media_expectations;
5077 media_expectations.ExpectBidirectionalAudioAndVideo();
5078 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07005079}
5080
henrika5f6bf242017-11-01 11:06:56 +01005081// Test that SetAudioPlayout can be used to disable audio playout from the
5082// start, then later enable it. This may be useful, for example, if the caller
5083// needs to play a local ringtone until some event occurs, after which it
5084// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005085TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01005086 ASSERT_TRUE(CreatePeerConnectionWrappers());
5087 ConnectFakeSignaling();
5088
5089 // Set up audio-only call where audio playout is disabled on caller's side.
5090 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08005091 caller()->AddAudioTrack();
5092 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01005093 caller()->CreateAndSetAndSignalOffer();
5094 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5095
5096 // Pump messages for a second.
5097 WAIT(false, 1000);
5098 // Since audio playout is disabled, the caller shouldn't have received
5099 // anything (at the playout level, at least).
5100 EXPECT_EQ(0, caller()->audio_frames_received());
5101 // As a sanity check, make sure the callee (for which playout isn't disabled)
5102 // did still see frames on its audio level.
5103 ASSERT_GT(callee()->audio_frames_received(), 0);
5104
5105 // Enable playout again, and ensure audio starts flowing.
5106 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005107 MediaExpectations media_expectations;
5108 media_expectations.ExpectBidirectionalAudio();
5109 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01005110}
5111
5112double GetAudioEnergyStat(PeerConnectionWrapper* pc) {
5113 auto report = pc->NewGetStats();
5114 auto track_stats_list =
5115 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
5116 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
5117 for (const auto* track_stats : track_stats_list) {
5118 if (track_stats->remote_source.is_defined() &&
5119 *track_stats->remote_source) {
5120 remote_track_stats = track_stats;
5121 break;
5122 }
5123 }
5124
5125 if (!remote_track_stats->total_audio_energy.is_defined()) {
5126 return 0.0;
5127 }
5128 return *remote_track_stats->total_audio_energy;
5129}
5130
5131// Test that if audio playout is disabled via the SetAudioPlayout() method, then
5132// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005133TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01005134 DisableAudioPlayoutStillGeneratesAudioStats) {
5135 ASSERT_TRUE(CreatePeerConnectionWrappers());
5136 ConnectFakeSignaling();
5137
5138 // Set up audio-only call where playout is disabled but audio-processing is
5139 // still active.
Steve Anton15324772018-01-16 10:26:49 -08005140 caller()->AddAudioTrack();
5141 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01005142 caller()->pc()->SetAudioPlayout(false);
5143
5144 caller()->CreateAndSetAndSignalOffer();
5145 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5146
5147 // Wait for the callee to receive audio stats.
5148 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
5149}
5150
henrika4f167df2017-11-01 14:45:55 +01005151// Test that SetAudioRecording can be used to disable audio recording from the
5152// start, then later enable it. This may be useful, for example, if the caller
5153// wants to ensure that no audio resources are active before a certain state
5154// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005155TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01005156 ASSERT_TRUE(CreatePeerConnectionWrappers());
5157 ConnectFakeSignaling();
5158
5159 // Set up audio-only call where audio recording is disabled on caller's side.
5160 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08005161 caller()->AddAudioTrack();
5162 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01005163 caller()->CreateAndSetAndSignalOffer();
5164 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5165
5166 // Pump messages for a second.
5167 WAIT(false, 1000);
5168 // Since caller has disabled audio recording, the callee shouldn't have
5169 // received anything.
5170 EXPECT_EQ(0, callee()->audio_frames_received());
5171 // As a sanity check, make sure the caller did still see frames on its
5172 // audio level since audio recording is enabled on the calle side.
5173 ASSERT_GT(caller()->audio_frames_received(), 0);
5174
5175 // Enable audio recording again, and ensure audio starts flowing.
5176 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005177 MediaExpectations media_expectations;
5178 media_expectations.ExpectBidirectionalAudio();
5179 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01005180}
5181
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005182// Test that after closing PeerConnections, they stop sending any packets (ICE,
5183// DTLS, RTP...).
Seth Hampson2f0d7022018-02-20 11:54:42 -08005184TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005185 // Set up audio/video/data, wait for some frames to be received.
5186 ASSERT_TRUE(CreatePeerConnectionWrappers());
5187 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08005188 caller()->AddAudioVideoTracks();
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005189#ifdef WEBRTC_HAVE_SCTP
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005190 caller()->CreateDataChannel();
5191#endif
5192 caller()->CreateAndSetAndSignalOffer();
5193 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005194 MediaExpectations media_expectations;
5195 media_expectations.CalleeExpectsSomeAudioAndVideo();
5196 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005197 // Close PeerConnections.
Steve Antond91969e2019-05-30 12:27:03 -07005198 ClosePeerConnections();
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005199 // Pump messages for a second, and ensure no new packets end up sent.
5200 uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
5201 WAIT(false, 1000);
5202 uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
5203 EXPECT_EQ(sent_packets_a, sent_packets_b);
5204}
5205
Steve Anton7eca0932018-03-30 15:18:41 -07005206// Test that transport stats are generated by the RTCStatsCollector for a
5207// connection that only involves data channels. This is a regression test for
5208// crbug.com/826972.
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005209#ifdef WEBRTC_HAVE_SCTP
Steve Anton7eca0932018-03-30 15:18:41 -07005210TEST_P(PeerConnectionIntegrationTest,
5211 TransportStatsReportedForDataChannelOnlyConnection) {
5212 ASSERT_TRUE(CreatePeerConnectionWrappers());
5213 ConnectFakeSignaling();
5214 caller()->CreateDataChannel();
5215
5216 caller()->CreateAndSetAndSignalOffer();
5217 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5218 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
5219
5220 auto caller_report = caller()->NewGetStats();
5221 EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
5222 auto callee_report = callee()->NewGetStats();
5223 EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
5224}
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005225#endif // WEBRTC_HAVE_SCTP
Steve Anton7eca0932018-03-30 15:18:41 -07005226
Qingsi Wang7685e862018-06-11 20:15:46 -07005227TEST_P(PeerConnectionIntegrationTest,
5228 IceEventsGeneratedAndLoggedInRtcEventLog) {
5229 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
5230 ConnectFakeSignaling();
5231 PeerConnectionInterface::RTCOfferAnswerOptions options;
5232 options.offer_to_receive_audio = 1;
5233 caller()->SetOfferAnswerOptions(options);
5234 caller()->CreateAndSetAndSignalOffer();
5235 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
5236 ASSERT_NE(nullptr, caller()->event_log_factory());
5237 ASSERT_NE(nullptr, callee()->event_log_factory());
5238 webrtc::FakeRtcEventLog* caller_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01005239 caller()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07005240 webrtc::FakeRtcEventLog* callee_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01005241 callee()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07005242 ASSERT_NE(nullptr, caller_event_log);
5243 ASSERT_NE(nullptr, callee_event_log);
5244 int caller_ice_config_count = caller_event_log->GetEventCount(
5245 webrtc::RtcEvent::Type::IceCandidatePairConfig);
5246 int caller_ice_event_count = caller_event_log->GetEventCount(
5247 webrtc::RtcEvent::Type::IceCandidatePairEvent);
5248 int callee_ice_config_count = callee_event_log->GetEventCount(
5249 webrtc::RtcEvent::Type::IceCandidatePairConfig);
5250 int callee_ice_event_count = callee_event_log->GetEventCount(
5251 webrtc::RtcEvent::Type::IceCandidatePairEvent);
5252 EXPECT_LT(0, caller_ice_config_count);
5253 EXPECT_LT(0, caller_ice_event_count);
5254 EXPECT_LT(0, callee_ice_config_count);
5255 EXPECT_LT(0, callee_ice_event_count);
5256}
5257
Qingsi Wangc129c352019-04-18 10:41:58 -07005258TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07005259 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
5260 3478};
5261 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
5262
5263 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
5264
5265 webrtc::PeerConnectionInterface::IceServer ice_server;
5266 ice_server.urls.push_back("turn:88.88.88.0:3478");
5267 ice_server.username = "test";
5268 ice_server.password = "test";
5269
5270 PeerConnectionInterface::RTCConfiguration caller_config;
5271 caller_config.servers.push_back(ice_server);
5272 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5273 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005274 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07005275
5276 PeerConnectionInterface::RTCConfiguration callee_config;
5277 callee_config.servers.push_back(ice_server);
5278 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5279 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005280 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07005281
5282 ASSERT_TRUE(
5283 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5284
5285 // Do normal offer/answer and wait for ICE to complete.
5286 ConnectFakeSignaling();
5287 caller()->AddAudioVideoTracks();
5288 callee()->AddAudioVideoTracks();
5289 caller()->CreateAndSetAndSignalOffer();
5290 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5291 // Since we are doing continual gathering, the ICE transport does not reach
5292 // kIceGatheringComplete (see
5293 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
5294 // kIceConnectionComplete.
5295 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
5296 caller()->ice_connection_state(), kDefaultTimeout);
5297 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
5298 callee()->ice_connection_state(), kDefaultTimeout);
5299 // Note that we cannot use the metric
5300 // |WebRTC.PeerConnection.CandidatePairType_UDP| in this test since this
5301 // metric is only populated when we reach kIceConnectionComplete in the
5302 // current implementation.
5303 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
5304 caller()->last_candidate_gathered().type());
5305 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
5306 callee()->last_candidate_gathered().type());
5307
5308 // Loosen the caller's candidate filter.
5309 caller_config = caller()->pc()->GetConfiguration();
5310 caller_config.type = webrtc::PeerConnectionInterface::kAll;
5311 caller()->pc()->SetConfiguration(caller_config);
5312 // We should have gathered a new host candidate.
5313 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
5314 caller()->last_candidate_gathered().type(), kDefaultTimeout);
5315
5316 // Loosen the callee's candidate filter.
5317 callee_config = callee()->pc()->GetConfiguration();
5318 callee_config.type = webrtc::PeerConnectionInterface::kAll;
5319 callee()->pc()->SetConfiguration(callee_config);
5320 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
5321 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02005322
5323 // Create an offer and verify that it does not contain an ICE restart (i.e new
5324 // ice credentials).
5325 std::string caller_ufrag_pre_offer = caller()
5326 ->pc()
5327 ->local_description()
5328 ->description()
5329 ->transport_infos()[0]
5330 .description.ice_ufrag;
5331 caller()->CreateAndSetAndSignalOffer();
5332 std::string caller_ufrag_post_offer = caller()
5333 ->pc()
5334 ->local_description()
5335 ->description()
5336 ->transport_infos()[0]
5337 .description.ice_ufrag;
5338 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07005339}
5340
Eldar Relloda13ea22019-06-01 12:23:43 +03005341TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03005342 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
5343 3478};
5344 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
5345
5346 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
5347
5348 webrtc::PeerConnectionInterface::IceServer ice_server;
5349 ice_server.urls.push_back("turn:88.88.88.0:3478");
5350 ice_server.username = "test";
5351 ice_server.password = "123";
5352
5353 PeerConnectionInterface::RTCConfiguration caller_config;
5354 caller_config.servers.push_back(ice_server);
5355 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5356 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5357
5358 PeerConnectionInterface::RTCConfiguration callee_config;
5359 callee_config.servers.push_back(ice_server);
5360 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5361 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5362
5363 ASSERT_TRUE(
5364 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5365
5366 // Do normal offer/answer and wait for ICE to complete.
5367 ConnectFakeSignaling();
5368 caller()->AddAudioVideoTracks();
5369 callee()->AddAudioVideoTracks();
5370 caller()->CreateAndSetAndSignalOffer();
5371 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5372 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
5373 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
5374 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02005375 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03005376}
5377
Eldar Rellofa8019c2020-05-14 11:59:33 +03005378TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
5379 webrtc::PeerConnectionInterface::IceServer ice_server;
5380 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
5381 ice_server.username = "test";
5382 ice_server.password = "test";
5383
5384 PeerConnectionInterface::RTCConfiguration caller_config;
5385 caller_config.servers.push_back(ice_server);
5386 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5387 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5388
5389 PeerConnectionInterface::RTCConfiguration callee_config;
5390 callee_config.servers.push_back(ice_server);
5391 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5392 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5393
5394 ASSERT_TRUE(
5395 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5396
5397 // Do normal offer/answer and wait for ICE to complete.
5398 ConnectFakeSignaling();
5399 caller()->AddAudioVideoTracks();
5400 callee()->AddAudioVideoTracks();
5401 caller()->CreateAndSetAndSignalOffer();
5402 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5403 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
5404 EXPECT_EQ(caller()->error_event().address, "");
5405}
5406
Eldar Rello5ab79e62019-10-09 18:29:44 +03005407TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5408 AudioKeepsFlowingAfterImplicitRollback) {
5409 PeerConnectionInterface::RTCConfiguration config;
5410 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5411 config.enable_implicit_rollback = true;
5412 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5413 ConnectFakeSignaling();
5414 caller()->AddAudioTrack();
5415 callee()->AddAudioTrack();
5416 caller()->CreateAndSetAndSignalOffer();
5417 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5418 MediaExpectations media_expectations;
5419 media_expectations.ExpectBidirectionalAudio();
5420 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5421 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
5422 caller()->AddVideoTrack();
5423 callee()->AddVideoTrack();
5424 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
5425 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5426 callee()->pc()->SetLocalDescription(observer,
5427 callee()->CreateOfferAndWait().release());
5428 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
5429 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
5430 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5431 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5432}
5433
5434TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5435 ImplicitRollbackVisitsStableState) {
5436 RTCConfiguration config;
5437 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5438 config.enable_implicit_rollback = true;
5439
5440 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5441
5442 rtc::scoped_refptr<MockSetSessionDescriptionObserver> sld_observer(
5443 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5444 callee()->pc()->SetLocalDescription(sld_observer,
5445 callee()->CreateOfferAndWait().release());
5446 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
5447 EXPECT_EQ(sld_observer->error(), "");
5448
5449 rtc::scoped_refptr<MockSetSessionDescriptionObserver> srd_observer(
5450 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5451 callee()->pc()->SetRemoteDescription(
5452 srd_observer, caller()->CreateOfferAndWait().release());
5453 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
5454 EXPECT_EQ(srd_observer->error(), "");
5455
5456 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
5457 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
5458 PeerConnectionInterface::kStable,
5459 PeerConnectionInterface::kHaveRemoteOffer));
5460}
5461
Eldar Rellobd9c33a2020-10-01 17:52:45 +03005462TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5463 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
5464 ASSERT_TRUE(CreatePeerConnectionWrappers());
5465 ConnectFakeSignaling();
5466 caller()->AddVideoTrack();
5467 callee()->AddVideoTrack();
5468 auto munger = [](cricket::SessionDescription* desc) {
5469 cricket::VideoContentDescription* video =
5470 GetFirstVideoContentDescription(desc);
5471 auto codecs = video->codecs();
5472 for (auto&& codec : codecs) {
5473 if (codec.name == "H264") {
5474 std::string value;
5475 // The parameter is not supposed to be present in SDP by default.
5476 EXPECT_FALSE(
5477 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
5478 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
5479 std::string(""));
5480 }
5481 }
5482 video->set_codecs(codecs);
5483 };
5484 // Munge local offer for SLD.
5485 caller()->SetGeneratedSdpMunger(munger);
5486 // Munge remote answer for SRD.
5487 caller()->SetReceivedSdpMunger(munger);
5488 caller()->CreateAndSetAndSignalOffer();
5489 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5490 // Observe that after munging the parameter is present in generated SDP.
5491 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
5492 cricket::VideoContentDescription* video =
5493 GetFirstVideoContentDescription(desc);
5494 for (auto&& codec : video->codecs()) {
5495 if (codec.name == "H264") {
5496 std::string value;
5497 EXPECT_TRUE(
5498 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
5499 }
5500 }
5501 });
5502 caller()->CreateOfferAndWait();
5503}
5504
Harald Alvestrand1a9be302020-12-11 14:53:59 +00005505TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00005506 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00005507 PeerConnectionInterface::RTCConfiguration config;
5508 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5509 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5510 ConnectFakeSignaling();
5511 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
5512
5513 caller()->CreateAndSetAndSignalOffer();
5514 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5515 int current_size = caller()->pc()->GetTransceivers().size();
5516 // Add more tracks until we get close to having issues.
5517 // Issues have been seen at:
5518 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005519 // - 16 tracks on android_arm_dbg (flaky)
5520 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00005521 // Double the number of tracks
5522 for (int i = 0; i < current_size; i++) {
5523 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
5524 }
5525 current_size = caller()->pc()->GetTransceivers().size();
5526 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
5527 auto start_time_ms = rtc::TimeMillis();
5528 caller()->CreateAndSetAndSignalOffer();
5529 // We want to stop when the time exceeds one second.
5530 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5531 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
5532 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
5533 ASSERT_GT(1000, elapsed_time_ms)
5534 << "Audio transceivers: Negotiation took too long after "
5535 << current_size << " tracks added";
5536 }
5537}
5538
5539TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5540 RenegotiateManyVideoTransceivers) {
5541 PeerConnectionInterface::RTCConfiguration config;
5542 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5543 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5544 ConnectFakeSignaling();
5545 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
5546
5547 caller()->CreateAndSetAndSignalOffer();
5548 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5549 int current_size = caller()->pc()->GetTransceivers().size();
5550 // Add more tracks until we get close to having issues.
5551 // Issues have been seen at:
5552 // - 96 on a Linux workstation
5553 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
5554 // - 32 on android_arm64_rel and linux_dbg bots
5555 while (current_size < 16) {
5556 // Double the number of tracks
5557 for (int i = 0; i < current_size; i++) {
5558 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
5559 }
5560 current_size = caller()->pc()->GetTransceivers().size();
5561 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
5562 auto start_time_ms = rtc::TimeMillis();
5563 caller()->CreateAndSetAndSignalOffer();
5564 // We want to stop when the time exceeds one second.
5565 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5566 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
5567 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
5568 ASSERT_GT(1000, elapsed_time_ms)
5569 << "Video transceivers: Negotiation took too long after "
5570 << current_size << " tracks added";
5571 }
5572}
5573
Harald Alvestrand94324f22021-01-13 12:31:53 +00005574TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5575 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
5576 PeerConnectionInterface::RTCConfiguration config;
5577 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5578 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5579 ConnectFakeSignaling();
5580 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005581 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00005582 caller()->CreateAndSetAndSignalOffer();
5583 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5584 // Wait until we can see the audio flowing.
5585 MediaExpectations media_expectations;
5586 media_expectations.CalleeExpectsSomeAudio();
5587 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5588
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005589 // Get the baseline numbers for audio_packets and audio_delay
5590 // in both directions.
5591 caller()->StartWatchingDelayStats();
5592 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00005593
5594 int current_size = caller()->pc()->GetTransceivers().size();
5595 // Add more tracks until we get close to having issues.
5596 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005597 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00005598 // Double the number of tracks
5599 for (int i = 0; i < current_size; i++) {
5600 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
5601 }
5602 current_size = caller()->pc()->GetTransceivers().size();
5603 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
5604 auto start_time_ms = rtc::TimeMillis();
5605 caller()->CreateAndSetAndSignalOffer();
5606 // We want to stop when the time exceeds one second.
5607 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5608 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
5609 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
5610 // This is a guard against the test using excessive amounts of time.
5611 ASSERT_GT(5000, elapsed_time_ms)
5612 << "Video transceivers: Negotiation took too long after "
5613 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005614 caller()->UpdateDelayStats("caller reception", current_size);
5615 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00005616 }
5617}
5618
Mirko Bonadeic84f6612019-01-31 12:20:57 +01005619INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
5620 PeerConnectionIntegrationTest,
5621 Values(SdpSemantics::kPlanB,
5622 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-17 17:41:02 -08005623
Yves Gerey100fe632020-01-17 19:15:53 +01005624INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
5625 PeerConnectionIntegrationTestWithFakeClock,
5626 Values(SdpSemantics::kPlanB,
5627 SdpSemantics::kUnifiedPlan));
5628
Steve Anton74255ff2018-01-24 18:32:57 -08005629// Tests that verify interoperability between Plan B and Unified Plan
5630// PeerConnections.
5631class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08005632 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08005633 public ::testing::WithParamInterface<
5634 std::tuple<SdpSemantics, SdpSemantics>> {
5635 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08005636 // Setting the SdpSemantics for the base test to kDefault does not matter
5637 // because we specify not to use the test semantics when creating
5638 // PeerConnectionWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08005639 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07005640 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08005641 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08005642 callee_semantics_(std::get<1>(GetParam())) {}
5643
5644 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07005645 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
5646 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08005647 }
5648
5649 const SdpSemantics caller_semantics_;
5650 const SdpSemantics callee_semantics_;
5651};
5652
5653TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
5654 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5655 ConnectFakeSignaling();
5656
5657 caller()->CreateAndSetAndSignalOffer();
5658 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5659}
5660
5661TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
5662 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5663 ConnectFakeSignaling();
5664 auto audio_sender = caller()->AddAudioTrack();
5665
5666 caller()->CreateAndSetAndSignalOffer();
5667 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5668
5669 // Verify that one audio receiver has been created on the remote and that it
5670 // has the same track ID as the sending track.
5671 auto receivers = callee()->pc()->GetReceivers();
5672 ASSERT_EQ(1u, receivers.size());
5673 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
5674 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
5675
Seth Hampson2f0d7022018-02-20 11:54:42 -08005676 MediaExpectations media_expectations;
5677 media_expectations.CalleeExpectsSomeAudio();
5678 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005679}
5680
5681TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
5682 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5683 ConnectFakeSignaling();
5684 auto video_sender = caller()->AddVideoTrack();
5685 auto audio_sender = caller()->AddAudioTrack();
5686
5687 caller()->CreateAndSetAndSignalOffer();
5688 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5689
5690 // Verify that one audio and one video receiver have been created on the
5691 // remote and that they have the same track IDs as the sending tracks.
5692 auto audio_receivers =
5693 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
5694 ASSERT_EQ(1u, audio_receivers.size());
5695 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
5696 auto video_receivers =
5697 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
5698 ASSERT_EQ(1u, video_receivers.size());
5699 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
5700
Seth Hampson2f0d7022018-02-20 11:54:42 -08005701 MediaExpectations media_expectations;
5702 media_expectations.CalleeExpectsSomeAudioAndVideo();
5703 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005704}
5705
5706TEST_P(PeerConnectionIntegrationInteropTest,
5707 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
5708 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5709 ConnectFakeSignaling();
5710 caller()->AddAudioVideoTracks();
5711 callee()->AddAudioVideoTracks();
5712
5713 caller()->CreateAndSetAndSignalOffer();
5714 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5715
Seth Hampson2f0d7022018-02-20 11:54:42 -08005716 MediaExpectations media_expectations;
5717 media_expectations.ExpectBidirectionalAudioAndVideo();
5718 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005719}
5720
5721TEST_P(PeerConnectionIntegrationInteropTest,
5722 ReverseRolesOneAudioLocalToOneVideoRemote) {
5723 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5724 ConnectFakeSignaling();
5725 caller()->AddAudioTrack();
5726 callee()->AddVideoTrack();
5727
5728 caller()->CreateAndSetAndSignalOffer();
5729 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5730
5731 // Verify that only the audio track has been negotiated.
5732 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
5733 // Might also check that the callee's NegotiationNeeded flag is set.
5734
5735 // Reverse roles.
5736 callee()->CreateAndSetAndSignalOffer();
5737 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5738
Seth Hampson2f0d7022018-02-20 11:54:42 -08005739 MediaExpectations media_expectations;
5740 media_expectations.CallerExpectsSomeVideo();
5741 media_expectations.CalleeExpectsSomeAudio();
5742 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005743}
5744
Mirko Bonadeic84f6612019-01-31 12:20:57 +01005745INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07005746 PeerConnectionIntegrationTest,
5747 PeerConnectionIntegrationInteropTest,
5748 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
5749 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
5750
5751// Test that if the Unified Plan side offers two video tracks then the Plan B
5752// side will only see the first one and ignore the second.
5753TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07005754 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
5755 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08005756 ConnectFakeSignaling();
5757 auto first_sender = caller()->AddVideoTrack();
5758 caller()->AddVideoTrack();
5759
5760 caller()->CreateAndSetAndSignalOffer();
5761 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5762
5763 // Verify that there is only one receiver and it corresponds to the first
5764 // added track.
5765 auto receivers = callee()->pc()->GetReceivers();
5766 ASSERT_EQ(1u, receivers.size());
5767 EXPECT_TRUE(receivers[0]->track()->enabled());
5768 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
5769
Seth Hampson2f0d7022018-02-20 11:54:42 -08005770 MediaExpectations media_expectations;
5771 media_expectations.CalleeExpectsSomeVideo();
5772 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005773}
5774
Steve Anton2bed3972019-01-04 17:04:30 -08005775// Test that if the initial offer tagged BUNDLE section is rejected due to its
5776// associated RtpTransceiver being stopped and another transceiver is added,
5777// then renegotiation causes the callee to receive the new video track without
5778// error.
5779// This is a regression test for bugs.webrtc.org/9954
5780TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5781 ReOfferWithStoppedBundleTaggedTransceiver) {
5782 RTCConfiguration config;
5783 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
5784 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5785 ConnectFakeSignaling();
5786 auto audio_transceiver_or_error =
5787 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5788 ASSERT_TRUE(audio_transceiver_or_error.ok());
5789 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5790
5791 caller()->CreateAndSetAndSignalOffer();
5792 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5793 {
5794 MediaExpectations media_expectations;
5795 media_expectations.CalleeExpectsSomeAudio();
5796 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5797 }
5798
Harald Alvestrand6060df52020-08-11 09:54:02 +02005799 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08005800 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
5801
5802 caller()->CreateAndSetAndSignalOffer();
5803 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5804 {
5805 MediaExpectations media_expectations;
5806 media_expectations.CalleeExpectsSomeVideo();
5807 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5808 }
5809}
5810
Harald Alvestrandbedb6052020-08-20 14:50:10 +02005811TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5812 StopTransceiverRemovesDtlsTransports) {
5813 RTCConfiguration config;
5814 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5815 ConnectFakeSignaling();
5816 auto audio_transceiver_or_error =
5817 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5818 ASSERT_TRUE(audio_transceiver_or_error.ok());
5819 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5820
5821 caller()->CreateAndSetAndSignalOffer();
5822 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5823
5824 audio_transceiver->StopStandard();
5825 caller()->CreateAndSetAndSignalOffer();
5826 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5827 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
5828 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
5829 caller()->pc()->ice_gathering_state());
5830 EXPECT_THAT(caller()->ice_gathering_state_history(),
5831 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
5832 PeerConnectionInterface::kIceGatheringComplete,
5833 PeerConnectionInterface::kIceGatheringNew));
5834}
5835
Harald Alvestrand1ee33252020-09-24 13:31:15 +00005836TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00005837 StopTransceiverStopsAndRemovesTransceivers) {
5838 RTCConfiguration config;
5839 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5840 ConnectFakeSignaling();
5841 auto audio_transceiver_or_error =
5842 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5843 ASSERT_TRUE(audio_transceiver_or_error.ok());
5844 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
5845
5846 caller()->CreateAndSetAndSignalOffer();
5847 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5848 caller_transceiver->StopStandard();
5849
5850 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
5851 caller()->CreateAndSetAndSignalOffer();
5852 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5853 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
5854 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
5855 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
5856 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
5857 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
5858 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
5859 EXPECT_TRUE(caller_transceiver->stopped());
5860 EXPECT_TRUE(callee_transceiver->stopped());
5861}
5862
5863TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00005864 StopTransceiverEndsIncomingAudioTrack) {
5865 RTCConfiguration config;
5866 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5867 ConnectFakeSignaling();
5868 auto audio_transceiver_or_error =
5869 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5870 ASSERT_TRUE(audio_transceiver_or_error.ok());
5871 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5872
5873 caller()->CreateAndSetAndSignalOffer();
5874 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5875 auto caller_track = audio_transceiver->receiver()->track();
5876 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
5877 audio_transceiver->StopStandard();
5878 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
5879 caller_track->state());
5880 caller()->CreateAndSetAndSignalOffer();
5881 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5882 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
5883 callee_track->state());
5884}
5885
5886TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5887 StopTransceiverEndsIncomingVideoTrack) {
5888 RTCConfiguration config;
5889 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5890 ConnectFakeSignaling();
5891 auto audio_transceiver_or_error =
5892 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
5893 ASSERT_TRUE(audio_transceiver_or_error.ok());
5894 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5895
5896 caller()->CreateAndSetAndSignalOffer();
5897 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5898 auto caller_track = audio_transceiver->receiver()->track();
5899 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
5900 audio_transceiver->StopStandard();
5901 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
5902 caller_track->state());
5903 caller()->CreateAndSetAndSignalOffer();
5904 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5905 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
5906 callee_track->state());
5907}
5908
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005909#ifdef WEBRTC_HAVE_SCTP
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02005910
5911TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5912 EndToEndCallWithBundledSctpDataChannel) {
5913 ASSERT_TRUE(CreatePeerConnectionWrappers());
5914 ConnectFakeSignaling();
5915 caller()->CreateDataChannel();
5916 caller()->AddAudioVideoTracks();
5917 callee()->AddAudioVideoTracks();
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02005918 caller()->CreateAndSetAndSignalOffer();
5919 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Harald Alvestrand17ea0682019-12-13 11:51:04 +01005920 ASSERT_EQ_WAIT(SctpTransportState::kConnected,
5921 caller()->pc()->GetSctpTransport()->Information().state(),
5922 kDefaultTimeout);
5923 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
5924 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5925}
5926
5927TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5928 EndToEndCallWithDataChannelOnlyConnects) {
5929 ASSERT_TRUE(CreatePeerConnectionWrappers());
5930 ConnectFakeSignaling();
5931 caller()->CreateDataChannel();
5932 caller()->CreateAndSetAndSignalOffer();
5933 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5934 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
5935 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5936 ASSERT_TRUE(caller()->data_observer()->IsOpen());
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02005937}
5938
Harald Alvestrand2697ac12019-12-16 10:37:04 +01005939TEST_F(PeerConnectionIntegrationTestUnifiedPlan, DataChannelClosesWhenClosed) {
5940 ASSERT_TRUE(CreatePeerConnectionWrappers());
5941 ConnectFakeSignaling();
5942 caller()->CreateDataChannel();
5943 caller()->CreateAndSetAndSignalOffer();
5944 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5945 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
5946 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5947 caller()->data_channel()->Close();
5948 ASSERT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
5949}
5950
5951TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5952 DataChannelClosesWhenClosedReverse) {
5953 ASSERT_TRUE(CreatePeerConnectionWrappers());
5954 ConnectFakeSignaling();
5955 caller()->CreateDataChannel();
5956 caller()->CreateAndSetAndSignalOffer();
5957 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5958 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
5959 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5960 callee()->data_channel()->Close();
5961 ASSERT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
5962}
5963
5964TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5965 DataChannelClosesWhenPeerConnectionClosed) {
5966 ASSERT_TRUE(CreatePeerConnectionWrappers());
5967 ConnectFakeSignaling();
5968 caller()->CreateDataChannel();
5969 caller()->CreateAndSetAndSignalOffer();
5970 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5971 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
5972 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5973 caller()->pc()->Close();
5974 ASSERT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
5975}
5976
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005977#endif // WEBRTC_HAVE_SCTP
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02005978
deadbeef1dcb1642017-03-29 21:08:16 -07005979} // namespace
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01005980} // namespace webrtc
deadbeef1dcb1642017-03-29 21:08:16 -07005981
5982#endif // if !defined(THREAD_SANITIZER)