blob: 4ed92adfce163a8741e688cc3cda405f01ceba6b [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;
Harald Alvestrandcbacec52021-01-14 13:13:42 +0000620 audio_samples_stat_ = *track_stats->total_samples_received;
621 audio_concealed_stat_ = *track_stats->concealed_samples;
Harald Alvestrandcc6ae442021-01-18 08:06:23 +0000622 }
623
624 void UpdateDelayStats(std::string tag, int desc_size) {
625 auto report = NewGetStats();
626 auto track_stats =
627 report->GetAs<webrtc::RTCMediaStreamTrackStats>(audio_track_stats_id_);
628 ASSERT_TRUE(track_stats);
629 auto rtp_stats =
630 report->GetAs<webrtc::RTCInboundRTPStreamStats>(rtp_stats_id_);
631 ASSERT_TRUE(rtp_stats);
632 auto delta_packets = *rtp_stats->packets_received - audio_packets_stat_;
633 auto delta_rpad =
634 *track_stats->relative_packet_arrival_delay - audio_delay_stat_;
635 auto recent_delay = delta_packets > 0 ? delta_rpad / delta_packets : -1;
Harald Alvestrand7ef97f62021-02-08 15:26:36 +0000636 // The purpose of these checks is to sound the alarm early if we introduce
637 // serious regressions. The numbers are not acceptable for production, but
638 // occur on slow bots.
639 //
Harald Alvestrandcc6ae442021-01-18 08:06:23 +0000640 // An average relative packet arrival delay over the renegotiation of
641 // > 100 ms indicates that something is dramatically wrong, and will impact
642 // quality for sure.
Harald Alvestrand7ef97f62021-02-08 15:26:36 +0000643 // Worst bots:
644 // linux_x86_dbg at 0.206
645#if !defined(NDEBUG)
646 EXPECT_GT(0.25, recent_delay) << tag << " size " << desc_size;
647#else
Harald Alvestrandcbacec52021-01-14 13:13:42 +0000648 EXPECT_GT(0.1, recent_delay) << tag << " size " << desc_size;
Harald Alvestrand7ef97f62021-02-08 15:26:36 +0000649#endif
Harald Alvestrandcbacec52021-01-14 13:13:42 +0000650 auto delta_samples =
651 *track_stats->total_samples_received - audio_samples_stat_;
652 auto delta_concealed =
653 *track_stats->concealed_samples - audio_concealed_stat_;
654 // These limits should be adjusted down as we improve:
655 //
656 // Concealing more than 4000 samples during a renegotiation is unacceptable.
Harald Alvestrand7ef97f62021-02-08 15:26:36 +0000657 // But some bots are slow.
Harald Alvestrandcbacec52021-01-14 13:13:42 +0000658
Harald Alvestrand7ef97f62021-02-08 15:26:36 +0000659 // Worst bots:
Harald Alvestrandcbacec52021-01-14 13:13:42 +0000660 // linux_more_configs bot at conceal count 5184
661 // android_arm_rel at conceal count 9241
Harald Alvestrand7ef97f62021-02-08 15:26:36 +0000662 // linux_x86_dbg at 15174
663#if !defined(NDEBUG)
664 EXPECT_GT(18000U, delta_concealed) << "Concealed " << delta_concealed
665 << " of " << delta_samples << " samples";
666#else
Harald Alvestrandcbacec52021-01-14 13:13:42 +0000667 EXPECT_GT(15000U, delta_concealed) << "Concealed " << delta_concealed
668 << " of " << delta_samples << " samples";
Harald Alvestrand7ef97f62021-02-08 15:26:36 +0000669#endif
670 // Concealing more than 20% of samples during a renegotiation is
671 // unacceptable.
672 // Worst bots:
673 // linux_more_configs bot at conceal rate 0.516
674 // linux_x86_dbg bot at conceal rate 0.854
Harald Alvestrandcbacec52021-01-14 13:13:42 +0000675 if (delta_samples > 0) {
Harald Alvestrand7ef97f62021-02-08 15:26:36 +0000676#if !defined(NDEBUG)
677 EXPECT_GT(0.95, 1.0 * delta_concealed / delta_samples)
678 << "Concealed " << delta_concealed << " of " << delta_samples
679 << " samples";
680#else
Harald Alvestrandcbacec52021-01-14 13:13:42 +0000681 EXPECT_GT(0.6, 1.0 * delta_concealed / delta_samples)
682 << "Concealed " << delta_concealed << " of " << delta_samples
683 << " samples";
Harald Alvestrand7ef97f62021-02-08 15:26:36 +0000684#endif
Harald Alvestrandcbacec52021-01-14 13:13:42 +0000685 }
Harald Alvestrandcc6ae442021-01-18 08:06:23 +0000686 // Increment trailing counters
687 audio_packets_stat_ = *rtp_stats->packets_received;
688 audio_delay_stat_ = *track_stats->relative_packet_arrival_delay;
Harald Alvestrandcbacec52021-01-14 13:13:42 +0000689 audio_samples_stat_ = *track_stats->total_samples_received;
690 audio_concealed_stat_ = *track_stats->concealed_samples;
Harald Alvestrandcc6ae442021-01-18 08:06:23 +0000691 }
692
deadbeef1dcb1642017-03-29 21:08:16 -0700693 private:
694 explicit PeerConnectionWrapper(const std::string& debug_name)
695 : debug_name_(debug_name) {}
696
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800697 bool Init(
698 const PeerConnectionFactory::Options* options,
699 const PeerConnectionInterface::RTCConfiguration* config,
700 webrtc::PeerConnectionDependencies dependencies,
701 rtc::Thread* network_thread,
702 rtc::Thread* worker_thread,
703 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory,
Johannes Kron3e983682020-03-29 22:17:00 +0200704 bool reset_encoder_factory,
705 bool reset_decoder_factory) {
deadbeef1dcb1642017-03-29 21:08:16 -0700706 // There's an error in this test code if Init ends up being called twice.
707 RTC_DCHECK(!peer_connection_);
708 RTC_DCHECK(!peer_connection_factory_);
709
710 fake_network_manager_.reset(new rtc::FakeNetworkManager());
Steve Antonede9ca52017-10-16 13:04:27 -0700711 fake_network_manager_->AddInterface(kDefaultLocalAddress);
deadbeef1dcb1642017-03-29 21:08:16 -0700712
713 std::unique_ptr<cricket::PortAllocator> port_allocator(
714 new cricket::BasicPortAllocator(fake_network_manager_.get()));
Steve Antonede9ca52017-10-16 13:04:27 -0700715 port_allocator_ = port_allocator.get();
deadbeef1dcb1642017-03-29 21:08:16 -0700716 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
717 if (!fake_audio_capture_module_) {
718 return false;
719 }
deadbeef1dcb1642017-03-29 21:08:16 -0700720 rtc::Thread* const signaling_thread = rtc::Thread::Current();
Qingsi Wang7685e862018-06-11 20:15:46 -0700721
722 webrtc::PeerConnectionFactoryDependencies pc_factory_dependencies;
723 pc_factory_dependencies.network_thread = network_thread;
724 pc_factory_dependencies.worker_thread = worker_thread;
725 pc_factory_dependencies.signaling_thread = signaling_thread;
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200726 pc_factory_dependencies.task_queue_factory =
727 webrtc::CreateDefaultTaskQueueFactory();
Erik Språngceb44952020-09-22 11:36:35 +0200728 pc_factory_dependencies.trials = std::make_unique<FieldTrialBasedConfig>();
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200729 cricket::MediaEngineDependencies media_deps;
730 media_deps.task_queue_factory =
731 pc_factory_dependencies.task_queue_factory.get();
732 media_deps.adm = fake_audio_capture_module_;
733 webrtc::SetMediaEngineDefaults(&media_deps);
Johannes Kron3e983682020-03-29 22:17:00 +0200734
735 if (reset_encoder_factory) {
736 media_deps.video_encoder_factory.reset();
737 }
738 if (reset_decoder_factory) {
739 media_deps.video_decoder_factory.reset();
740 }
741
Per Åhgrencc73ed32020-04-26 23:56:17 +0200742 if (!media_deps.audio_processing) {
743 // If the standard Creation method for APM returns a null pointer, instead
744 // use the builder for testing to create an APM object.
745 media_deps.audio_processing = AudioProcessingBuilderForTesting().Create();
746 }
747
Erik Språngceb44952020-09-22 11:36:35 +0200748 media_deps.trials = pc_factory_dependencies.trials.get();
749
Qingsi Wang7685e862018-06-11 20:15:46 -0700750 pc_factory_dependencies.media_engine =
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200751 cricket::CreateMediaEngine(std::move(media_deps));
Qingsi Wang7685e862018-06-11 20:15:46 -0700752 pc_factory_dependencies.call_factory = webrtc::CreateCallFactory();
753 if (event_log_factory) {
754 event_log_factory_ = event_log_factory.get();
755 pc_factory_dependencies.event_log_factory = std::move(event_log_factory);
756 } else {
757 pc_factory_dependencies.event_log_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200758 std::make_unique<webrtc::RtcEventLogFactory>(
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200759 pc_factory_dependencies.task_queue_factory.get());
Qingsi Wang7685e862018-06-11 20:15:46 -0700760 }
761 peer_connection_factory_ = webrtc::CreateModularPeerConnectionFactory(
762 std::move(pc_factory_dependencies));
763
deadbeef1dcb1642017-03-29 21:08:16 -0700764 if (!peer_connection_factory_) {
765 return false;
766 }
767 if (options) {
768 peer_connection_factory_->SetOptions(*options);
769 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800770 if (config) {
771 sdp_semantics_ = config->sdp_semantics;
772 }
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700773
774 dependencies.allocator = std::move(port_allocator);
Niels Möllerf06f9232018-08-07 12:32:18 +0200775 peer_connection_ = CreatePeerConnection(config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700776 return peer_connection_.get() != nullptr;
777 }
778
779 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(
deadbeef1dcb1642017-03-29 21:08:16 -0700780 const PeerConnectionInterface::RTCConfiguration* config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700781 webrtc::PeerConnectionDependencies dependencies) {
deadbeef1dcb1642017-03-29 21:08:16 -0700782 PeerConnectionInterface::RTCConfiguration modified_config;
783 // If |config| is null, this will result in a default configuration being
784 // used.
785 if (config) {
786 modified_config = *config;
787 }
788 // Disable resolution adaptation; we don't want it interfering with the
789 // test results.
790 // TODO(deadbeef): Do something more robust. Since we're testing for aspect
791 // ratios and not specific resolutions, is this even necessary?
792 modified_config.set_cpu_adaptation(false);
793
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700794 dependencies.observer = this;
deadbeef1dcb1642017-03-29 21:08:16 -0700795 return peer_connection_factory_->CreatePeerConnection(
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700796 modified_config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700797 }
798
799 void set_signaling_message_receiver(
800 SignalingMessageReceiver* signaling_message_receiver) {
801 signaling_message_receiver_ = signaling_message_receiver;
802 }
803
804 void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; }
805
Steve Antonede9ca52017-10-16 13:04:27 -0700806 void set_signal_ice_candidates(bool signal) {
807 signal_ice_candidates_ = signal;
808 }
809
deadbeef1dcb1642017-03-29 21:08:16 -0700810 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
Niels Möller5c7efe72018-05-11 10:34:46 +0200811 webrtc::FakePeriodicVideoSource::Config config) {
deadbeef1dcb1642017-03-29 21:08:16 -0700812 // Set max frame rate to 10fps to reduce the risk of test flakiness.
813 // TODO(deadbeef): Do something more robust.
Niels Möller5c7efe72018-05-11 10:34:46 +0200814 config.frame_interval_ms = 100;
deadbeef1dcb1642017-03-29 21:08:16 -0700815
Niels Möller5c7efe72018-05-11 10:34:46 +0200816 video_track_sources_.emplace_back(
Niels Möller0f405822018-05-17 09:16:41 +0200817 new rtc::RefCountedObject<webrtc::FakePeriodicVideoTrackSource>(
818 config, false /* remote */));
deadbeef1dcb1642017-03-29 21:08:16 -0700819 rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
Niels Möller5c7efe72018-05-11 10:34:46 +0200820 peer_connection_factory_->CreateVideoTrack(
821 rtc::CreateRandomUuid(), video_track_sources_.back()));
deadbeef1dcb1642017-03-29 21:08:16 -0700822 if (!local_video_renderer_) {
823 local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
824 }
825 return track;
826 }
827
828 void HandleIncomingOffer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100829 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer";
Steve Antona3a92c22017-12-07 10:27:41 -0800830 std::unique_ptr<SessionDescriptionInterface> desc =
831 webrtc::CreateSessionDescription(SdpType::kOffer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700832 if (received_sdp_munger_) {
833 received_sdp_munger_(desc->description());
834 }
835
836 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
837 // Setting a remote description may have changed the number of receivers,
838 // so reset the receiver observers.
839 ResetRtpReceiverObservers();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800840 if (remote_offer_handler_) {
841 remote_offer_handler_();
842 }
deadbeef1dcb1642017-03-29 21:08:16 -0700843 auto answer = CreateAnswer();
844 ASSERT_NE(nullptr, answer);
845 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
846 }
847
848 void HandleIncomingAnswer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100849 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
Steve Antona3a92c22017-12-07 10:27:41 -0800850 std::unique_ptr<SessionDescriptionInterface> desc =
851 webrtc::CreateSessionDescription(SdpType::kAnswer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700852 if (received_sdp_munger_) {
853 received_sdp_munger_(desc->description());
854 }
855
856 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
857 // Set the RtpReceiverObserver after receivers are created.
858 ResetRtpReceiverObservers();
859 }
860
861 // Returns null on failure.
deadbeef1dcb1642017-03-29 21:08:16 -0700862 std::unique_ptr<SessionDescriptionInterface> CreateAnswer() {
863 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
864 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
865 pc()->CreateAnswer(observer, offer_answer_options_);
866 return WaitForDescriptionFromObserver(observer);
867 }
868
869 std::unique_ptr<SessionDescriptionInterface> WaitForDescriptionFromObserver(
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100870 MockCreateSessionDescriptionObserver* observer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700871 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
872 if (!observer->result()) {
873 return nullptr;
874 }
875 auto description = observer->MoveDescription();
876 if (generated_sdp_munger_) {
877 generated_sdp_munger_(description->description());
878 }
879 return description;
880 }
881
882 // Setting the local description and sending the SDP message over the fake
883 // signaling channel are combined into the same method because the SDP
884 // message needs to be sent as soon as SetLocalDescription finishes, without
885 // waiting for the observer to be called. This ensures that ICE candidates
886 // don't outrace the description.
887 bool SetLocalDescriptionAndSendSdpMessage(
888 std::unique_ptr<SessionDescriptionInterface> desc) {
889 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
890 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100891 RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage";
Steve Antona3a92c22017-12-07 10:27:41 -0800892 SdpType type = desc->GetType();
deadbeef1dcb1642017-03-29 21:08:16 -0700893 std::string sdp;
894 EXPECT_TRUE(desc->ToString(&sdp));
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700895 RTC_LOG(LS_INFO) << debug_name_ << ": local SDP contents=\n" << sdp;
deadbeef1dcb1642017-03-29 21:08:16 -0700896 pc()->SetLocalDescription(observer, desc.release());
Harald Alvestrand6060df52020-08-11 09:54:02 +0200897 RemoveUnusedVideoRenderers();
deadbeef1dcb1642017-03-29 21:08:16 -0700898 // As mentioned above, we need to send the message immediately after
899 // SetLocalDescription.
900 SendSdpMessage(type, sdp);
901 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
902 return true;
903 }
904
905 bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
906 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
907 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100908 RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription";
deadbeef1dcb1642017-03-29 21:08:16 -0700909 pc()->SetRemoteDescription(observer, desc.release());
Harald Alvestrand6060df52020-08-11 09:54:02 +0200910 RemoveUnusedVideoRenderers();
deadbeef1dcb1642017-03-29 21:08:16 -0700911 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
912 return observer->result();
913 }
914
Seth Hampson2f0d7022018-02-20 11:54:42 -0800915 // This is a work around to remove unused fake_video_renderers from
916 // transceivers that have either stopped or are no longer receiving.
917 void RemoveUnusedVideoRenderers() {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200918 if (sdp_semantics_ != SdpSemantics::kUnifiedPlan) {
919 return;
920 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800921 auto transceivers = pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +0200922 std::set<std::string> active_renderers;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800923 for (auto& transceiver : transceivers) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200924 // Note - we don't check for direction here. This function is called
925 // before direction is set, and in that case, we should not remove
926 // the renderer.
927 if (transceiver->receiver()->media_type() == cricket::MEDIA_TYPE_VIDEO) {
928 active_renderers.insert(transceiver->receiver()->track()->id());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800929 }
Harald Alvestrand6060df52020-08-11 09:54:02 +0200930 }
931 for (auto it = fake_video_renderers_.begin();
932 it != fake_video_renderers_.end();) {
933 // Remove fake video renderers belonging to any non-active transceivers.
934 if (!active_renderers.count(it->first)) {
935 it = fake_video_renderers_.erase(it);
936 } else {
937 it++;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800938 }
939 }
940 }
941
deadbeef1dcb1642017-03-29 21:08:16 -0700942 // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by
943 // default).
Steve Antona3a92c22017-12-07 10:27:41 -0800944 void SendSdpMessage(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700945 if (signaling_delay_ms_ == 0) {
946 RelaySdpMessageIfReceiverExists(type, msg);
947 } else {
948 invoker_.AsyncInvokeDelayed<void>(
949 RTC_FROM_HERE, rtc::Thread::Current(),
Niels Möller4bab23f2021-01-18 09:24:33 +0100950 [this, type, msg] { RelaySdpMessageIfReceiverExists(type, msg); },
deadbeef1dcb1642017-03-29 21:08:16 -0700951 signaling_delay_ms_);
952 }
953 }
954
Steve Antona3a92c22017-12-07 10:27:41 -0800955 void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700956 if (signaling_message_receiver_) {
957 signaling_message_receiver_->ReceiveSdpMessage(type, msg);
958 }
959 }
960
961 // Simulate trickling an ICE candidate with delay |signaling_delay_ms_| (0 by
962 // default).
963 void SendIceMessage(const std::string& sdp_mid,
964 int sdp_mline_index,
965 const std::string& msg) {
966 if (signaling_delay_ms_ == 0) {
967 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
968 } else {
969 invoker_.AsyncInvokeDelayed<void>(
970 RTC_FROM_HERE, rtc::Thread::Current(),
Niels Möller4bab23f2021-01-18 09:24:33 +0100971 [this, sdp_mid, sdp_mline_index, msg] {
972 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
973 },
deadbeef1dcb1642017-03-29 21:08:16 -0700974 signaling_delay_ms_);
975 }
976 }
977
978 void RelayIceMessageIfReceiverExists(const std::string& sdp_mid,
979 int sdp_mline_index,
980 const std::string& msg) {
981 if (signaling_message_receiver_) {
982 signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index,
983 msg);
984 }
985 }
986
987 // SignalingMessageReceiver callbacks.
Steve Antona3a92c22017-12-07 10:27:41 -0800988 void ReceiveSdpMessage(SdpType type, const std::string& msg) override {
989 if (type == SdpType::kOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700990 HandleIncomingOffer(msg);
991 } else {
992 HandleIncomingAnswer(msg);
993 }
994 }
995
996 void ReceiveIceMessage(const std::string& sdp_mid,
997 int sdp_mline_index,
998 const std::string& msg) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100999 RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage";
deadbeef1dcb1642017-03-29 21:08:16 -07001000 std::unique_ptr<webrtc::IceCandidateInterface> candidate(
1001 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr));
1002 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
1003 }
1004
1005 // PeerConnectionObserver callbacks.
1006 void OnSignalingChange(
1007 webrtc::PeerConnectionInterface::SignalingState new_state) override {
1008 EXPECT_EQ(pc()->signaling_state(), new_state);
Eldar Rello5ab79e62019-10-09 18:29:44 +03001009 peer_connection_signaling_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -07001010 }
Steve Anton15324772018-01-16 10:26:49 -08001011 void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
1012 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
1013 streams) override {
1014 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
1015 rtc::scoped_refptr<VideoTrackInterface> video_track(
1016 static_cast<VideoTrackInterface*>(receiver->track().get()));
1017 ASSERT_TRUE(fake_video_renderers_.find(video_track->id()) ==
deadbeef1dcb1642017-03-29 21:08:16 -07001018 fake_video_renderers_.end());
Steve Anton15324772018-01-16 10:26:49 -08001019 fake_video_renderers_[video_track->id()] =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001020 std::make_unique<FakeVideoTrackRenderer>(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07001021 }
1022 }
Steve Anton15324772018-01-16 10:26:49 -08001023 void OnRemoveTrack(
1024 rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
1025 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
1026 auto it = fake_video_renderers_.find(receiver->track()->id());
Harald Alvestrand6060df52020-08-11 09:54:02 +02001027 if (it != fake_video_renderers_.end()) {
1028 fake_video_renderers_.erase(it);
1029 } else {
1030 RTC_LOG(LS_ERROR) << "OnRemoveTrack called for non-active renderer";
1031 }
Steve Anton15324772018-01-16 10:26:49 -08001032 }
1033 }
deadbeef1dcb1642017-03-29 21:08:16 -07001034 void OnRenegotiationNeeded() override {}
1035 void OnIceConnectionChange(
1036 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
1037 EXPECT_EQ(pc()->ice_connection_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -07001038 ice_connection_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -07001039 }
Jonas Olssonacd8ae72019-02-25 15:26:24 +01001040 void OnStandardizedIceConnectionChange(
1041 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
1042 standardized_ice_connection_state_history_.push_back(new_state);
1043 }
Jonas Olsson635474e2018-10-18 15:58:17 +02001044 void OnConnectionChange(
1045 webrtc::PeerConnectionInterface::PeerConnectionState new_state) override {
1046 peer_connection_state_history_.push_back(new_state);
1047 }
1048
deadbeef1dcb1642017-03-29 21:08:16 -07001049 void OnIceGatheringChange(
1050 webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
deadbeef1dcb1642017-03-29 21:08:16 -07001051 EXPECT_EQ(pc()->ice_gathering_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -07001052 ice_gathering_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -07001053 }
Alex Drake00c7ecf2019-08-06 10:54:47 -07001054
1055 void OnIceSelectedCandidatePairChanged(
1056 const cricket::CandidatePairChangeEvent& event) {
1057 ice_candidate_pair_change_history_.push_back(event);
1058 }
Alex Drake43faee02019-08-12 16:27:34 -07001059
deadbeef1dcb1642017-03-29 21:08:16 -07001060 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001061 RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate";
deadbeef1dcb1642017-03-29 21:08:16 -07001062
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001063 if (remote_async_resolver_) {
1064 const auto& local_candidate = candidate->candidate();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001065 if (local_candidate.address().IsUnresolvedIP()) {
1066 RTC_DCHECK(local_candidate.type() == cricket::LOCAL_PORT_TYPE);
1067 rtc::SocketAddress resolved_addr(local_candidate.address());
Qingsi Wangecd30542019-05-22 14:34:56 -07001068 const auto resolved_ip = mdns_responder_->GetMappedAddressForName(
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001069 local_candidate.address().hostname());
1070 RTC_DCHECK(!resolved_ip.IsNil());
1071 resolved_addr.SetResolvedIP(resolved_ip);
1072 EXPECT_CALL(*remote_async_resolver_, GetResolvedAddress(_, _))
1073 .WillOnce(DoAll(SetArgPointee<1>(resolved_addr), Return(true)));
1074 EXPECT_CALL(*remote_async_resolver_, Destroy(_));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001075 }
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001076 }
1077
deadbeef1dcb1642017-03-29 21:08:16 -07001078 std::string ice_sdp;
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001079 EXPECT_TRUE(candidate->ToString(&ice_sdp));
Steve Antonede9ca52017-10-16 13:04:27 -07001080 if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) {
deadbeef1dcb1642017-03-29 21:08:16 -07001081 // Remote party may be deleted.
1082 return;
1083 }
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001084 SendIceMessage(candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp);
Qingsi Wangc129c352019-04-18 10:41:58 -07001085 last_candidate_gathered_ = candidate->candidate();
deadbeef1dcb1642017-03-29 21:08:16 -07001086 }
Eldar Rello0095d372019-12-02 22:22:07 +02001087 void OnIceCandidateError(const std::string& address,
1088 int port,
Eldar Relloda13ea22019-06-01 12:23:43 +03001089 const std::string& url,
1090 int error_code,
1091 const std::string& error_text) override {
Eldar Rello0095d372019-12-02 22:22:07 +02001092 error_event_ = cricket::IceCandidateErrorEvent(address, port, url,
Eldar Relloda13ea22019-06-01 12:23:43 +03001093 error_code, error_text);
1094 }
deadbeef1dcb1642017-03-29 21:08:16 -07001095 void OnDataChannel(
1096 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001097 RTC_LOG(LS_INFO) << debug_name_ << ": OnDataChannel";
deadbeef1dcb1642017-03-29 21:08:16 -07001098 data_channel_ = data_channel;
1099 data_observer_.reset(new MockDataChannelObserver(data_channel));
1100 }
1101
deadbeef1dcb1642017-03-29 21:08:16 -07001102 std::string debug_name_;
1103
1104 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
Qingsi Wangecd30542019-05-22 14:34:56 -07001105 // Reference to the mDNS responder owned by |fake_network_manager_| after set.
1106 webrtc::FakeMdnsResponder* mdns_responder_ = nullptr;
deadbeef1dcb1642017-03-29 21:08:16 -07001107
1108 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
1109 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
1110 peer_connection_factory_;
1111
Steve Antonede9ca52017-10-16 13:04:27 -07001112 cricket::PortAllocator* port_allocator_;
deadbeef1dcb1642017-03-29 21:08:16 -07001113 // Needed to keep track of number of frames sent.
1114 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
1115 // Needed to keep track of number of frames received.
1116 std::map<std::string, std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
1117 fake_video_renderers_;
1118 // Needed to ensure frames aren't received for removed tracks.
1119 std::vector<std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
1120 removed_fake_video_renderers_;
deadbeef1dcb1642017-03-29 21:08:16 -07001121
1122 // For remote peer communication.
1123 SignalingMessageReceiver* signaling_message_receiver_ = nullptr;
1124 int signaling_delay_ms_ = 0;
Steve Antonede9ca52017-10-16 13:04:27 -07001125 bool signal_ice_candidates_ = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07001126 cricket::Candidate last_candidate_gathered_;
Eldar Relloda13ea22019-06-01 12:23:43 +03001127 cricket::IceCandidateErrorEvent error_event_;
deadbeef1dcb1642017-03-29 21:08:16 -07001128
Niels Möller5c7efe72018-05-11 10:34:46 +02001129 // Store references to the video sources we've created, so that we can stop
deadbeef1dcb1642017-03-29 21:08:16 -07001130 // them, if required.
Niels Möller5c7efe72018-05-11 10:34:46 +02001131 std::vector<rtc::scoped_refptr<webrtc::VideoTrackSource>>
1132 video_track_sources_;
deadbeef1dcb1642017-03-29 21:08:16 -07001133 // |local_video_renderer_| attached to the first created local video track.
1134 std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
1135
Seth Hampson2f0d7022018-02-20 11:54:42 -08001136 SdpSemantics sdp_semantics_;
deadbeef1dcb1642017-03-29 21:08:16 -07001137 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_;
1138 std::function<void(cricket::SessionDescription*)> received_sdp_munger_;
1139 std::function<void(cricket::SessionDescription*)> generated_sdp_munger_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001140 std::function<void()> remote_offer_handler_;
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001141 rtc::MockAsyncResolver* remote_async_resolver_ = nullptr;
deadbeef1dcb1642017-03-29 21:08:16 -07001142 rtc::scoped_refptr<DataChannelInterface> data_channel_;
1143 std::unique_ptr<MockDataChannelObserver> data_observer_;
1144
1145 std::vector<std::unique_ptr<MockRtpReceiverObserver>> rtp_receiver_observers_;
1146
Steve Antonede9ca52017-10-16 13:04:27 -07001147 std::vector<PeerConnectionInterface::IceConnectionState>
1148 ice_connection_state_history_;
Jonas Olssonacd8ae72019-02-25 15:26:24 +01001149 std::vector<PeerConnectionInterface::IceConnectionState>
1150 standardized_ice_connection_state_history_;
Jonas Olsson635474e2018-10-18 15:58:17 +02001151 std::vector<PeerConnectionInterface::PeerConnectionState>
1152 peer_connection_state_history_;
Steve Antonede9ca52017-10-16 13:04:27 -07001153 std::vector<PeerConnectionInterface::IceGatheringState>
1154 ice_gathering_state_history_;
Alex Drake00c7ecf2019-08-06 10:54:47 -07001155 std::vector<cricket::CandidatePairChangeEvent>
1156 ice_candidate_pair_change_history_;
Eldar Rello5ab79e62019-10-09 18:29:44 +03001157 std::vector<PeerConnectionInterface::SignalingState>
1158 peer_connection_signaling_state_history_;
Qingsi Wang7685e862018-06-11 20:15:46 -07001159 webrtc::FakeRtcEventLogFactory* event_log_factory_;
1160
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00001161 // Variables for tracking delay stats on an audio track
1162 int audio_packets_stat_ = 0;
1163 double audio_delay_stat_ = 0.0;
Harald Alvestrandcbacec52021-01-14 13:13:42 +00001164 uint64_t audio_samples_stat_ = 0;
1165 uint64_t audio_concealed_stat_ = 0;
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00001166 std::string rtp_stats_id_;
1167 std::string audio_track_stats_id_;
1168
deadbeef1dcb1642017-03-29 21:08:16 -07001169 rtc::AsyncInvoker invoker_;
1170
Seth Hampson2f0d7022018-02-20 11:54:42 -08001171 friend class PeerConnectionIntegrationBaseTest;
deadbeef1dcb1642017-03-29 21:08:16 -07001172};
1173
Elad Alon99c3fe52017-10-13 16:29:40 +02001174class MockRtcEventLogOutput : public webrtc::RtcEventLogOutput {
1175 public:
1176 virtual ~MockRtcEventLogOutput() = default;
Danil Chapovalov3a353122020-05-15 11:16:53 +02001177 MOCK_METHOD(bool, IsActive, (), (const, override));
1178 MOCK_METHOD(bool, Write, (const std::string&), (override));
Elad Alon99c3fe52017-10-13 16:29:40 +02001179};
1180
Seth Hampson2f0d7022018-02-20 11:54:42 -08001181// This helper object is used for both specifying how many audio/video frames
1182// are expected to be received for a caller/callee. It provides helper functions
1183// to specify these expectations. The object initially starts in a state of no
1184// expectations.
1185class MediaExpectations {
1186 public:
1187 enum ExpectFrames {
1188 kExpectSomeFrames,
1189 kExpectNoFrames,
1190 kNoExpectation,
1191 };
1192
1193 void ExpectBidirectionalAudioAndVideo() {
1194 ExpectBidirectionalAudio();
1195 ExpectBidirectionalVideo();
1196 }
1197
1198 void ExpectBidirectionalAudio() {
1199 CallerExpectsSomeAudio();
1200 CalleeExpectsSomeAudio();
1201 }
1202
1203 void ExpectNoAudio() {
1204 CallerExpectsNoAudio();
1205 CalleeExpectsNoAudio();
1206 }
1207
1208 void ExpectBidirectionalVideo() {
1209 CallerExpectsSomeVideo();
1210 CalleeExpectsSomeVideo();
1211 }
1212
1213 void ExpectNoVideo() {
1214 CallerExpectsNoVideo();
1215 CalleeExpectsNoVideo();
1216 }
1217
1218 void CallerExpectsSomeAudioAndVideo() {
1219 CallerExpectsSomeAudio();
1220 CallerExpectsSomeVideo();
1221 }
1222
1223 void CalleeExpectsSomeAudioAndVideo() {
1224 CalleeExpectsSomeAudio();
1225 CalleeExpectsSomeVideo();
1226 }
1227
1228 // Caller's audio functions.
1229 void CallerExpectsSomeAudio(
1230 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1231 caller_audio_expectation_ = kExpectSomeFrames;
1232 caller_audio_frames_expected_ = expected_audio_frames;
1233 }
1234
1235 void CallerExpectsNoAudio() {
1236 caller_audio_expectation_ = kExpectNoFrames;
1237 caller_audio_frames_expected_ = 0;
1238 }
1239
1240 // Caller's video functions.
1241 void CallerExpectsSomeVideo(
1242 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1243 caller_video_expectation_ = kExpectSomeFrames;
1244 caller_video_frames_expected_ = expected_video_frames;
1245 }
1246
1247 void CallerExpectsNoVideo() {
1248 caller_video_expectation_ = kExpectNoFrames;
1249 caller_video_frames_expected_ = 0;
1250 }
1251
1252 // Callee's audio functions.
1253 void CalleeExpectsSomeAudio(
1254 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1255 callee_audio_expectation_ = kExpectSomeFrames;
1256 callee_audio_frames_expected_ = expected_audio_frames;
1257 }
1258
1259 void CalleeExpectsNoAudio() {
1260 callee_audio_expectation_ = kExpectNoFrames;
1261 callee_audio_frames_expected_ = 0;
1262 }
1263
1264 // Callee's video functions.
1265 void CalleeExpectsSomeVideo(
1266 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1267 callee_video_expectation_ = kExpectSomeFrames;
1268 callee_video_frames_expected_ = expected_video_frames;
1269 }
1270
1271 void CalleeExpectsNoVideo() {
1272 callee_video_expectation_ = kExpectNoFrames;
1273 callee_video_frames_expected_ = 0;
1274 }
1275
1276 ExpectFrames caller_audio_expectation_ = kNoExpectation;
1277 ExpectFrames caller_video_expectation_ = kNoExpectation;
1278 ExpectFrames callee_audio_expectation_ = kNoExpectation;
1279 ExpectFrames callee_video_expectation_ = kNoExpectation;
1280 int caller_audio_frames_expected_ = 0;
1281 int caller_video_frames_expected_ = 0;
1282 int callee_audio_frames_expected_ = 0;
1283 int callee_video_frames_expected_ = 0;
1284};
1285
Qingsi Wang25ec8882019-11-15 12:33:05 -08001286class MockIceTransport : public webrtc::IceTransportInterface {
1287 public:
1288 MockIceTransport(const std::string& name, int component)
1289 : internal_(std::make_unique<cricket::FakeIceTransport>(
1290 name,
1291 component,
1292 nullptr /* network_thread */)) {}
1293 ~MockIceTransport() = default;
1294 cricket::IceTransportInternal* internal() { return internal_.get(); }
1295
1296 private:
1297 std::unique_ptr<cricket::FakeIceTransport> internal_;
1298};
1299
1300class MockIceTransportFactory : public IceTransportFactory {
1301 public:
1302 ~MockIceTransportFactory() override = default;
1303 rtc::scoped_refptr<IceTransportInterface> CreateIceTransport(
1304 const std::string& transport_name,
1305 int component,
1306 IceTransportInit init) {
1307 RecordIceTransportCreated();
1308 return new rtc::RefCountedObject<MockIceTransport>(transport_name,
1309 component);
1310 }
Danil Chapovalov3a353122020-05-15 11:16:53 +02001311 MOCK_METHOD(void, RecordIceTransportCreated, ());
Qingsi Wang25ec8882019-11-15 12:33:05 -08001312};
1313
deadbeef1dcb1642017-03-29 21:08:16 -07001314// Tests two PeerConnections connecting to each other end-to-end, using a
1315// virtual network, fake A/V capture and fake encoder/decoders. The
1316// PeerConnections share the threads/socket servers, but use separate versions
1317// of everything else (including "PeerConnectionFactory"s).
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001318class PeerConnectionIntegrationBaseTest : public ::testing::Test {
deadbeef1dcb1642017-03-29 21:08:16 -07001319 public:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001320 explicit PeerConnectionIntegrationBaseTest(SdpSemantics sdp_semantics)
1321 : sdp_semantics_(sdp_semantics),
1322 ss_(new rtc::VirtualSocketServer()),
Steve Antonede9ca52017-10-16 13:04:27 -07001323 fss_(new rtc::FirewallSocketServer(ss_.get())),
1324 network_thread_(new rtc::Thread(fss_.get())),
Niels Möller2a707032020-06-16 16:39:13 +02001325 worker_thread_(rtc::Thread::Create()) {
Sebastian Jansson8a793a02018-03-13 15:21:48 +01001326 network_thread_->SetName("PCNetworkThread", this);
1327 worker_thread_->SetName("PCWorkerThread", this);
deadbeef1dcb1642017-03-29 21:08:16 -07001328 RTC_CHECK(network_thread_->Start());
1329 RTC_CHECK(worker_thread_->Start());
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001330 webrtc::metrics::Reset();
deadbeef1dcb1642017-03-29 21:08:16 -07001331 }
1332
Seth Hampson2f0d7022018-02-20 11:54:42 -08001333 ~PeerConnectionIntegrationBaseTest() {
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00001334 // The PeerConnections should be deleted before the TurnCustomizers.
Seth Hampsonaed71642018-06-11 07:41:32 -07001335 // A TurnPort is created with a raw pointer to a TurnCustomizer. The
1336 // TurnPort has the same lifetime as the PeerConnection, so it's expected
1337 // that the TurnCustomizer outlives the life of the PeerConnection or else
1338 // when Send() is called it will hit a seg fault.
deadbeef1dcb1642017-03-29 21:08:16 -07001339 if (caller_) {
1340 caller_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001341 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001342 }
1343 if (callee_) {
1344 callee_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001345 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001346 }
Seth Hampsonaed71642018-06-11 07:41:32 -07001347
1348 // If turn servers were created for the test they need to be destroyed on
1349 // the network thread.
1350 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
1351 turn_servers_.clear();
1352 turn_customizers_.clear();
1353 });
deadbeef1dcb1642017-03-29 21:08:16 -07001354 }
1355
1356 bool SignalingStateStable() {
1357 return caller_->SignalingStateStable() && callee_->SignalingStateStable();
1358 }
1359
deadbeef71452802017-05-07 17:21:01 -07001360 bool DtlsConnected() {
Alex Loiko9289eda2018-11-23 16:18:59 +00001361 // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS
1362 // are connected. This is an important distinction. Once we have separate
1363 // ICE and DTLS state, this check needs to use the DTLS state.
1364 return (callee()->ice_connection_state() ==
1365 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1366 callee()->ice_connection_state() ==
1367 webrtc::PeerConnectionInterface::kIceConnectionCompleted) &&
1368 (caller()->ice_connection_state() ==
1369 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1370 caller()->ice_connection_state() ==
1371 webrtc::PeerConnectionInterface::kIceConnectionCompleted);
deadbeef71452802017-05-07 17:21:01 -07001372 }
1373
Qingsi Wang7685e862018-06-11 20:15:46 -07001374 // When |event_log_factory| is null, the default implementation of the event
1375 // log factory will be used.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001376 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWrapper(
1377 const std::string& debug_name,
Seth Hampson2f0d7022018-02-20 11:54:42 -08001378 const PeerConnectionFactory::Options* options,
1379 const RTCConfiguration* config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001380 webrtc::PeerConnectionDependencies dependencies,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001381 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory,
Johannes Kron3e983682020-03-29 22:17:00 +02001382 bool reset_encoder_factory,
1383 bool reset_decoder_factory) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001384 RTCConfiguration modified_config;
1385 if (config) {
1386 modified_config = *config;
1387 }
Steve Anton3acffc32018-04-12 17:21:03 -07001388 modified_config.sdp_semantics = sdp_semantics_;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001389 if (!dependencies.cert_generator) {
1390 dependencies.cert_generator =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001391 std::make_unique<FakeRTCCertificateGenerator>();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001392 }
1393 std::unique_ptr<PeerConnectionWrapper> client(
1394 new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001395
Niels Möllerf06f9232018-08-07 12:32:18 +02001396 if (!client->Init(options, &modified_config, std::move(dependencies),
1397 network_thread_.get(), worker_thread_.get(),
Niels Möller2a707032020-06-16 16:39:13 +02001398 std::move(event_log_factory), reset_encoder_factory,
Johannes Kron3e983682020-03-29 22:17:00 +02001399 reset_decoder_factory)) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001400 return nullptr;
1401 }
1402 return client;
1403 }
1404
Qingsi Wang7685e862018-06-11 20:15:46 -07001405 std::unique_ptr<PeerConnectionWrapper>
1406 CreatePeerConnectionWrapperWithFakeRtcEventLog(
1407 const std::string& debug_name,
Qingsi Wang7685e862018-06-11 20:15:46 -07001408 const PeerConnectionFactory::Options* options,
1409 const RTCConfiguration* config,
1410 webrtc::PeerConnectionDependencies dependencies) {
Danil Chapovalov4f281f12021-01-18 13:29:00 +01001411 return CreatePeerConnectionWrapper(
1412 debug_name, options, config, std::move(dependencies),
1413 std::make_unique<webrtc::FakeRtcEventLogFactory>(),
1414 /*reset_encoder_factory=*/false,
1415 /*reset_decoder_factory=*/false);
Qingsi Wang7685e862018-06-11 20:15:46 -07001416 }
1417
deadbeef1dcb1642017-03-29 21:08:16 -07001418 bool CreatePeerConnectionWrappers() {
1419 return CreatePeerConnectionWrappersWithConfig(
1420 PeerConnectionInterface::RTCConfiguration(),
1421 PeerConnectionInterface::RTCConfiguration());
1422 }
1423
Steve Anton3acffc32018-04-12 17:21:03 -07001424 bool CreatePeerConnectionWrappersWithSdpSemantics(
1425 SdpSemantics caller_semantics,
1426 SdpSemantics callee_semantics) {
1427 // Can't specify the sdp_semantics in the passed-in configuration since it
1428 // will be overwritten by CreatePeerConnectionWrapper with whatever is
1429 // stored in sdp_semantics_. So get around this by modifying the instance
1430 // variable before calling CreatePeerConnectionWrapper for the caller and
1431 // callee PeerConnections.
1432 SdpSemantics original_semantics = sdp_semantics_;
1433 sdp_semantics_ = caller_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001434 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001435 "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001436 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001437 /*reset_encoder_factory=*/false,
1438 /*reset_decoder_factory=*/false);
Steve Anton3acffc32018-04-12 17:21:03 -07001439 sdp_semantics_ = callee_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001440 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001441 "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001442 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001443 /*reset_encoder_factory=*/false,
1444 /*reset_decoder_factory=*/false);
Steve Anton3acffc32018-04-12 17:21:03 -07001445 sdp_semantics_ = original_semantics;
1446 return caller_ && callee_;
1447 }
1448
deadbeef1dcb1642017-03-29 21:08:16 -07001449 bool CreatePeerConnectionWrappersWithConfig(
1450 const PeerConnectionInterface::RTCConfiguration& caller_config,
1451 const PeerConnectionInterface::RTCConfiguration& callee_config) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001452 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001453 "Caller", nullptr, &caller_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001454 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001455 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001456 /*reset_decoder_factory=*/false);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001457 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001458 "Callee", nullptr, &callee_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001459 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001460 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001461 /*reset_decoder_factory=*/false);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001462 return caller_ && callee_;
1463 }
1464
1465 bool CreatePeerConnectionWrappersWithConfigAndDeps(
1466 const PeerConnectionInterface::RTCConfiguration& caller_config,
1467 webrtc::PeerConnectionDependencies caller_dependencies,
1468 const PeerConnectionInterface::RTCConfiguration& callee_config,
1469 webrtc::PeerConnectionDependencies callee_dependencies) {
Niels Möller2a707032020-06-16 16:39:13 +02001470 caller_ =
1471 CreatePeerConnectionWrapper("Caller", nullptr, &caller_config,
1472 std::move(caller_dependencies), nullptr,
1473 /*reset_encoder_factory=*/false,
1474 /*reset_decoder_factory=*/false);
1475 callee_ =
1476 CreatePeerConnectionWrapper("Callee", nullptr, &callee_config,
1477 std::move(callee_dependencies), nullptr,
1478 /*reset_encoder_factory=*/false,
1479 /*reset_decoder_factory=*/false);
deadbeef1dcb1642017-03-29 21:08:16 -07001480 return caller_ && callee_;
1481 }
1482
1483 bool CreatePeerConnectionWrappersWithOptions(
1484 const PeerConnectionFactory::Options& caller_options,
1485 const PeerConnectionFactory::Options& callee_options) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001486 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001487 "Caller", &caller_options, nullptr,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001488 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001489 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001490 /*reset_decoder_factory=*/false);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001491 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001492 "Callee", &callee_options, nullptr,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001493 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001494 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001495 /*reset_decoder_factory=*/false);
Qingsi Wang7685e862018-06-11 20:15:46 -07001496 return caller_ && callee_;
1497 }
1498
1499 bool CreatePeerConnectionWrappersWithFakeRtcEventLog() {
1500 PeerConnectionInterface::RTCConfiguration default_config;
1501 caller_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001502 "Caller", nullptr, &default_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001503 webrtc::PeerConnectionDependencies(nullptr));
1504 callee_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001505 "Callee", nullptr, &default_config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001506 webrtc::PeerConnectionDependencies(nullptr));
deadbeef1dcb1642017-03-29 21:08:16 -07001507 return caller_ && callee_;
1508 }
1509
Seth Hampson2f0d7022018-02-20 11:54:42 -08001510 std::unique_ptr<PeerConnectionWrapper>
1511 CreatePeerConnectionWrapperWithAlternateKey() {
deadbeef1dcb1642017-03-29 21:08:16 -07001512 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
1513 new FakeRTCCertificateGenerator());
1514 cert_generator->use_alternate_key();
1515
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001516 webrtc::PeerConnectionDependencies dependencies(nullptr);
1517 dependencies.cert_generator = std::move(cert_generator);
Niels Möller2a707032020-06-16 16:39:13 +02001518 return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr,
1519 std::move(dependencies), nullptr,
1520 /*reset_encoder_factory=*/false,
1521 /*reset_decoder_factory=*/false);
Johannes Kron3e983682020-03-29 22:17:00 +02001522 }
1523
1524 bool CreateOneDirectionalPeerConnectionWrappers(bool caller_to_callee) {
1525 caller_ = CreatePeerConnectionWrapper(
1526 "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001527 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001528 /*reset_encoder_factory=*/!caller_to_callee,
1529 /*reset_decoder_factory=*/caller_to_callee);
1530 callee_ = CreatePeerConnectionWrapper(
1531 "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001532 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001533 /*reset_encoder_factory=*/caller_to_callee,
1534 /*reset_decoder_factory=*/!caller_to_callee);
1535 return caller_ && callee_;
deadbeef1dcb1642017-03-29 21:08:16 -07001536 }
1537
Seth Hampsonaed71642018-06-11 07:41:32 -07001538 cricket::TestTurnServer* CreateTurnServer(
1539 rtc::SocketAddress internal_address,
1540 rtc::SocketAddress external_address,
1541 cricket::ProtocolType type = cricket::ProtocolType::PROTO_UDP,
1542 const std::string& common_name = "test turn server") {
1543 rtc::Thread* thread = network_thread();
1544 std::unique_ptr<cricket::TestTurnServer> turn_server =
1545 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnServer>>(
1546 RTC_FROM_HERE,
1547 [thread, internal_address, external_address, type, common_name] {
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001548 return std::make_unique<cricket::TestTurnServer>(
Seth Hampsonaed71642018-06-11 07:41:32 -07001549 thread, internal_address, external_address, type,
1550 /*ignore_bad_certs=*/true, common_name);
1551 });
1552 turn_servers_.push_back(std::move(turn_server));
1553 // Interactions with the turn server should be done on the network thread.
1554 return turn_servers_.back().get();
1555 }
1556
1557 cricket::TestTurnCustomizer* CreateTurnCustomizer() {
1558 std::unique_ptr<cricket::TestTurnCustomizer> turn_customizer =
1559 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnCustomizer>>(
1560 RTC_FROM_HERE,
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001561 [] { return std::make_unique<cricket::TestTurnCustomizer>(); });
Seth Hampsonaed71642018-06-11 07:41:32 -07001562 turn_customizers_.push_back(std::move(turn_customizer));
1563 // Interactions with the turn customizer should be done on the network
1564 // thread.
1565 return turn_customizers_.back().get();
1566 }
1567
1568 // Checks that the function counters for a TestTurnCustomizer are greater than
1569 // 0.
1570 void ExpectTurnCustomizerCountersIncremented(
1571 cricket::TestTurnCustomizer* turn_customizer) {
1572 unsigned int allow_channel_data_counter =
1573 network_thread()->Invoke<unsigned int>(
1574 RTC_FROM_HERE, [turn_customizer] {
1575 return turn_customizer->allow_channel_data_cnt_;
1576 });
1577 EXPECT_GT(allow_channel_data_counter, 0u);
1578 unsigned int modify_counter = network_thread()->Invoke<unsigned int>(
1579 RTC_FROM_HERE,
1580 [turn_customizer] { return turn_customizer->modify_cnt_; });
1581 EXPECT_GT(modify_counter, 0u);
1582 }
1583
deadbeef1dcb1642017-03-29 21:08:16 -07001584 // Once called, SDP blobs and ICE candidates will be automatically signaled
1585 // between PeerConnections.
1586 void ConnectFakeSignaling() {
1587 caller_->set_signaling_message_receiver(callee_.get());
1588 callee_->set_signaling_message_receiver(caller_.get());
1589 }
1590
Steve Antonede9ca52017-10-16 13:04:27 -07001591 // Once called, SDP blobs will be automatically signaled between
1592 // PeerConnections. Note that ICE candidates will not be signaled unless they
1593 // are in the exchanged SDP blobs.
1594 void ConnectFakeSignalingForSdpOnly() {
1595 ConnectFakeSignaling();
1596 SetSignalIceCandidates(false);
1597 }
1598
deadbeef1dcb1642017-03-29 21:08:16 -07001599 void SetSignalingDelayMs(int delay_ms) {
1600 caller_->set_signaling_delay_ms(delay_ms);
1601 callee_->set_signaling_delay_ms(delay_ms);
1602 }
1603
Steve Antonede9ca52017-10-16 13:04:27 -07001604 void SetSignalIceCandidates(bool signal) {
1605 caller_->set_signal_ice_candidates(signal);
1606 callee_->set_signal_ice_candidates(signal);
1607 }
1608
deadbeef1dcb1642017-03-29 21:08:16 -07001609 // Messages may get lost on the unreliable DataChannel, so we send multiple
1610 // times to avoid test flakiness.
1611 void SendRtpDataWithRetries(webrtc::DataChannelInterface* dc,
1612 const std::string& data,
1613 int retries) {
1614 for (int i = 0; i < retries; ++i) {
1615 dc->Send(DataBuffer(data));
1616 }
1617 }
1618
1619 rtc::Thread* network_thread() { return network_thread_.get(); }
1620
1621 rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); }
1622
1623 PeerConnectionWrapper* caller() { return caller_.get(); }
1624
1625 // Set the |caller_| to the |wrapper| passed in and return the
1626 // original |caller_|.
1627 PeerConnectionWrapper* SetCallerPcWrapperAndReturnCurrent(
1628 PeerConnectionWrapper* wrapper) {
1629 PeerConnectionWrapper* old = caller_.release();
1630 caller_.reset(wrapper);
1631 return old;
1632 }
1633
1634 PeerConnectionWrapper* callee() { return callee_.get(); }
1635
1636 // Set the |callee_| to the |wrapper| passed in and return the
1637 // original |callee_|.
1638 PeerConnectionWrapper* SetCalleePcWrapperAndReturnCurrent(
1639 PeerConnectionWrapper* wrapper) {
1640 PeerConnectionWrapper* old = callee_.release();
1641 callee_.reset(wrapper);
1642 return old;
1643 }
1644
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001645 void SetPortAllocatorFlags(uint32_t caller_flags, uint32_t callee_flags) {
Niels Möller4bab23f2021-01-18 09:24:33 +01001646 network_thread()->Invoke<void>(RTC_FROM_HERE, [this, caller_flags] {
1647 caller()->port_allocator()->set_flags(caller_flags);
1648 });
1649 network_thread()->Invoke<void>(RTC_FROM_HERE, [this, callee_flags] {
1650 callee()->port_allocator()->set_flags(callee_flags);
1651 });
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001652 }
1653
Steve Antonede9ca52017-10-16 13:04:27 -07001654 rtc::FirewallSocketServer* firewall() const { return fss_.get(); }
1655
Seth Hampson2f0d7022018-02-20 11:54:42 -08001656 // Expects the provided number of new frames to be received within
1657 // kMaxWaitForFramesMs. The new expected frames are specified in
1658 // |media_expectations|. Returns false if any of the expectations were
1659 // not met.
1660 bool ExpectNewFrames(const MediaExpectations& media_expectations) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02001661 // Make sure there are no bogus tracks confusing the issue.
1662 caller()->RemoveUnusedVideoRenderers();
1663 callee()->RemoveUnusedVideoRenderers();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001664 // First initialize the expected frame counts based upon the current
1665 // frame count.
1666 int total_caller_audio_frames_expected = caller()->audio_frames_received();
1667 if (media_expectations.caller_audio_expectation_ ==
1668 MediaExpectations::kExpectSomeFrames) {
1669 total_caller_audio_frames_expected +=
1670 media_expectations.caller_audio_frames_expected_;
1671 }
1672 int total_caller_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001673 caller()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001674 if (media_expectations.caller_video_expectation_ ==
1675 MediaExpectations::kExpectSomeFrames) {
1676 total_caller_video_frames_expected +=
1677 media_expectations.caller_video_frames_expected_;
1678 }
1679 int total_callee_audio_frames_expected = callee()->audio_frames_received();
1680 if (media_expectations.callee_audio_expectation_ ==
1681 MediaExpectations::kExpectSomeFrames) {
1682 total_callee_audio_frames_expected +=
1683 media_expectations.callee_audio_frames_expected_;
1684 }
1685 int total_callee_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001686 callee()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001687 if (media_expectations.callee_video_expectation_ ==
1688 MediaExpectations::kExpectSomeFrames) {
1689 total_callee_video_frames_expected +=
1690 media_expectations.callee_video_frames_expected_;
1691 }
deadbeef1dcb1642017-03-29 21:08:16 -07001692
Seth Hampson2f0d7022018-02-20 11:54:42 -08001693 // Wait for the expected frames.
deadbeef1dcb1642017-03-29 21:08:16 -07001694 EXPECT_TRUE_WAIT(caller()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001695 total_caller_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001696 caller()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001697 total_caller_video_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001698 callee()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001699 total_callee_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001700 callee()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001701 total_callee_video_frames_expected,
1702 kMaxWaitForFramesMs);
1703 bool expectations_correct =
1704 caller()->audio_frames_received() >=
1705 total_caller_audio_frames_expected &&
1706 caller()->min_video_frames_received_per_track() >=
1707 total_caller_video_frames_expected &&
1708 callee()->audio_frames_received() >=
1709 total_callee_audio_frames_expected &&
1710 callee()->min_video_frames_received_per_track() >=
1711 total_callee_video_frames_expected;
deadbeef1dcb1642017-03-29 21:08:16 -07001712
Seth Hampson2f0d7022018-02-20 11:54:42 -08001713 // After the combined wait, print out a more detailed message upon
1714 // failure.
deadbeef1dcb1642017-03-29 21:08:16 -07001715 EXPECT_GE(caller()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001716 total_caller_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001717 EXPECT_GE(caller()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001718 total_caller_video_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001719 EXPECT_GE(callee()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001720 total_callee_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001721 EXPECT_GE(callee()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001722 total_callee_video_frames_expected);
1723
1724 // We want to make sure nothing unexpected was received.
1725 if (media_expectations.caller_audio_expectation_ ==
1726 MediaExpectations::kExpectNoFrames) {
1727 EXPECT_EQ(caller()->audio_frames_received(),
1728 total_caller_audio_frames_expected);
1729 if (caller()->audio_frames_received() !=
1730 total_caller_audio_frames_expected) {
1731 expectations_correct = false;
1732 }
1733 }
1734 if (media_expectations.caller_video_expectation_ ==
1735 MediaExpectations::kExpectNoFrames) {
1736 EXPECT_EQ(caller()->min_video_frames_received_per_track(),
1737 total_caller_video_frames_expected);
1738 if (caller()->min_video_frames_received_per_track() !=
1739 total_caller_video_frames_expected) {
1740 expectations_correct = false;
1741 }
1742 }
1743 if (media_expectations.callee_audio_expectation_ ==
1744 MediaExpectations::kExpectNoFrames) {
1745 EXPECT_EQ(callee()->audio_frames_received(),
1746 total_callee_audio_frames_expected);
1747 if (callee()->audio_frames_received() !=
1748 total_callee_audio_frames_expected) {
1749 expectations_correct = false;
1750 }
1751 }
1752 if (media_expectations.callee_video_expectation_ ==
1753 MediaExpectations::kExpectNoFrames) {
1754 EXPECT_EQ(callee()->min_video_frames_received_per_track(),
1755 total_callee_video_frames_expected);
1756 if (callee()->min_video_frames_received_per_track() !=
1757 total_callee_video_frames_expected) {
1758 expectations_correct = false;
1759 }
1760 }
1761 return expectations_correct;
deadbeef1dcb1642017-03-29 21:08:16 -07001762 }
1763
Steve Antond91969e2019-05-30 12:27:03 -07001764 void ClosePeerConnections() {
1765 caller()->pc()->Close();
1766 callee()->pc()->Close();
1767 }
1768
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001769 void TestNegotiatedCipherSuite(
1770 const PeerConnectionFactory::Options& caller_options,
1771 const PeerConnectionFactory::Options& callee_options,
1772 int expected_cipher_suite) {
deadbeef1dcb1642017-03-29 21:08:16 -07001773 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options,
1774 callee_options));
deadbeef1dcb1642017-03-29 21:08:16 -07001775 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001776 caller()->AddAudioVideoTracks();
1777 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001778 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001779 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001780 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite),
deadbeefd8ad7882017-04-18 16:01:17 -07001781 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001782 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001783 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1784 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1785 expected_cipher_suite));
deadbeef1dcb1642017-03-29 21:08:16 -07001786 }
1787
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001788 void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
1789 bool remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001790 bool aes_ctr_enabled,
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001791 int expected_cipher_suite) {
1792 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001793 caller_options.crypto_options.srtp.enable_gcm_crypto_suites =
1794 local_gcm_enabled;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001795 caller_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher =
1796 aes_ctr_enabled;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001797 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001798 callee_options.crypto_options.srtp.enable_gcm_crypto_suites =
1799 remote_gcm_enabled;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001800 callee_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher =
1801 aes_ctr_enabled;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001802 TestNegotiatedCipherSuite(caller_options, callee_options,
1803 expected_cipher_suite);
1804 }
1805
Seth Hampson2f0d7022018-02-20 11:54:42 -08001806 protected:
Steve Anton3acffc32018-04-12 17:21:03 -07001807 SdpSemantics sdp_semantics_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001808
deadbeef1dcb1642017-03-29 21:08:16 -07001809 private:
1810 // |ss_| is used by |network_thread_| so it must be destroyed later.
deadbeef1dcb1642017-03-29 21:08:16 -07001811 std::unique_ptr<rtc::VirtualSocketServer> ss_;
Steve Antonede9ca52017-10-16 13:04:27 -07001812 std::unique_ptr<rtc::FirewallSocketServer> fss_;
deadbeef1dcb1642017-03-29 21:08:16 -07001813 // |network_thread_| and |worker_thread_| are used by both
1814 // |caller_| and |callee_| so they must be destroyed
1815 // later.
1816 std::unique_ptr<rtc::Thread> network_thread_;
1817 std::unique_ptr<rtc::Thread> worker_thread_;
Seth Hampsonaed71642018-06-11 07:41:32 -07001818 // The turn servers and turn customizers should be accessed & deleted on the
1819 // network thread to avoid a race with the socket read/write that occurs
1820 // on the network thread.
1821 std::vector<std::unique_ptr<cricket::TestTurnServer>> turn_servers_;
1822 std::vector<std::unique_ptr<cricket::TestTurnCustomizer>> turn_customizers_;
deadbeef1dcb1642017-03-29 21:08:16 -07001823 std::unique_ptr<PeerConnectionWrapper> caller_;
1824 std::unique_ptr<PeerConnectionWrapper> callee_;
1825};
1826
Seth Hampson2f0d7022018-02-20 11:54:42 -08001827class PeerConnectionIntegrationTest
1828 : public PeerConnectionIntegrationBaseTest,
1829 public ::testing::WithParamInterface<SdpSemantics> {
1830 protected:
1831 PeerConnectionIntegrationTest()
1832 : PeerConnectionIntegrationBaseTest(GetParam()) {}
1833};
1834
Yves Gerey100fe632020-01-17 19:15:53 +01001835// Fake clock must be set before threads are started to prevent race on
1836// Set/GetClockForTesting().
1837// To achieve that, multiple inheritance is used as a mixin pattern
1838// where order of construction is finely controlled.
1839// This also ensures peerconnection is closed before switching back to non-fake
1840// clock, avoiding other races and DCHECK failures such as in rtp_sender.cc.
1841class FakeClockForTest : public rtc::ScopedFakeClock {
1842 protected:
1843 FakeClockForTest() {
1844 // Some things use a time of "0" as a special value, so we need to start out
1845 // the fake clock at a nonzero time.
1846 // TODO(deadbeef): Fix this.
Danil Chapovalov0c626af2020-02-10 11:16:00 +01001847 AdvanceTime(webrtc::TimeDelta::Seconds(1));
Yves Gerey100fe632020-01-17 19:15:53 +01001848 }
1849
1850 // Explicit handle.
1851 ScopedFakeClock& FakeClock() { return *this; }
1852};
1853
1854// Ensure FakeClockForTest is constructed first (see class for rationale).
1855class PeerConnectionIntegrationTestWithFakeClock
1856 : public FakeClockForTest,
1857 public PeerConnectionIntegrationTest {};
1858
Seth Hampson2f0d7022018-02-20 11:54:42 -08001859class PeerConnectionIntegrationTestPlanB
1860 : public PeerConnectionIntegrationBaseTest {
1861 protected:
1862 PeerConnectionIntegrationTestPlanB()
1863 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
1864};
1865
1866class PeerConnectionIntegrationTestUnifiedPlan
1867 : public PeerConnectionIntegrationBaseTest {
1868 protected:
1869 PeerConnectionIntegrationTestUnifiedPlan()
1870 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
1871};
1872
deadbeef1dcb1642017-03-29 21:08:16 -07001873// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
1874// includes testing that the callback is invoked if an observer is connected
1875// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001876TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001877 RtpReceiverObserverOnFirstPacketReceived) {
1878 ASSERT_TRUE(CreatePeerConnectionWrappers());
1879 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001880 caller()->AddAudioVideoTracks();
1881 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001882 // Start offer/answer exchange and wait for it to complete.
1883 caller()->CreateAndSetAndSignalOffer();
1884 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1885 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001886 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1887 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001888 // Wait for all "first packet received" callbacks to be fired.
1889 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -08001890 absl::c_all_of(caller()->rtp_receiver_observers(),
1891 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1892 return o->first_packet_received();
1893 }),
deadbeef1dcb1642017-03-29 21:08:16 -07001894 kMaxWaitForFramesMs);
1895 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -08001896 absl::c_all_of(callee()->rtp_receiver_observers(),
1897 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1898 return o->first_packet_received();
1899 }),
deadbeef1dcb1642017-03-29 21:08:16 -07001900 kMaxWaitForFramesMs);
1901 // If new observers are set after the first packet was already received, the
1902 // callback should still be invoked.
1903 caller()->ResetRtpReceiverObservers();
1904 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001905 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1906 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001907 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -08001908 absl::c_all_of(caller()->rtp_receiver_observers(),
1909 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1910 return o->first_packet_received();
1911 }));
deadbeef1dcb1642017-03-29 21:08:16 -07001912 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -08001913 absl::c_all_of(callee()->rtp_receiver_observers(),
1914 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1915 return o->first_packet_received();
1916 }));
deadbeef1dcb1642017-03-29 21:08:16 -07001917}
1918
1919class DummyDtmfObserver : public DtmfSenderObserverInterface {
1920 public:
1921 DummyDtmfObserver() : completed_(false) {}
1922
1923 // Implements DtmfSenderObserverInterface.
1924 void OnToneChange(const std::string& tone) override {
1925 tones_.push_back(tone);
1926 if (tone.empty()) {
1927 completed_ = true;
1928 }
1929 }
1930
1931 const std::vector<std::string>& tones() const { return tones_; }
1932 bool completed() const { return completed_; }
1933
1934 private:
1935 bool completed_;
1936 std::vector<std::string> tones_;
1937};
1938
1939// Assumes |sender| already has an audio track added and the offer/answer
1940// exchange is done.
1941void TestDtmfFromSenderToReceiver(PeerConnectionWrapper* sender,
1942 PeerConnectionWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -08001943 // We should be able to get a DTMF sender from the local sender.
1944 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
1945 sender->pc()->GetSenders().at(0)->GetDtmfSender();
1946 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -07001947 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -07001948 dtmf_sender->RegisterObserver(&observer);
1949
1950 // Test the DtmfSender object just created.
1951 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
1952 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
1953
1954 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
1955 std::vector<std::string> tones = {"1", "a", ""};
1956 EXPECT_EQ(tones, observer.tones());
1957 dtmf_sender->UnregisterObserver();
1958 // TODO(deadbeef): Verify the tones were actually received end-to-end.
1959}
1960
1961// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
1962// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001963TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -07001964 ASSERT_TRUE(CreatePeerConnectionWrappers());
1965 ConnectFakeSignaling();
1966 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -08001967 caller()->AddAudioTrack();
1968 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001969 caller()->CreateAndSetAndSignalOffer();
1970 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -07001971 // DTLS must finish before the DTMF sender can be used reliably.
1972 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001973 TestDtmfFromSenderToReceiver(caller(), callee());
1974 TestDtmfFromSenderToReceiver(callee(), caller());
1975}
1976
1977// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
1978// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001979TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -07001980 ASSERT_TRUE(CreatePeerConnectionWrappers());
1981 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +01001982
deadbeef1dcb1642017-03-29 21:08:16 -07001983 // Do normal offer/answer and wait for some frames to be received in each
1984 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001985 caller()->AddAudioVideoTracks();
1986 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001987 caller()->CreateAndSetAndSignalOffer();
1988 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001989 MediaExpectations media_expectations;
1990 media_expectations.ExpectBidirectionalAudioAndVideo();
1991 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Ying Wangef3998f2019-12-09 13:06:53 +01001992 EXPECT_METRIC_LE(
1993 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1994 webrtc::kEnumCounterKeyProtocolDtls));
1995 EXPECT_METRIC_EQ(
1996 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1997 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -07001998}
1999
2000// Uses SDES instead of DTLS for key agreement.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002001TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
deadbeef1dcb1642017-03-29 21:08:16 -07002002 PeerConnectionInterface::RTCConfiguration sdes_config;
2003 sdes_config.enable_dtls_srtp.emplace(false);
2004 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
2005 ConnectFakeSignaling();
2006
2007 // Do normal offer/answer and wait for some frames to be received in each
2008 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002009 caller()->AddAudioVideoTracks();
2010 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002011 caller()->CreateAndSetAndSignalOffer();
2012 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002013 MediaExpectations media_expectations;
2014 media_expectations.ExpectBidirectionalAudioAndVideo();
2015 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Ying Wangef3998f2019-12-09 13:06:53 +01002016 EXPECT_METRIC_LE(
2017 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
2018 webrtc::kEnumCounterKeyProtocolSdes));
2019 EXPECT_METRIC_EQ(
2020 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
2021 webrtc::kEnumCounterKeyProtocolDtls));
deadbeef1dcb1642017-03-29 21:08:16 -07002022}
2023
Steve Anton9a44b2d2019-07-12 12:58:30 -07002024// Basic end-to-end test specifying the |enable_encrypted_rtp_header_extensions|
2025// option to offer encrypted versions of all header extensions alongside the
2026// unencrypted versions.
2027TEST_P(PeerConnectionIntegrationTest,
2028 EndToEndCallWithEncryptedRtpHeaderExtensions) {
2029 CryptoOptions crypto_options;
2030 crypto_options.srtp.enable_encrypted_rtp_header_extensions = true;
2031 PeerConnectionInterface::RTCConfiguration config;
2032 config.crypto_options = crypto_options;
2033 // Note: This allows offering >14 RTP header extensions.
2034 config.offer_extmap_allow_mixed = true;
2035 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2036 ConnectFakeSignaling();
2037
2038 // Do normal offer/answer and wait for some frames to be received in each
2039 // direction.
2040 caller()->AddAudioVideoTracks();
2041 callee()->AddAudioVideoTracks();
2042 caller()->CreateAndSetAndSignalOffer();
2043 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2044 MediaExpectations media_expectations;
2045 media_expectations.ExpectBidirectionalAudioAndVideo();
2046 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2047}
2048
deadbeef1dcb1642017-03-29 21:08:16 -07002049// This test sets up a call between two parties with a source resolution of
2050// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002051TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002052 Send1280By720ResolutionAndReceive16To9AspectRatio) {
2053 ASSERT_TRUE(CreatePeerConnectionWrappers());
2054 ConnectFakeSignaling();
2055
Niels Möller5c7efe72018-05-11 10:34:46 +02002056 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
2057 webrtc::FakePeriodicVideoSource::Config config;
2058 config.width = 1280;
2059 config.height = 720;
Johannes Kron965e7942018-09-13 15:36:20 +02002060 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +02002061 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
2062 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -07002063
2064 // Do normal offer/answer and wait for at least one frame to be received in
2065 // each direction.
2066 caller()->CreateAndSetAndSignalOffer();
2067 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2068 callee()->min_video_frames_received_per_track() > 0,
2069 kMaxWaitForFramesMs);
2070
2071 // Check rendered aspect ratio.
2072 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
2073 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
2074 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
2075 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
2076}
2077
2078// This test sets up an one-way call, with media only from caller to
2079// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002080TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -07002081 ASSERT_TRUE(CreatePeerConnectionWrappers());
2082 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002083 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002084 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002085 MediaExpectations media_expectations;
2086 media_expectations.CalleeExpectsSomeAudioAndVideo();
2087 media_expectations.CallerExpectsNoAudio();
2088 media_expectations.CallerExpectsNoVideo();
2089 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002090}
2091
Johannes Kron3e983682020-03-29 22:17:00 +02002092// Tests that send only works without the caller having a decoder factory and
2093// the callee having an encoder factory.
2094TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSendOnlyVideo) {
2095 ASSERT_TRUE(
2096 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
2097 ConnectFakeSignaling();
2098 // Add one-directional video, from caller to callee.
2099 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2100 caller()->CreateLocalVideoTrack();
2101 caller()->AddTrack(caller_track);
2102 PeerConnectionInterface::RTCOfferAnswerOptions options;
2103 options.offer_to_receive_video = 0;
2104 caller()->SetOfferAnswerOptions(options);
2105 caller()->CreateAndSetAndSignalOffer();
2106 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2107 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2108
2109 // Expect video to be received in one direction.
2110 MediaExpectations media_expectations;
2111 media_expectations.CallerExpectsNoVideo();
2112 media_expectations.CalleeExpectsSomeVideo();
2113
2114 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2115}
2116
2117// Tests that receive only works without the caller having an encoder factory
2118// and the callee having a decoder factory.
2119TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithReceiveOnlyVideo) {
2120 ASSERT_TRUE(
2121 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/false));
2122 ConnectFakeSignaling();
2123 // Add one-directional video, from callee to caller.
2124 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2125 callee()->CreateLocalVideoTrack();
2126 callee()->AddTrack(callee_track);
2127 PeerConnectionInterface::RTCOfferAnswerOptions options;
2128 options.offer_to_receive_video = 1;
2129 caller()->SetOfferAnswerOptions(options);
2130 caller()->CreateAndSetAndSignalOffer();
2131 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2132 ASSERT_EQ(caller()->pc()->GetReceivers().size(), 1u);
2133
2134 // Expect video to be received in one direction.
2135 MediaExpectations media_expectations;
2136 media_expectations.CallerExpectsSomeVideo();
2137 media_expectations.CalleeExpectsNoVideo();
2138
2139 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2140}
2141
2142TEST_P(PeerConnectionIntegrationTest,
2143 EndToEndCallAddReceiveVideoToSendOnlyCall) {
2144 ASSERT_TRUE(CreatePeerConnectionWrappers());
2145 ConnectFakeSignaling();
2146 // Add one-directional video, from caller to callee.
2147 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2148 caller()->CreateLocalVideoTrack();
2149 caller()->AddTrack(caller_track);
2150 caller()->CreateAndSetAndSignalOffer();
2151 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2152
2153 // Add receive video.
2154 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2155 callee()->CreateLocalVideoTrack();
2156 callee()->AddTrack(callee_track);
2157 caller()->CreateAndSetAndSignalOffer();
2158 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2159
2160 // Ensure that video frames are received end-to-end.
2161 MediaExpectations media_expectations;
2162 media_expectations.ExpectBidirectionalVideo();
2163 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2164}
2165
2166TEST_P(PeerConnectionIntegrationTest,
2167 EndToEndCallAddSendVideoToReceiveOnlyCall) {
2168 ASSERT_TRUE(CreatePeerConnectionWrappers());
2169 ConnectFakeSignaling();
2170 // Add one-directional video, from callee to caller.
2171 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2172 callee()->CreateLocalVideoTrack();
2173 callee()->AddTrack(callee_track);
2174 caller()->CreateAndSetAndSignalOffer();
2175 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2176
2177 // Add send video.
2178 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2179 caller()->CreateLocalVideoTrack();
2180 caller()->AddTrack(caller_track);
2181 caller()->CreateAndSetAndSignalOffer();
2182 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2183
2184 // Expect video to be received in one direction.
2185 MediaExpectations media_expectations;
2186 media_expectations.ExpectBidirectionalVideo();
2187 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2188}
2189
2190TEST_P(PeerConnectionIntegrationTest,
2191 EndToEndCallRemoveReceiveVideoFromSendReceiveCall) {
2192 ASSERT_TRUE(CreatePeerConnectionWrappers());
2193 ConnectFakeSignaling();
2194 // Add send video, from caller to callee.
2195 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2196 caller()->CreateLocalVideoTrack();
2197 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
2198 caller()->AddTrack(caller_track);
2199 // Add receive video, from callee to caller.
2200 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2201 callee()->CreateLocalVideoTrack();
2202
2203 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
2204 callee()->AddTrack(callee_track);
2205 caller()->CreateAndSetAndSignalOffer();
2206 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2207
2208 // Remove receive video (i.e., callee sender track).
2209 callee()->pc()->RemoveTrack(callee_sender);
2210
2211 caller()->CreateAndSetAndSignalOffer();
2212 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2213
2214 // Expect one-directional video.
2215 MediaExpectations media_expectations;
2216 media_expectations.CallerExpectsNoVideo();
2217 media_expectations.CalleeExpectsSomeVideo();
2218
2219 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2220}
2221
2222TEST_P(PeerConnectionIntegrationTest,
2223 EndToEndCallRemoveSendVideoFromSendReceiveCall) {
2224 ASSERT_TRUE(CreatePeerConnectionWrappers());
2225 ConnectFakeSignaling();
2226 // Add send video, from caller to callee.
2227 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2228 caller()->CreateLocalVideoTrack();
2229 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
2230 caller()->AddTrack(caller_track);
2231 // Add receive video, from callee to caller.
2232 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2233 callee()->CreateLocalVideoTrack();
2234
2235 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
2236 callee()->AddTrack(callee_track);
2237 caller()->CreateAndSetAndSignalOffer();
2238 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2239
2240 // Remove send video (i.e., caller sender track).
2241 caller()->pc()->RemoveTrack(caller_sender);
2242
2243 caller()->CreateAndSetAndSignalOffer();
2244 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2245
2246 // Expect one-directional video.
2247 MediaExpectations media_expectations;
2248 media_expectations.CalleeExpectsNoVideo();
2249 media_expectations.CallerExpectsSomeVideo();
2250
2251 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2252}
2253
deadbeef1dcb1642017-03-29 21:08:16 -07002254// This test sets up a audio call initially, with the callee rejecting video
2255// initially. Then later the callee decides to upgrade to audio/video, and
2256// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002257TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -07002258 ASSERT_TRUE(CreatePeerConnectionWrappers());
2259 ConnectFakeSignaling();
2260 // Initially, offer an audio/video stream from the caller, but refuse to
2261 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -08002262 caller()->AddAudioVideoTracks();
2263 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002264 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2265 PeerConnectionInterface::RTCOfferAnswerOptions options;
2266 options.offer_to_receive_video = 0;
2267 callee()->SetOfferAnswerOptions(options);
2268 } else {
2269 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002270 callee()
2271 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2272 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002273 });
2274 }
deadbeef1dcb1642017-03-29 21:08:16 -07002275 // Do offer/answer and make sure audio is still received end-to-end.
2276 caller()->CreateAndSetAndSignalOffer();
2277 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002278 {
2279 MediaExpectations media_expectations;
2280 media_expectations.ExpectBidirectionalAudio();
2281 media_expectations.ExpectNoVideo();
2282 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2283 }
deadbeef1dcb1642017-03-29 21:08:16 -07002284 // Sanity check that the callee's description has a rejected video section.
2285 ASSERT_NE(nullptr, callee()->pc()->local_description());
2286 const ContentInfo* callee_video_content =
2287 GetFirstVideoContent(callee()->pc()->local_description()->description());
2288 ASSERT_NE(nullptr, callee_video_content);
2289 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002290
deadbeef1dcb1642017-03-29 21:08:16 -07002291 // Now negotiate with video and ensure negotiation succeeds, with video
2292 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -08002293 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002294 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2295 PeerConnectionInterface::RTCOfferAnswerOptions options;
2296 options.offer_to_receive_video = 1;
2297 callee()->SetOfferAnswerOptions(options);
2298 } else {
2299 callee()->SetRemoteOfferHandler(nullptr);
2300 caller()->SetRemoteOfferHandler([this] {
2301 // The caller creates a new transceiver to receive video on when receiving
2302 // the offer, but by default it is send only.
2303 auto transceivers = caller()->pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +02002304 ASSERT_EQ(2U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002305 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
Harald Alvestrand6060df52020-08-11 09:54:02 +02002306 transceivers[1]->receiver()->media_type());
2307 transceivers[1]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
2308 transceivers[1]->SetDirectionWithError(
2309 RtpTransceiverDirection::kSendRecv);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002310 });
2311 }
deadbeef1dcb1642017-03-29 21:08:16 -07002312 callee()->CreateAndSetAndSignalOffer();
2313 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002314 {
2315 // Expect additional audio frames to be received after the upgrade.
2316 MediaExpectations media_expectations;
2317 media_expectations.ExpectBidirectionalAudioAndVideo();
2318 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2319 }
deadbeef1dcb1642017-03-29 21:08:16 -07002320}
2321
deadbeef4389b4d2017-09-07 09:07:36 -07002322// Simpler than the above test; just add an audio track to an established
2323// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002324TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -07002325 ASSERT_TRUE(CreatePeerConnectionWrappers());
2326 ConnectFakeSignaling();
2327 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -08002328 caller()->AddVideoTrack();
2329 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07002330 caller()->CreateAndSetAndSignalOffer();
2331 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2332 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08002333 caller()->AddAudioTrack();
2334 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07002335 caller()->CreateAndSetAndSignalOffer();
2336 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2337 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002338 MediaExpectations media_expectations;
2339 media_expectations.ExpectBidirectionalAudioAndVideo();
2340 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -07002341}
2342
deadbeef1dcb1642017-03-29 21:08:16 -07002343// This test sets up a call that's transferred to a new caller with a different
2344// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002345TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -07002346 ASSERT_TRUE(CreatePeerConnectionWrappers());
2347 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002348 caller()->AddAudioVideoTracks();
2349 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002350 caller()->CreateAndSetAndSignalOffer();
2351 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2352
2353 // Keep the original peer around which will still send packets to the
2354 // receiving client. These SRTP packets will be dropped.
2355 std::unique_ptr<PeerConnectionWrapper> original_peer(
2356 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002357 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07002358 // TODO(deadbeef): Why do we call Close here? That goes against the comment
2359 // directly above.
2360 original_peer->pc()->Close();
2361
2362 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002363 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002364 caller()->CreateAndSetAndSignalOffer();
2365 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2366 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002367 MediaExpectations media_expectations;
2368 media_expectations.ExpectBidirectionalAudioAndVideo();
2369 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002370}
2371
2372// This test sets up a call that's transferred to a new callee with a different
2373// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002374TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -07002375 ASSERT_TRUE(CreatePeerConnectionWrappers());
2376 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002377 caller()->AddAudioVideoTracks();
2378 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002379 caller()->CreateAndSetAndSignalOffer();
2380 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2381
2382 // Keep the original peer around which will still send packets to the
2383 // receiving client. These SRTP packets will be dropped.
2384 std::unique_ptr<PeerConnectionWrapper> original_peer(
2385 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002386 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07002387 // TODO(deadbeef): Why do we call Close here? That goes against the comment
2388 // directly above.
2389 original_peer->pc()->Close();
2390
2391 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002392 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002393 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2394 caller()->CreateAndSetAndSignalOffer();
2395 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2396 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002397 MediaExpectations media_expectations;
2398 media_expectations.ExpectBidirectionalAudioAndVideo();
2399 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002400}
2401
2402// This test sets up a non-bundled call and negotiates bundling at the same
2403// time as starting an ICE restart. When bundling is in effect in the restart,
2404// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002405TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -07002406 ASSERT_TRUE(CreatePeerConnectionWrappers());
2407 ConnectFakeSignaling();
2408
Steve Anton15324772018-01-16 10:26:49 -08002409 caller()->AddAudioVideoTracks();
2410 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002411 // Remove the bundle group from the SDP received by the callee.
2412 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2413 desc->RemoveGroupByName("BUNDLE");
2414 });
2415 caller()->CreateAndSetAndSignalOffer();
2416 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002417 {
2418 MediaExpectations media_expectations;
2419 media_expectations.ExpectBidirectionalAudioAndVideo();
2420 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2421 }
deadbeef1dcb1642017-03-29 21:08:16 -07002422 // Now stop removing the BUNDLE group, and trigger an ICE restart.
2423 callee()->SetReceivedSdpMunger(nullptr);
2424 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2425 caller()->CreateAndSetAndSignalOffer();
2426 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2427
2428 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002429 {
2430 MediaExpectations media_expectations;
2431 media_expectations.ExpectBidirectionalAudioAndVideo();
2432 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2433 }
deadbeef1dcb1642017-03-29 21:08:16 -07002434}
2435
2436// Test CVO (Coordination of Video Orientation). If a video source is rotated
2437// and both peers support the CVO RTP header extension, the actual video frames
2438// don't need to be encoded in different resolutions, since the rotation is
2439// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002440TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002441 ASSERT_TRUE(CreatePeerConnectionWrappers());
2442 ConnectFakeSignaling();
2443 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002444 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002445 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002446 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002447 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2448
2449 // Wait for video frames to be received by both sides.
2450 caller()->CreateAndSetAndSignalOffer();
2451 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2452 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2453 callee()->min_video_frames_received_per_track() > 0,
2454 kMaxWaitForFramesMs);
2455
2456 // Ensure that the aspect ratio is unmodified.
2457 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2458 // not just assumed.
2459 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
2460 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
2461 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
2462 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
2463 // Ensure that the CVO bits were surfaced to the renderer.
2464 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
2465 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
2466}
2467
2468// Test that when the CVO extension isn't supported, video is rotated the
2469// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002470TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002471 ASSERT_TRUE(CreatePeerConnectionWrappers());
2472 ConnectFakeSignaling();
2473 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002474 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002475 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002476 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002477 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2478
2479 // Remove the CVO extension from the offered SDP.
2480 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2481 cricket::VideoContentDescription* video =
2482 GetFirstVideoContentDescription(desc);
2483 video->ClearRtpHeaderExtensions();
2484 });
2485 // Wait for video frames to be received by both sides.
2486 caller()->CreateAndSetAndSignalOffer();
2487 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2488 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2489 callee()->min_video_frames_received_per_track() > 0,
2490 kMaxWaitForFramesMs);
2491
2492 // Expect that the aspect ratio is inversed to account for the 90/270 degree
2493 // rotation.
2494 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2495 // not just assumed.
2496 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
2497 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
2498 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
2499 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
2500 // Expect that each endpoint is unaware of the rotation of the other endpoint.
2501 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
2502 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
2503}
2504
deadbeef1dcb1642017-03-29 21:08:16 -07002505// Test that if the answerer rejects the audio m= section, no audio is sent or
2506// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002507TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002508 ASSERT_TRUE(CreatePeerConnectionWrappers());
2509 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002510 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002511 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2512 // Only add video track for callee, and set offer_to_receive_audio to 0, so
2513 // it will reject the audio m= section completely.
2514 PeerConnectionInterface::RTCOfferAnswerOptions options;
2515 options.offer_to_receive_audio = 0;
2516 callee()->SetOfferAnswerOptions(options);
2517 } else {
2518 // Stopping the audio RtpTransceiver will cause the media section to be
2519 // rejected in the answer.
2520 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002521 callee()
2522 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
2523 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002524 });
2525 }
Steve Anton15324772018-01-16 10:26:49 -08002526 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002527 // Do offer/answer and wait for successful end-to-end video frames.
2528 caller()->CreateAndSetAndSignalOffer();
2529 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002530 MediaExpectations media_expectations;
2531 media_expectations.ExpectBidirectionalVideo();
2532 media_expectations.ExpectNoAudio();
2533 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2534
deadbeef1dcb1642017-03-29 21:08:16 -07002535 // Sanity check that the callee's description has a rejected audio section.
2536 ASSERT_NE(nullptr, callee()->pc()->local_description());
2537 const ContentInfo* callee_audio_content =
2538 GetFirstAudioContent(callee()->pc()->local_description()->description());
2539 ASSERT_NE(nullptr, callee_audio_content);
2540 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002541 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002542 // The caller's transceiver should have stopped after receiving the answer,
2543 // and thus no longer listed in transceivers.
2544 EXPECT_EQ(nullptr,
2545 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002546 }
deadbeef1dcb1642017-03-29 21:08:16 -07002547}
2548
2549// Test that if the answerer rejects the video m= section, no video is sent or
2550// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002551TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002552 ASSERT_TRUE(CreatePeerConnectionWrappers());
2553 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002554 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002555 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2556 // Only add audio track for callee, and set offer_to_receive_video to 0, so
2557 // it will reject the video m= section completely.
2558 PeerConnectionInterface::RTCOfferAnswerOptions options;
2559 options.offer_to_receive_video = 0;
2560 callee()->SetOfferAnswerOptions(options);
2561 } else {
2562 // Stopping the video RtpTransceiver will cause the media section to be
2563 // rejected in the answer.
2564 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002565 callee()
2566 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2567 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002568 });
2569 }
Steve Anton15324772018-01-16 10:26:49 -08002570 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002571 // Do offer/answer and wait for successful end-to-end audio frames.
2572 caller()->CreateAndSetAndSignalOffer();
2573 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002574 MediaExpectations media_expectations;
2575 media_expectations.ExpectBidirectionalAudio();
2576 media_expectations.ExpectNoVideo();
2577 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2578
deadbeef1dcb1642017-03-29 21:08:16 -07002579 // Sanity check that the callee's description has a rejected video section.
2580 ASSERT_NE(nullptr, callee()->pc()->local_description());
2581 const ContentInfo* callee_video_content =
2582 GetFirstVideoContent(callee()->pc()->local_description()->description());
2583 ASSERT_NE(nullptr, callee_video_content);
2584 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002585 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002586 // The caller's transceiver should have stopped after receiving the answer,
2587 // and thus is no longer present.
2588 EXPECT_EQ(nullptr,
2589 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002590 }
deadbeef1dcb1642017-03-29 21:08:16 -07002591}
2592
2593// Test that if the answerer rejects both audio and video m= sections, nothing
2594// bad happens.
2595// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
2596// test anything but the fact that negotiation succeeds, which doesn't mean
2597// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002598TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -07002599 ASSERT_TRUE(CreatePeerConnectionWrappers());
2600 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002601 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002602 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2603 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
2604 // will reject both audio and video m= sections.
2605 PeerConnectionInterface::RTCOfferAnswerOptions options;
2606 options.offer_to_receive_audio = 0;
2607 options.offer_to_receive_video = 0;
2608 callee()->SetOfferAnswerOptions(options);
2609 } else {
2610 callee()->SetRemoteOfferHandler([this] {
2611 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +01002612 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002613 transceiver->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002614 }
2615 });
2616 }
deadbeef1dcb1642017-03-29 21:08:16 -07002617 // Do offer/answer and wait for stable signaling state.
2618 caller()->CreateAndSetAndSignalOffer();
2619 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002620
deadbeef1dcb1642017-03-29 21:08:16 -07002621 // Sanity check that the callee's description has rejected m= sections.
2622 ASSERT_NE(nullptr, callee()->pc()->local_description());
2623 const ContentInfo* callee_audio_content =
2624 GetFirstAudioContent(callee()->pc()->local_description()->description());
2625 ASSERT_NE(nullptr, callee_audio_content);
2626 EXPECT_TRUE(callee_audio_content->rejected);
2627 const ContentInfo* callee_video_content =
2628 GetFirstVideoContent(callee()->pc()->local_description()->description());
2629 ASSERT_NE(nullptr, callee_video_content);
2630 EXPECT_TRUE(callee_video_content->rejected);
2631}
2632
2633// This test sets up an audio and video call between two parties. After the
2634// call runs for a while, the caller sends an updated offer with video being
2635// rejected. Once the re-negotiation is done, the video flow should stop and
2636// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002637TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07002638 ASSERT_TRUE(CreatePeerConnectionWrappers());
2639 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002640 caller()->AddAudioVideoTracks();
2641 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002642 caller()->CreateAndSetAndSignalOffer();
2643 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002644 {
2645 MediaExpectations media_expectations;
2646 media_expectations.ExpectBidirectionalAudioAndVideo();
2647 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2648 }
deadbeef1dcb1642017-03-29 21:08:16 -07002649 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002650 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2651 caller()->SetGeneratedSdpMunger(
2652 [](cricket::SessionDescription* description) {
2653 for (cricket::ContentInfo& content : description->contents()) {
2654 if (cricket::IsVideoContent(&content)) {
2655 content.rejected = true;
2656 }
2657 }
2658 });
2659 } else {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002660 caller()
2661 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2662 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002663 }
deadbeef1dcb1642017-03-29 21:08:16 -07002664 caller()->CreateAndSetAndSignalOffer();
2665 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2666
2667 // Sanity check that the caller's description has a rejected video section.
2668 ASSERT_NE(nullptr, caller()->pc()->local_description());
2669 const ContentInfo* caller_video_content =
2670 GetFirstVideoContent(caller()->pc()->local_description()->description());
2671 ASSERT_NE(nullptr, caller_video_content);
2672 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -07002673 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002674 {
2675 MediaExpectations media_expectations;
2676 media_expectations.ExpectBidirectionalAudio();
2677 media_expectations.ExpectNoVideo();
2678 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2679 }
deadbeef1dcb1642017-03-29 21:08:16 -07002680}
2681
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -07002682// Do one offer/answer with audio, another that disables it (rejecting the m=
2683// section), and another that re-enables it. Regression test for:
2684// bugs.webrtc.org/6023
2685TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
2686 ASSERT_TRUE(CreatePeerConnectionWrappers());
2687 ConnectFakeSignaling();
2688
2689 // Add audio track, do normal offer/answer.
2690 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2691 caller()->CreateLocalAudioTrack();
2692 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2693 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2694 caller()->CreateAndSetAndSignalOffer();
2695 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2696
2697 // Remove audio track, and set offer_to_receive_audio to false to cause the
2698 // m= section to be completely disabled, not just "recvonly".
2699 caller()->pc()->RemoveTrack(sender);
2700 PeerConnectionInterface::RTCOfferAnswerOptions options;
2701 options.offer_to_receive_audio = 0;
2702 caller()->SetOfferAnswerOptions(options);
2703 caller()->CreateAndSetAndSignalOffer();
2704 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2705
2706 // Add the audio track again, expecting negotiation to succeed and frames to
2707 // flow.
2708 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2709 options.offer_to_receive_audio = 1;
2710 caller()->SetOfferAnswerOptions(options);
2711 caller()->CreateAndSetAndSignalOffer();
2712 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2713
2714 MediaExpectations media_expectations;
2715 media_expectations.CalleeExpectsSomeAudio();
2716 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2717}
2718
deadbeef1dcb1642017-03-29 21:08:16 -07002719// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
2720// is needed to support legacy endpoints.
2721// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
2722// add a test for an end-to-end test without MID signaling either (basically,
2723// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002724TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -07002725 ASSERT_TRUE(CreatePeerConnectionWrappers());
2726 ConnectFakeSignaling();
2727 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08002728 caller()->AddAudioVideoTracks();
2729 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07002730 // Remove SSRCs and MSIDs from the received offer SDP.
2731 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07002732 caller()->CreateAndSetAndSignalOffer();
2733 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002734 MediaExpectations media_expectations;
2735 media_expectations.ExpectBidirectionalAudioAndVideo();
2736 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002737}
2738
Seth Hampson5897a6e2018-04-03 11:16:33 -07002739// Basic end-to-end test, without SSRC signaling. This means that the track
2740// was created properly and frames are delivered when the MSIDs are communicated
2741// with a=msid lines and no a=ssrc lines.
2742TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2743 EndToEndCallWithoutSsrcSignaling) {
2744 const char kStreamId[] = "streamId";
2745 ASSERT_TRUE(CreatePeerConnectionWrappers());
2746 ConnectFakeSignaling();
2747 // Add just audio tracks.
2748 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
2749 callee()->AddAudioTrack();
2750
2751 // Remove SSRCs from the received offer SDP.
2752 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
2753 caller()->CreateAndSetAndSignalOffer();
2754 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2755 MediaExpectations media_expectations;
2756 media_expectations.ExpectBidirectionalAudio();
2757 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2758}
2759
Johannes Kron3e983682020-03-29 22:17:00 +02002760TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2761 EndToEndCallAddReceiveVideoToSendOnlyCall) {
2762 ASSERT_TRUE(CreatePeerConnectionWrappers());
2763 ConnectFakeSignaling();
2764 // Add one-directional video, from caller to callee.
2765 rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
2766 caller()->CreateLocalVideoTrack();
2767
2768 RtpTransceiverInit video_transceiver_init;
2769 video_transceiver_init.stream_ids = {"video1"};
2770 video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly;
2771 auto video_sender =
2772 caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue();
2773 caller()->CreateAndSetAndSignalOffer();
2774 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2775
2776 // Add receive direction.
Harald Alvestrand6060df52020-08-11 09:54:02 +02002777 video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);
Johannes Kron3e983682020-03-29 22:17:00 +02002778
2779 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2780 callee()->CreateLocalVideoTrack();
2781
2782 callee()->AddTrack(callee_track);
2783 caller()->CreateAndSetAndSignalOffer();
2784 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2785 // Ensure that video frames are received end-to-end.
2786 MediaExpectations media_expectations;
2787 media_expectations.ExpectBidirectionalVideo();
2788 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2789}
2790
Steve Antondf527fd2018-04-27 15:52:03 -07002791// Tests that video flows between multiple video tracks when SSRCs are not
2792// signaled. This exercises the MID RTP header extension which is needed to
2793// demux the incoming video tracks.
2794TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2795 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
2796 ASSERT_TRUE(CreatePeerConnectionWrappers());
2797 ConnectFakeSignaling();
2798 caller()->AddVideoTrack();
2799 caller()->AddVideoTrack();
2800 callee()->AddVideoTrack();
2801 callee()->AddVideoTrack();
2802
2803 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2804 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2805 caller()->CreateAndSetAndSignalOffer();
2806 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2807 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2808 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2809
2810 // Expect video to be received in both directions on both tracks.
2811 MediaExpectations media_expectations;
2812 media_expectations.ExpectBidirectionalVideo();
2813 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2814}
2815
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -07002816// Used for the test below.
2817void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
2818 RemoveSsrcsAndKeepMsids(desc);
2819 desc->RemoveGroupByName("BUNDLE");
2820 for (ContentInfo& content : desc->contents()) {
2821 cricket::MediaContentDescription* media = content.media_description();
2822 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
2823 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
2824 [](const RtpExtension& extension) {
2825 return extension.uri ==
2826 RtpExtension::kMidUri;
2827 }),
2828 extensions.end());
2829 media->set_rtp_header_extensions(extensions);
2830 }
2831}
2832
2833// Tests that video flows between multiple video tracks when BUNDLE is not used,
2834// SSRCs are not signaled and the MID RTP header extension is not used. This
2835// relies on demuxing by payload type, which normally doesn't work if you have
2836// multiple media sections using the same payload type, but which should work as
2837// long as the media sections aren't bundled.
2838// Regression test for: http://crbug.com/webrtc/12023
2839TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2840 EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid) {
2841 ASSERT_TRUE(CreatePeerConnectionWrappers());
2842 ConnectFakeSignaling();
2843 caller()->AddVideoTrack();
2844 caller()->AddVideoTrack();
2845 callee()->AddVideoTrack();
2846 callee()->AddVideoTrack();
2847 caller()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
2848 callee()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
2849 caller()->CreateAndSetAndSignalOffer();
2850 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2851 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2852 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2853 // Make sure we are not bundled.
2854 ASSERT_NE(caller()->pc()->GetSenders()[0]->dtls_transport(),
2855 caller()->pc()->GetSenders()[1]->dtls_transport());
2856
2857 // Expect video to be received in both directions on both tracks.
2858 MediaExpectations media_expectations;
2859 media_expectations.ExpectBidirectionalVideo();
2860 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2861}
2862
2863// Used for the test below.
2864void ModifyPayloadTypesAndRemoveMidExtension(
2865 cricket::SessionDescription* desc) {
2866 int pt = 96;
2867 for (ContentInfo& content : desc->contents()) {
2868 cricket::MediaContentDescription* media = content.media_description();
2869 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
2870 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
2871 [](const RtpExtension& extension) {
2872 return extension.uri ==
2873 RtpExtension::kMidUri;
2874 }),
2875 extensions.end());
2876 media->set_rtp_header_extensions(extensions);
2877 cricket::VideoContentDescription* video = media->as_video();
2878 ASSERT_TRUE(video != nullptr);
2879 std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
2880 video->set_codecs(codecs);
2881 }
2882}
2883
2884// Tests that two video tracks can be demultiplexed by payload type alone, by
2885// using different payload types for the same codec in different m= sections.
2886// This practice is discouraged but historically has been supported.
2887// Regression test for: http://crbug.com/webrtc/12029
2888TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2889 EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType) {
2890 ASSERT_TRUE(CreatePeerConnectionWrappers());
2891 ConnectFakeSignaling();
2892 caller()->AddVideoTrack();
2893 caller()->AddVideoTrack();
2894 callee()->AddVideoTrack();
2895 callee()->AddVideoTrack();
2896 caller()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
2897 callee()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
2898 // We can't remove SSRCs from the generated SDP because then no send streams
2899 // would be created.
2900 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2901 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2902 caller()->CreateAndSetAndSignalOffer();
2903 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2904 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2905 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2906 // Make sure we are bundled.
2907 ASSERT_EQ(caller()->pc()->GetSenders()[0]->dtls_transport(),
2908 caller()->pc()->GetSenders()[1]->dtls_transport());
2909
2910 // Expect video to be received in both directions on both tracks.
2911 MediaExpectations media_expectations;
2912 media_expectations.ExpectBidirectionalVideo();
2913 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2914}
2915
Henrik Boström5b147782018-12-04 11:25:05 +01002916TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
2917 ASSERT_TRUE(CreatePeerConnectionWrappers());
2918 ConnectFakeSignaling();
2919 caller()->AddAudioTrack();
2920 caller()->AddVideoTrack();
2921 caller()->CreateAndSetAndSignalOffer();
2922 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2923 auto callee_receivers = callee()->pc()->GetReceivers();
2924 ASSERT_EQ(2u, callee_receivers.size());
2925 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
2926 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
2927}
2928
2929TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
2930 ASSERT_TRUE(CreatePeerConnectionWrappers());
2931 ConnectFakeSignaling();
2932 caller()->AddAudioTrack();
2933 caller()->AddVideoTrack();
2934 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2935 caller()->CreateAndSetAndSignalOffer();
2936 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2937 auto callee_receivers = callee()->pc()->GetReceivers();
2938 ASSERT_EQ(2u, callee_receivers.size());
2939 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
2940 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
2941 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
2942 callee_receivers[1]->stream_ids()[0]);
2943 EXPECT_EQ(callee_receivers[0]->streams()[0],
2944 callee_receivers[1]->streams()[0]);
2945}
2946
deadbeef1dcb1642017-03-29 21:08:16 -07002947// Test that if two video tracks are sent (from caller to callee, in this test),
2948// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002949TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07002950 ASSERT_TRUE(CreatePeerConnectionWrappers());
2951 ConnectFakeSignaling();
2952 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08002953 caller()->AddAudioVideoTracks();
2954 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002955 caller()->CreateAndSetAndSignalOffer();
2956 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08002957 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002958
2959 MediaExpectations media_expectations;
2960 media_expectations.CalleeExpectsSomeAudioAndVideo();
2961 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002962}
2963
2964static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
2965 bool first = true;
2966 for (cricket::ContentInfo& content : desc->contents()) {
2967 if (first) {
2968 first = false;
2969 continue;
2970 }
2971 content.bundle_only = true;
2972 }
2973 first = true;
2974 for (cricket::TransportInfo& transport : desc->transport_infos()) {
2975 if (first) {
2976 first = false;
2977 continue;
2978 }
2979 transport.description.ice_ufrag.clear();
2980 transport.description.ice_pwd.clear();
2981 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
2982 transport.description.identity_fingerprint.reset(nullptr);
2983 }
2984}
2985
2986// Test that if applying a true "max bundle" offer, which uses ports of 0,
2987// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
2988// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
2989// successfully and media flows.
2990// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
2991// TODO(deadbeef): Won't need this test once we start generating actual
2992// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002993TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002994 EndToEndCallWithSpecCompliantMaxBundleOffer) {
2995 ASSERT_TRUE(CreatePeerConnectionWrappers());
2996 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002997 caller()->AddAudioVideoTracks();
2998 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002999 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
3000 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
3001 // but the first m= section.
3002 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
3003 caller()->CreateAndSetAndSignalOffer();
3004 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003005 MediaExpectations media_expectations;
3006 media_expectations.ExpectBidirectionalAudioAndVideo();
3007 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003008}
3009
3010// Test that we can receive the audio output level from a remote audio track.
3011// TODO(deadbeef): Use a fake audio source and verify that the output level is
3012// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003013TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07003014 ASSERT_TRUE(CreatePeerConnectionWrappers());
3015 ConnectFakeSignaling();
3016 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08003017 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07003018 caller()->CreateAndSetAndSignalOffer();
3019 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3020
3021 // Get the audio output level stats. Note that the level is not available
3022 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07003023 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07003024 kMaxWaitForFramesMs);
3025}
3026
3027// Test that an audio input level is reported.
3028// TODO(deadbeef): Use a fake audio source and verify that the input level is
3029// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003030TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07003031 ASSERT_TRUE(CreatePeerConnectionWrappers());
3032 ConnectFakeSignaling();
3033 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08003034 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07003035 caller()->CreateAndSetAndSignalOffer();
3036 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3037
3038 // Get the audio input level stats. The level should be available very
3039 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07003040 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07003041 kMaxWaitForStatsMs);
3042}
3043
3044// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003045TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07003046 ASSERT_TRUE(CreatePeerConnectionWrappers());
3047 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003048 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003049 // Do offer/answer, wait for the callee to receive some frames.
3050 caller()->CreateAndSetAndSignalOffer();
3051 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003052
3053 MediaExpectations media_expectations;
3054 media_expectations.CalleeExpectsSomeAudioAndVideo();
3055 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003056
3057 // Get a handle to the remote tracks created, so they can be used as GetStats
3058 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01003059 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08003060 // We received frames, so we definitely should have nonzero "received bytes"
3061 // stats at this point.
3062 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
3063 0);
3064 }
deadbeef1dcb1642017-03-29 21:08:16 -07003065}
3066
3067// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003068TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07003069 ASSERT_TRUE(CreatePeerConnectionWrappers());
3070 ConnectFakeSignaling();
3071 auto audio_track = caller()->CreateLocalAudioTrack();
3072 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08003073 caller()->AddTrack(audio_track);
3074 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07003075 // Do offer/answer, wait for the callee to receive some frames.
3076 caller()->CreateAndSetAndSignalOffer();
3077 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003078 MediaExpectations media_expectations;
3079 media_expectations.CalleeExpectsSomeAudioAndVideo();
3080 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003081
3082 // The callee received frames, so we definitely should have nonzero "sent
3083 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07003084 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
3085 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
3086}
3087
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003088// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003089TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003090 ASSERT_TRUE(CreatePeerConnectionWrappers());
3091 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003092 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003093
Steve Anton15324772018-01-16 10:26:49 -08003094 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003095
3096 // Do offer/answer, wait for the callee to receive some frames.
3097 caller()->CreateAndSetAndSignalOffer();
3098 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3099
3100 // Get the remote audio track created on the receiver, so they can be used as
3101 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08003102 auto receivers = callee()->pc()->GetReceivers();
3103 ASSERT_EQ(1u, receivers.size());
3104 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003105
3106 // Get the audio output level stats. Note that the level is not available
3107 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07003108 EXPECT_TRUE_WAIT(
3109 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
3110 0,
3111 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003112}
3113
Steve Antona41959e2018-11-28 11:15:33 -08003114// Test that the track ID is associated with all local and remote SSRC stats
3115// using the old GetStats() and more than 1 audio and more than 1 video track.
3116// This is a regression test for crbug.com/906988
3117TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3118 OldGetStatsAssociatesTrackIdForManyMediaSections) {
3119 ASSERT_TRUE(CreatePeerConnectionWrappers());
3120 ConnectFakeSignaling();
3121 auto audio_sender_1 = caller()->AddAudioTrack();
3122 auto video_sender_1 = caller()->AddVideoTrack();
3123 auto audio_sender_2 = caller()->AddAudioTrack();
3124 auto video_sender_2 = caller()->AddVideoTrack();
3125 caller()->CreateAndSetAndSignalOffer();
3126 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3127
3128 MediaExpectations media_expectations;
3129 media_expectations.CalleeExpectsSomeAudioAndVideo();
3130 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
3131
3132 std::vector<std::string> track_ids = {
3133 audio_sender_1->track()->id(), video_sender_1->track()->id(),
3134 audio_sender_2->track()->id(), video_sender_2->track()->id()};
3135
3136 auto caller_stats = caller()->OldGetStats();
3137 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
3138 auto callee_stats = callee()->OldGetStats();
3139 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
3140}
3141
Steve Antonffa6ce42018-11-30 09:26:08 -08003142// Test that the new GetStats() returns stats for all outgoing/incoming streams
3143// with the correct track IDs if there are more than one audio and more than one
3144// video senders/receivers.
3145TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
3146 ASSERT_TRUE(CreatePeerConnectionWrappers());
3147 ConnectFakeSignaling();
3148 auto audio_sender_1 = caller()->AddAudioTrack();
3149 auto video_sender_1 = caller()->AddVideoTrack();
3150 auto audio_sender_2 = caller()->AddAudioTrack();
3151 auto video_sender_2 = caller()->AddVideoTrack();
3152 caller()->CreateAndSetAndSignalOffer();
3153 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3154
3155 MediaExpectations media_expectations;
3156 media_expectations.CalleeExpectsSomeAudioAndVideo();
3157 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
3158
3159 std::vector<std::string> track_ids = {
3160 audio_sender_1->track()->id(), video_sender_1->track()->id(),
3161 audio_sender_2->track()->id(), video_sender_2->track()->id()};
3162
3163 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
3164 caller()->NewGetStats();
3165 ASSERT_TRUE(caller_report);
3166 auto outbound_stream_stats =
3167 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
Henrik Boströma0ff50c2020-05-05 15:54:46 +02003168 ASSERT_EQ(outbound_stream_stats.size(), 4u);
Steve Antonffa6ce42018-11-30 09:26:08 -08003169 std::vector<std::string> outbound_track_ids;
3170 for (const auto& stat : outbound_stream_stats) {
3171 ASSERT_TRUE(stat->bytes_sent.is_defined());
3172 EXPECT_LT(0u, *stat->bytes_sent);
Rasmus Brandt2efae772019-06-27 14:29:34 +02003173 if (*stat->kind == "video") {
3174 ASSERT_TRUE(stat->key_frames_encoded.is_defined());
3175 EXPECT_GT(*stat->key_frames_encoded, 0u);
3176 ASSERT_TRUE(stat->frames_encoded.is_defined());
3177 EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
3178 }
Steve Antonffa6ce42018-11-30 09:26:08 -08003179 ASSERT_TRUE(stat->track_id.is_defined());
3180 const auto* track_stat =
3181 caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
3182 ASSERT_TRUE(track_stat);
3183 outbound_track_ids.push_back(*track_stat->track_identifier);
3184 }
3185 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
3186
3187 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
3188 callee()->NewGetStats();
3189 ASSERT_TRUE(callee_report);
3190 auto inbound_stream_stats =
3191 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
3192 ASSERT_EQ(4u, inbound_stream_stats.size());
3193 std::vector<std::string> inbound_track_ids;
3194 for (const auto& stat : inbound_stream_stats) {
3195 ASSERT_TRUE(stat->bytes_received.is_defined());
3196 EXPECT_LT(0u, *stat->bytes_received);
Rasmus Brandt2efae772019-06-27 14:29:34 +02003197 if (*stat->kind == "video") {
3198 ASSERT_TRUE(stat->key_frames_decoded.is_defined());
3199 EXPECT_GT(*stat->key_frames_decoded, 0u);
3200 ASSERT_TRUE(stat->frames_decoded.is_defined());
3201 EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
3202 }
Steve Antonffa6ce42018-11-30 09:26:08 -08003203 ASSERT_TRUE(stat->track_id.is_defined());
3204 const auto* track_stat =
3205 callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
3206 ASSERT_TRUE(track_stat);
3207 inbound_track_ids.push_back(*track_stat->track_identifier);
3208 }
3209 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
3210}
3211
3212// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07003213// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
3214// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003215TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07003216 GetStatsForUnsignaledStreamWithNewStatsApi) {
3217 ASSERT_TRUE(CreatePeerConnectionWrappers());
3218 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003219 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07003220 // Remove SSRCs and MSIDs from the received offer SDP.
3221 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3222 caller()->CreateAndSetAndSignalOffer();
3223 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003224 MediaExpectations media_expectations;
3225 media_expectations.CalleeExpectsSomeAudio(1);
3226 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07003227
3228 // We received a frame, so we should have nonzero "bytes received" stats for
3229 // the unsignaled stream, if stats are working for it.
3230 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
3231 callee()->NewGetStats();
3232 ASSERT_NE(nullptr, report);
3233 auto inbound_stream_stats =
3234 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
3235 ASSERT_EQ(1U, inbound_stream_stats.size());
3236 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
3237 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07003238 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
3239}
3240
Taylor Brandstettera4653442018-06-19 09:44:26 -07003241// Same as above but for the legacy stats implementation.
3242TEST_P(PeerConnectionIntegrationTest,
3243 GetStatsForUnsignaledStreamWithOldStatsApi) {
3244 ASSERT_TRUE(CreatePeerConnectionWrappers());
3245 ConnectFakeSignaling();
3246 caller()->AddAudioTrack();
3247 // Remove SSRCs and MSIDs from the received offer SDP.
3248 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3249 caller()->CreateAndSetAndSignalOffer();
3250 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3251
3252 // Note that, since the old stats implementation associates SSRCs with tracks
3253 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
3254 // associated track ID. So we can't use the track "selector" argument.
3255 //
3256 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
3257 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003258 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07003259 kDefaultTimeout);
3260}
3261
zhihuangf8164932017-05-19 13:09:47 -07003262// Test that we can successfully get the media related stats (audio level
3263// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003264TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07003265 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
3266 ASSERT_TRUE(CreatePeerConnectionWrappers());
3267 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003268 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07003269 // Remove SSRCs and MSIDs from the received offer SDP.
3270 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3271 caller()->CreateAndSetAndSignalOffer();
3272 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003273 MediaExpectations media_expectations;
3274 media_expectations.CalleeExpectsSomeAudio(1);
3275 media_expectations.CalleeExpectsSomeVideo(1);
3276 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07003277
3278 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
3279 callee()->NewGetStats();
3280 ASSERT_NE(nullptr, report);
3281
3282 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3283 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
3284 ASSERT_GE(audio_index, 0);
3285 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07003286}
3287
deadbeef4e2deab2017-09-20 13:56:21 -07003288// Helper for test below.
3289void ModifySsrcs(cricket::SessionDescription* desc) {
3290 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07003291 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08003292 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07003293 for (uint32_t& ssrc : stream.ssrcs) {
3294 ssrc = rtc::CreateRandomId();
3295 }
3296 }
3297 }
3298}
3299
3300// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
3301// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
3302// This should result in two "RTCInboundRTPStreamStats", but only one
3303// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
3304// being reset to 0 once the SSRC change occurs.
3305//
3306// Regression test for this bug:
3307// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
3308//
3309// The bug causes the track stats to only represent one of the two streams:
3310// whichever one has the higher SSRC. So with this bug, there was a 50% chance
3311// that the track stat counters would reset to 0 when the new stream is
3312// received, and a 50% chance that they'll stop updating (while
3313// "concealed_samples" continues increasing, due to silence being generated for
3314// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003315TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08003316 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07003317 ASSERT_TRUE(CreatePeerConnectionWrappers());
3318 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003319 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07003320 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
3321 // that doesn't signal SSRCs (from the callee's perspective).
3322 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3323 caller()->CreateAndSetAndSignalOffer();
3324 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3325 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003326 {
3327 MediaExpectations media_expectations;
3328 media_expectations.CalleeExpectsSomeAudio(50);
3329 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3330 }
deadbeef4e2deab2017-09-20 13:56:21 -07003331 // Some audio frames were received, so we should have nonzero "samples
3332 // received" for the track.
3333 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
3334 callee()->NewGetStats();
3335 ASSERT_NE(nullptr, report);
3336 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3337 ASSERT_EQ(1U, track_stats.size());
3338 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
3339 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
3340 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
3341
3342 // Create a new offer and munge it to cause the caller to use a new SSRC.
3343 caller()->SetGeneratedSdpMunger(ModifySsrcs);
3344 caller()->CreateAndSetAndSignalOffer();
3345 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3346 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
3347 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003348 {
3349 MediaExpectations media_expectations;
3350 media_expectations.CalleeExpectsSomeAudio(25);
3351 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3352 }
deadbeef4e2deab2017-09-20 13:56:21 -07003353
3354 report = callee()->NewGetStats();
3355 ASSERT_NE(nullptr, report);
3356 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3357 ASSERT_EQ(1U, track_stats.size());
3358 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
3359 // The "total samples received" stat should only be greater than it was
3360 // before.
3361 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
3362 // Right now, the new SSRC will cause the counters to reset to 0.
3363 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
3364
3365 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08003366 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07003367 // good sign that we're seeing stats from the old stream that's no longer
3368 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08003369 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07003370 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
3371 EXPECT_LT(*track_stats[0]->concealed_samples,
3372 *track_stats[0]->total_samples_received *
3373 kAcceptableConcealedSamplesPercentage);
3374
3375 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
3376 // sanity check that the SSRC really changed.
3377 // TODO(deadbeef): This isn't working right now, because we're not returning
3378 // *any* stats for the inactive stream. Uncomment when the bug is completely
3379 // fixed.
3380 // auto inbound_stream_stats =
3381 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
3382 // ASSERT_EQ(2U, inbound_stream_stats.size());
3383}
3384
deadbeef1dcb1642017-03-29 21:08:16 -07003385// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003386TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07003387 PeerConnectionFactory::Options dtls_10_options;
3388 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3389 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
3390 dtls_10_options));
3391 ConnectFakeSignaling();
3392 // Do normal offer/answer and wait for some frames to be received in each
3393 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003394 caller()->AddAudioVideoTracks();
3395 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003396 caller()->CreateAndSetAndSignalOffer();
3397 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003398 MediaExpectations media_expectations;
3399 media_expectations.ExpectBidirectionalAudioAndVideo();
3400 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003401}
3402
3403// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003404TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07003405 PeerConnectionFactory::Options dtls_10_options;
3406 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3407 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
3408 dtls_10_options));
3409 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003410 caller()->AddAudioVideoTracks();
3411 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003412 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003413 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07003414 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07003415 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07003416 kDefaultTimeout);
3417 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07003418 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003419 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01003420 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
3421 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
3422 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07003423}
3424
3425// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003426TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07003427 PeerConnectionFactory::Options dtls_12_options;
3428 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3429 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
3430 dtls_12_options));
3431 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003432 caller()->AddAudioVideoTracks();
3433 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003434 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003435 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07003436 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07003437 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07003438 kDefaultTimeout);
3439 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07003440 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003441 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01003442 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
3443 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
3444 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07003445}
3446
3447// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
3448// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003449TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07003450 PeerConnectionFactory::Options caller_options;
3451 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3452 PeerConnectionFactory::Options callee_options;
3453 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3454 ASSERT_TRUE(
3455 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
3456 ConnectFakeSignaling();
3457 // Do normal offer/answer and wait for some frames to be received in each
3458 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003459 caller()->AddAudioVideoTracks();
3460 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003461 caller()->CreateAndSetAndSignalOffer();
3462 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003463 MediaExpectations media_expectations;
3464 media_expectations.ExpectBidirectionalAudioAndVideo();
3465 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003466}
3467
3468// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
3469// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003470TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07003471 PeerConnectionFactory::Options caller_options;
3472 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3473 PeerConnectionFactory::Options callee_options;
3474 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3475 ASSERT_TRUE(
3476 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
3477 ConnectFakeSignaling();
3478 // Do normal offer/answer and wait for some frames to be received in each
3479 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003480 caller()->AddAudioVideoTracks();
3481 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003482 caller()->CreateAndSetAndSignalOffer();
3483 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003484 MediaExpectations media_expectations;
3485 media_expectations.ExpectBidirectionalAudioAndVideo();
3486 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003487}
3488
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003489// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
3490// works as expected; the cipher should only be used if enabled by both sides.
3491TEST_P(PeerConnectionIntegrationTest,
3492 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
3493 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003494 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003495 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003496 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
3497 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003498 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
3499 TestNegotiatedCipherSuite(caller_options, callee_options,
3500 expected_cipher_suite);
3501}
3502
3503TEST_P(PeerConnectionIntegrationTest,
3504 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
3505 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003506 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
3507 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003508 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003509 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003510 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
3511 TestNegotiatedCipherSuite(caller_options, callee_options,
3512 expected_cipher_suite);
3513}
3514
3515TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
3516 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003517 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003518 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003519 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003520 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
3521 TestNegotiatedCipherSuite(caller_options, callee_options,
3522 expected_cipher_suite);
3523}
3524
deadbeef1dcb1642017-03-29 21:08:16 -07003525// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003526TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07003527 bool local_gcm_enabled = false;
3528 bool remote_gcm_enabled = false;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003529 bool aes_ctr_enabled = true;
deadbeef1dcb1642017-03-29 21:08:16 -07003530 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
3531 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003532 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07003533}
3534
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003535// Test that a GCM cipher is used if both ends support it and non-GCM is
3536// disabled.
3537TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07003538 bool local_gcm_enabled = true;
3539 bool remote_gcm_enabled = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003540 bool aes_ctr_enabled = false;
deadbeef1dcb1642017-03-29 21:08:16 -07003541 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
3542 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003543 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07003544}
3545
deadbeef7914b8c2017-04-21 03:23:33 -07003546// Verify that media can be transmitted end-to-end when GCM crypto suites are
3547// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
3548// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
3549// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003550TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07003551 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003552 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003553 gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false;
deadbeef7914b8c2017-04-21 03:23:33 -07003554 ASSERT_TRUE(
3555 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
3556 ConnectFakeSignaling();
3557 // Do normal offer/answer and wait for some frames to be received in each
3558 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003559 caller()->AddAudioVideoTracks();
3560 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003561 caller()->CreateAndSetAndSignalOffer();
3562 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003563 MediaExpectations media_expectations;
3564 media_expectations.ExpectBidirectionalAudioAndVideo();
3565 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003566}
3567
deadbeef1dcb1642017-03-29 21:08:16 -07003568// This test sets up a call between two parties with audio, video and an RTP
3569// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003570TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003571 PeerConnectionInterface::RTCConfiguration rtc_config;
3572 rtc_config.enable_rtp_data_channel = true;
3573 rtc_config.enable_dtls_srtp = false;
3574 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003575 ConnectFakeSignaling();
3576 // Expect that data channel created on caller side will show up for callee as
3577 // well.
3578 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003579 caller()->AddAudioVideoTracks();
3580 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003581 caller()->CreateAndSetAndSignalOffer();
3582 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3583 // Ensure the existence of the RTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003584 MediaExpectations media_expectations;
3585 media_expectations.ExpectBidirectionalAudioAndVideo();
3586 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003587 ASSERT_NE(nullptr, caller()->data_channel());
3588 ASSERT_NE(nullptr, callee()->data_channel());
3589 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3590 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3591
3592 // Ensure data can be sent in both directions.
3593 std::string data = "hello world";
3594 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3595 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3596 kDefaultTimeout);
3597 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3598 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3599 kDefaultTimeout);
3600}
3601
Eldar Rellod9ebe012020-03-18 20:41:45 +02003602TEST_P(PeerConnectionIntegrationTest, RtpDataChannelWorksAfterRollback) {
3603 PeerConnectionInterface::RTCConfiguration rtc_config;
3604 rtc_config.enable_rtp_data_channel = true;
3605 rtc_config.enable_dtls_srtp = false;
3606 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
3607 ConnectFakeSignaling();
3608 auto data_channel = caller()->pc()->CreateDataChannel("label_1", nullptr);
3609 ASSERT_TRUE(data_channel.get() != nullptr);
3610 caller()->CreateAndSetAndSignalOffer();
3611 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3612
3613 caller()->CreateDataChannel("label_2", nullptr);
3614 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
3615 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
3616 caller()->pc()->SetLocalDescription(observer,
3617 caller()->CreateOfferAndWait().release());
3618 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3619 caller()->Rollback();
3620
3621 std::string data = "hello world";
3622 SendRtpDataWithRetries(data_channel, data, 5);
3623 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3624 kDefaultTimeout);
3625}
3626
deadbeef1dcb1642017-03-29 21:08:16 -07003627// Ensure that an RTP data channel is signaled as closed for the caller when
3628// the callee rejects it in a subsequent offer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003629TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003630 RtpDataChannelSignaledClosedInCalleeOffer) {
3631 // Same procedure as above test.
Niels Möllerf06f9232018-08-07 12:32:18 +02003632 PeerConnectionInterface::RTCConfiguration rtc_config;
3633 rtc_config.enable_rtp_data_channel = true;
3634 rtc_config.enable_dtls_srtp = false;
3635 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003636 ConnectFakeSignaling();
3637 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003638 caller()->AddAudioVideoTracks();
3639 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003640 caller()->CreateAndSetAndSignalOffer();
3641 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3642 ASSERT_NE(nullptr, caller()->data_channel());
3643 ASSERT_NE(nullptr, callee()->data_channel());
3644 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3645 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3646
3647 // Close the data channel on the callee, and do an updated offer/answer.
3648 callee()->data_channel()->Close();
3649 callee()->CreateAndSetAndSignalOffer();
3650 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3651 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3652 EXPECT_FALSE(callee()->data_observer()->IsOpen());
3653}
3654
3655// Tests that data is buffered in an RTP data channel until an observer is
3656// registered for it.
3657//
3658// NOTE: RTP data channels can receive data before the underlying
3659// transport has detected that a channel is writable and thus data can be
3660// received before the data channel state changes to open. That is hard to test
3661// but the same buffering is expected to be used in that case.
Yves Gerey100fe632020-01-17 19:15:53 +01003662//
3663// Use fake clock and simulated network delay so that we predictably can wait
3664// until an SCTP message has been delivered without "sleep()"ing.
3665TEST_P(PeerConnectionIntegrationTestWithFakeClock,
deadbeef1dcb1642017-03-29 21:08:16 -07003666 DataBufferedUntilRtpDataChannelObserverRegistered) {
deadbeef1dcb1642017-03-29 21:08:16 -07003667 virtual_socket_server()->set_delay_mean(5); // 5 ms per hop.
3668 virtual_socket_server()->UpdateDelayDistribution();
3669
Niels Möllerf06f9232018-08-07 12:32:18 +02003670 PeerConnectionInterface::RTCConfiguration rtc_config;
3671 rtc_config.enable_rtp_data_channel = true;
3672 rtc_config.enable_dtls_srtp = false;
3673 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003674 ConnectFakeSignaling();
3675 caller()->CreateDataChannel();
3676 caller()->CreateAndSetAndSignalOffer();
3677 ASSERT_TRUE(caller()->data_channel() != nullptr);
3678 ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr,
Yves Gerey100fe632020-01-17 19:15:53 +01003679 kDefaultTimeout, FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003680 ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(),
Yves Gerey100fe632020-01-17 19:15:53 +01003681 kDefaultTimeout, FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003682 ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen,
3683 callee()->data_channel()->state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01003684 FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003685
3686 // Unregister the observer which is normally automatically registered.
3687 callee()->data_channel()->UnregisterObserver();
3688 // Send data and advance fake clock until it should have been received.
3689 std::string data = "hello world";
3690 caller()->data_channel()->Send(DataBuffer(data));
Yves Gerey100fe632020-01-17 19:15:53 +01003691 SIMULATED_WAIT(false, 50, FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003692
3693 // Attach data channel and expect data to be received immediately. Note that
3694 // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any
3695 // further, but data can be received even if the callback is asynchronous.
3696 MockDataChannelObserver new_observer(callee()->data_channel());
3697 EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01003698 FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003699}
3700
3701// This test sets up a call between two parties with audio, video and but only
3702// the caller client supports RTP data channels.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003703TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003704 PeerConnectionInterface::RTCConfiguration rtc_config_1;
3705 rtc_config_1.enable_rtp_data_channel = true;
deadbeef1dcb1642017-03-29 21:08:16 -07003706 // Must disable DTLS to make negotiation succeed.
Niels Möllerf06f9232018-08-07 12:32:18 +02003707 rtc_config_1.enable_dtls_srtp = false;
3708 PeerConnectionInterface::RTCConfiguration rtc_config_2;
3709 rtc_config_2.enable_dtls_srtp = false;
3710 rtc_config_2.enable_dtls_srtp = false;
3711 ASSERT_TRUE(
3712 CreatePeerConnectionWrappersWithConfig(rtc_config_1, rtc_config_2));
deadbeef1dcb1642017-03-29 21:08:16 -07003713 ConnectFakeSignaling();
3714 caller()->CreateDataChannel();
Harald Alvestrandf3736ed2019-04-08 13:09:30 +02003715 ASSERT_TRUE(caller()->data_channel() != nullptr);
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 // The caller should still have a data channel, but it should be closed, and
3721 // one should ever have been created for the callee.
3722 EXPECT_TRUE(caller()->data_channel() != nullptr);
3723 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3724 EXPECT_EQ(nullptr, callee()->data_channel());
3725}
3726
3727// This test sets up a call between two parties with audio, and video. When
3728// audio and video is setup and flowing, an RTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003729TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003730 PeerConnectionInterface::RTCConfiguration rtc_config;
3731 rtc_config.enable_rtp_data_channel = true;
3732 rtc_config.enable_dtls_srtp = false;
3733 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003734 ConnectFakeSignaling();
3735 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003736 caller()->AddAudioVideoTracks();
3737 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003738 caller()->CreateAndSetAndSignalOffer();
3739 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3740 // Create data channel and do new offer and answer.
3741 caller()->CreateDataChannel();
3742 caller()->CreateAndSetAndSignalOffer();
3743 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3744 ASSERT_NE(nullptr, caller()->data_channel());
3745 ASSERT_NE(nullptr, callee()->data_channel());
3746 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3747 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3748 // Ensure data can be sent in both directions.
3749 std::string data = "hello world";
3750 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3751 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3752 kDefaultTimeout);
3753 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3754 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3755 kDefaultTimeout);
3756}
3757
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01003758#ifdef WEBRTC_HAVE_SCTP
deadbeef1dcb1642017-03-29 21:08:16 -07003759
3760// This test sets up a call between two parties with audio, video and an SCTP
3761// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003762TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003763 ASSERT_TRUE(CreatePeerConnectionWrappers());
3764 ConnectFakeSignaling();
3765 // Expect that data channel created on caller side will show up for callee as
3766 // well.
3767 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003768 caller()->AddAudioVideoTracks();
3769 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003770 caller()->CreateAndSetAndSignalOffer();
3771 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3772 // Ensure the existence of the SCTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003773 MediaExpectations media_expectations;
3774 media_expectations.ExpectBidirectionalAudioAndVideo();
3775 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003776 // Caller data channel should already exist (it created one). Callee data
3777 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3778 ASSERT_NE(nullptr, caller()->data_channel());
3779 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3780 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3781 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3782
3783 // Ensure data can be sent in both directions.
3784 std::string data = "hello world";
3785 caller()->data_channel()->Send(DataBuffer(data));
3786 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3787 kDefaultTimeout);
3788 callee()->data_channel()->Send(DataBuffer(data));
3789 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3790 kDefaultTimeout);
3791}
3792
3793// Ensure that when the callee closes an SCTP data channel, the closing
3794// procedure results in the data channel being closed for the caller as well.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003795TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003796 // Same procedure as above test.
3797 ASSERT_TRUE(CreatePeerConnectionWrappers());
3798 ConnectFakeSignaling();
3799 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003800 caller()->AddAudioVideoTracks();
3801 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003802 caller()->CreateAndSetAndSignalOffer();
3803 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3804 ASSERT_NE(nullptr, caller()->data_channel());
3805 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3806 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3807 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3808
3809 // Close the data channel on the callee side, and wait for it to reach the
3810 // "closed" state on both sides.
3811 callee()->data_channel()->Close();
3812 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3813 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3814}
3815
Seth Hampson2f0d7022018-02-20 11:54:42 -08003816TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
Steve Antonda6c0952017-10-23 11:41:54 -07003817 ASSERT_TRUE(CreatePeerConnectionWrappers());
3818 ConnectFakeSignaling();
3819 webrtc::DataChannelInit init;
3820 init.id = 53;
3821 init.maxRetransmits = 52;
3822 caller()->CreateDataChannel("data-channel", &init);
Steve Anton15324772018-01-16 10:26:49 -08003823 caller()->AddAudioVideoTracks();
3824 callee()->AddAudioVideoTracks();
Steve Antonda6c0952017-10-23 11:41:54 -07003825 caller()->CreateAndSetAndSignalOffer();
3826 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton074dece2017-10-24 13:04:12 -07003827 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3828 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Harald Alvestrand5c4d2ee2019-04-01 12:58:15 +02003829 // Since "negotiated" is false, the "id" parameter should be ignored.
3830 EXPECT_NE(init.id, callee()->data_channel()->id());
Steve Antonda6c0952017-10-23 11:41:54 -07003831 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3832 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3833 EXPECT_FALSE(callee()->data_channel()->negotiated());
3834}
3835
deadbeef1dcb1642017-03-29 21:08:16 -07003836// Test usrsctp's ability to process unordered data stream, where data actually
3837// arrives out of order using simulated delays. Previously there have been some
3838// bugs in this area.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003839TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003840 // Introduce random network delays.
3841 // Otherwise it's not a true "unordered" test.
3842 virtual_socket_server()->set_delay_mean(20);
3843 virtual_socket_server()->set_delay_stddev(5);
3844 virtual_socket_server()->UpdateDelayDistribution();
3845 // Normal procedure, but with unordered data channel config.
3846 ASSERT_TRUE(CreatePeerConnectionWrappers());
3847 ConnectFakeSignaling();
3848 webrtc::DataChannelInit init;
3849 init.ordered = false;
3850 caller()->CreateDataChannel(&init);
3851 caller()->CreateAndSetAndSignalOffer();
3852 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3853 ASSERT_NE(nullptr, caller()->data_channel());
3854 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3855 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3856 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3857
3858 static constexpr int kNumMessages = 100;
3859 // Deliberately chosen to be larger than the MTU so messages get fragmented.
3860 static constexpr size_t kMaxMessageSize = 4096;
3861 // Create and send random messages.
3862 std::vector<std::string> sent_messages;
3863 for (int i = 0; i < kNumMessages; ++i) {
3864 size_t length =
3865 (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand)
3866 std::string message;
3867 ASSERT_TRUE(rtc::CreateRandomString(length, &message));
3868 caller()->data_channel()->Send(DataBuffer(message));
3869 callee()->data_channel()->Send(DataBuffer(message));
3870 sent_messages.push_back(message);
3871 }
3872
3873 // Wait for all messages to be received.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003874 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003875 caller()->data_observer()->received_message_count(),
3876 kDefaultTimeout);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003877 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003878 callee()->data_observer()->received_message_count(),
3879 kDefaultTimeout);
3880
3881 // Sort and compare to make sure none of the messages were corrupted.
3882 std::vector<std::string> caller_received_messages =
3883 caller()->data_observer()->messages();
3884 std::vector<std::string> callee_received_messages =
3885 callee()->data_observer()->messages();
Steve Anton64b626b2019-01-28 17:25:26 -08003886 absl::c_sort(sent_messages);
3887 absl::c_sort(caller_received_messages);
3888 absl::c_sort(callee_received_messages);
deadbeef1dcb1642017-03-29 21:08:16 -07003889 EXPECT_EQ(sent_messages, caller_received_messages);
3890 EXPECT_EQ(sent_messages, callee_received_messages);
3891}
3892
3893// This test sets up a call between two parties with audio, and video. When
3894// audio and video are setup and flowing, an SCTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003895TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07003896 ASSERT_TRUE(CreatePeerConnectionWrappers());
3897 ConnectFakeSignaling();
3898 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003899 caller()->AddAudioVideoTracks();
3900 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003901 caller()->CreateAndSetAndSignalOffer();
3902 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3903 // Create data channel and do new offer and answer.
3904 caller()->CreateDataChannel();
3905 caller()->CreateAndSetAndSignalOffer();
3906 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3907 // Caller data channel should already exist (it created one). Callee data
3908 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3909 ASSERT_NE(nullptr, caller()->data_channel());
3910 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3911 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3912 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3913 // Ensure data can be sent in both directions.
3914 std::string data = "hello world";
3915 caller()->data_channel()->Send(DataBuffer(data));
3916 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3917 kDefaultTimeout);
3918 callee()->data_channel()->Send(DataBuffer(data));
3919 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3920 kDefaultTimeout);
3921}
3922
deadbeef7914b8c2017-04-21 03:23:33 -07003923// Set up a connection initially just using SCTP data channels, later upgrading
3924// to audio/video, ensuring frames are received end-to-end. Effectively the
3925// inverse of the test above.
3926// This was broken in M57; see https://crbug.com/711243
Seth Hampson2f0d7022018-02-20 11:54:42 -08003927TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
deadbeef7914b8c2017-04-21 03:23:33 -07003928 ASSERT_TRUE(CreatePeerConnectionWrappers());
3929 ConnectFakeSignaling();
3930 // Do initial offer/answer with just data channel.
3931 caller()->CreateDataChannel();
3932 caller()->CreateAndSetAndSignalOffer();
3933 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3934 // Wait until data can be sent over the data channel.
3935 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3936 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3937 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3938
3939 // Do subsequent offer/answer with two-way audio and video. Audio and video
3940 // should end up bundled on the DTLS/ICE transport already used for data.
Steve Anton15324772018-01-16 10:26:49 -08003941 caller()->AddAudioVideoTracks();
3942 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003943 caller()->CreateAndSetAndSignalOffer();
3944 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003945 MediaExpectations media_expectations;
3946 media_expectations.ExpectBidirectionalAudioAndVideo();
3947 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003948}
3949
deadbeef8b7e9ad2017-05-25 09:38:55 -07003950static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
Harald Alvestrand5fc28b12019-05-13 13:36:16 +02003951 cricket::SctpDataContentDescription* dcd_offer =
3952 GetFirstSctpDataContentDescription(desc);
Harald Alvestrand17ea0682019-12-13 11:51:04 +01003953 // See https://crbug.com/webrtc/11211 - this function is a no-op
Steve Antonb1c1de12017-12-21 15:14:30 -08003954 ASSERT_TRUE(dcd_offer);
deadbeef8b7e9ad2017-05-25 09:38:55 -07003955 dcd_offer->set_use_sctpmap(false);
3956 dcd_offer->set_protocol("UDP/DTLS/SCTP");
3957}
3958
3959// Test that the data channel works when a spec-compliant SCTP m= section is
3960// offered (using "a=sctp-port" instead of "a=sctpmap", and using
3961// "UDP/DTLS/SCTP" as the protocol).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003962TEST_P(PeerConnectionIntegrationTest,
deadbeef8b7e9ad2017-05-25 09:38:55 -07003963 DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
3964 ASSERT_TRUE(CreatePeerConnectionWrappers());
3965 ConnectFakeSignaling();
3966 caller()->CreateDataChannel();
3967 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
3968 caller()->CreateAndSetAndSignalOffer();
3969 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3970 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3971 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3972 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3973
3974 // Ensure data can be sent in both directions.
3975 std::string data = "hello world";
3976 caller()->data_channel()->Send(DataBuffer(data));
3977 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3978 kDefaultTimeout);
3979 callee()->data_channel()->Send(DataBuffer(data));
3980 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3981 kDefaultTimeout);
3982}
3983
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01003984#endif // WEBRTC_HAVE_SCTP
deadbeef1dcb1642017-03-29 21:08:16 -07003985
3986// Test that the ICE connection and gathering states eventually reach
3987// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08003988TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07003989 ASSERT_TRUE(CreatePeerConnectionWrappers());
3990 ConnectFakeSignaling();
3991 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08003992 caller()->AddAudioVideoTracks();
3993 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003994 caller()->CreateAndSetAndSignalOffer();
3995 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3996 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3997 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
3998 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3999 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
4000 // After the best candidate pair is selected and all candidates are signaled,
4001 // the ICE connection state should reach "complete".
4002 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
4003 // answerer/"callee" by default) only reaches "connected". When this is
4004 // fixed, this test should be updated.
4005 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4006 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00004007 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4008 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07004009}
4010
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004011constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
4012 cricket::PORTALLOCATOR_DISABLE_RELAY |
4013 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004014
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004015// Use a mock resolver to resolve the hostname back to the original IP on both
4016// sides and check that the ICE connection connects.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004017TEST_P(PeerConnectionIntegrationTest,
4018 IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004019 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004020 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004021 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004022 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004023 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
4024 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004025
4026 // This also verifies that the injected AsyncResolverFactory is used by
4027 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004028 EXPECT_CALL(*caller_resolver_factory, Create())
4029 .WillOnce(Return(&caller_async_resolver));
4030 webrtc::PeerConnectionDependencies caller_deps(nullptr);
4031 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
4032
4033 EXPECT_CALL(*callee_resolver_factory, Create())
4034 .WillOnce(Return(&callee_async_resolver));
4035 webrtc::PeerConnectionDependencies callee_deps(nullptr);
4036 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
4037
4038 PeerConnectionInterface::RTCConfiguration config;
4039 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
4040 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
4041
4042 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4043 config, std::move(caller_deps), config, std::move(callee_deps)));
4044
4045 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
4046 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
4047
4048 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07004049 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004050 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07004051 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004052 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004053
4054 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004055
4056 ConnectFakeSignaling();
4057 caller()->AddAudioVideoTracks();
4058 callee()->AddAudioVideoTracks();
4059 caller()->CreateAndSetAndSignalOffer();
4060 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4061 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4062 caller()->ice_connection_state(), kDefaultTimeout);
4063 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4064 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08004065
Ying Wangef3998f2019-12-09 13:06:53 +01004066 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
4067 "WebRTC.PeerConnection.CandidatePairType_UDP",
4068 webrtc::kIceCandidatePairHostNameHostName));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004069}
4070
Steve Antonede9ca52017-10-16 13:04:27 -07004071// Test that firewalling the ICE connection causes the clients to identify the
4072// disconnected state and then removing the firewall causes them to reconnect.
4073class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08004074 : public PeerConnectionIntegrationBaseTest,
4075 public ::testing::WithParamInterface<
4076 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07004077 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08004078 PeerConnectionIntegrationIceStatesTest()
4079 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
4080 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07004081 }
4082
4083 void StartStunServer(const SocketAddress& server_address) {
4084 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01004085 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07004086 }
4087
4088 bool TestIPv6() {
4089 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
4090 }
4091
4092 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004093 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
4094 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07004095 }
4096
4097 std::vector<SocketAddress> CallerAddresses() {
4098 std::vector<SocketAddress> addresses;
4099 addresses.push_back(SocketAddress("1.1.1.1", 0));
4100 if (TestIPv6()) {
4101 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
4102 }
4103 return addresses;
4104 }
4105
4106 std::vector<SocketAddress> CalleeAddresses() {
4107 std::vector<SocketAddress> addresses;
4108 addresses.push_back(SocketAddress("2.2.2.2", 0));
4109 if (TestIPv6()) {
4110 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
4111 }
4112 return addresses;
4113 }
4114
4115 void SetUpNetworkInterfaces() {
4116 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07004117 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
4118 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07004119
4120 // Add network addresses for test.
4121 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07004122 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07004123 }
4124 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07004125 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07004126 }
4127 }
4128
4129 private:
4130 uint32_t port_allocator_flags_;
4131 std::unique_ptr<cricket::TestStunServer> stun_server_;
4132};
4133
Yves Gerey100fe632020-01-17 19:15:53 +01004134// Ensure FakeClockForTest is constructed first (see class for rationale).
4135class PeerConnectionIntegrationIceStatesTestWithFakeClock
4136 : public FakeClockForTest,
4137 public PeerConnectionIntegrationIceStatesTest {};
4138
Steve Antonede9ca52017-10-16 13:04:27 -07004139// Tests that the PeerConnection goes through all the ICE gathering/connection
4140// states over the duration of the call. This includes Disconnected and Failed
4141// states, induced by putting a firewall between the peers and waiting for them
4142// to time out.
Yves Gerey100fe632020-01-17 19:15:53 +01004143TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock, VerifyIceStates) {
Steve Antonede9ca52017-10-16 13:04:27 -07004144 const SocketAddress kStunServerAddress =
4145 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
4146 StartStunServer(kStunServerAddress);
4147
4148 PeerConnectionInterface::RTCConfiguration config;
4149 PeerConnectionInterface::IceServer ice_stun_server;
4150 ice_stun_server.urls.push_back(
4151 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
4152 kStunServerAddress.PortAsString());
4153 config.servers.push_back(ice_stun_server);
4154
4155 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
4156 ConnectFakeSignaling();
4157 SetPortAllocatorFlags();
4158 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08004159 caller()->AddAudioVideoTracks();
4160 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004161
4162 // Initial state before anything happens.
4163 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
4164 caller()->ice_gathering_state());
4165 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
4166 caller()->ice_connection_state());
Jonas Olsson7a6739e2019-01-15 16:31:55 +01004167 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
4168 caller()->standardized_ice_connection_state());
Steve Antonede9ca52017-10-16 13:04:27 -07004169
4170 // Start the call by creating the offer, setting it as the local description,
4171 // then sending it to the peer who will respond with an answer. This happens
4172 // asynchronously so that we can watch the states as it runs in the
4173 // background.
4174 caller()->CreateAndSetAndSignalOffer();
4175
Steve Antona9b67ce2020-01-16 14:00:44 -08004176 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4177 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004178 FakeClock());
Steve Antona9b67ce2020-01-16 14:00:44 -08004179 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4180 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004181 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004182
4183 // Verify that the observer was notified of the intermediate transitions.
4184 EXPECT_THAT(caller()->ice_connection_state_history(),
4185 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
4186 PeerConnectionInterface::kIceConnectionConnected,
4187 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olssonacd8ae72019-02-25 15:26:24 +01004188 EXPECT_THAT(caller()->standardized_ice_connection_state_history(),
4189 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
4190 PeerConnectionInterface::kIceConnectionConnected,
4191 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olsson635474e2018-10-18 15:58:17 +02004192 EXPECT_THAT(
4193 caller()->peer_connection_state_history(),
4194 ElementsAre(PeerConnectionInterface::PeerConnectionState::kConnecting,
Jonas Olsson635474e2018-10-18 15:58:17 +02004195 PeerConnectionInterface::PeerConnectionState::kConnected));
Steve Antonede9ca52017-10-16 13:04:27 -07004196 EXPECT_THAT(caller()->ice_gathering_state_history(),
4197 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
4198 PeerConnectionInterface::kIceGatheringComplete));
4199
4200 // Block connections to/from the caller and wait for ICE to become
4201 // disconnected.
4202 for (const auto& caller_address : CallerAddresses()) {
4203 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4204 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01004205 RTC_LOG(LS_INFO) << "Firewall rules applied";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004206 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
4207 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004208 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004209 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
4210 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004211 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004212
4213 // Let ICE re-establish by removing the firewall rules.
4214 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01004215 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004216 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4217 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004218 FakeClock());
Jonas Olssonacd8ae72019-02-25 15:26:24 +01004219 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004220 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004221 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004222
4223 // According to RFC7675, if there is no response within 30 seconds then the
4224 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08004225 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07004226 constexpr int kConsentTimeout = 30000;
4227 for (const auto& caller_address : CallerAddresses()) {
4228 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4229 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01004230 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004231 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4232 caller()->ice_connection_state(), kConsentTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004233 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004234 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4235 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004236 kConsentTimeout, FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004237}
4238
4239// Tests that if the connection doesn't get set up properly we eventually reach
4240// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01004241TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
4242 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004243 // Block connections to/from the caller and wait for ICE to become
4244 // disconnected.
4245 for (const auto& caller_address : CallerAddresses()) {
4246 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4247 }
4248
4249 ASSERT_TRUE(CreatePeerConnectionWrappers());
4250 ConnectFakeSignaling();
4251 SetPortAllocatorFlags();
4252 SetUpNetworkInterfaces();
4253 caller()->AddAudioVideoTracks();
4254 caller()->CreateAndSetAndSignalOffer();
4255
4256 // According to RFC7675, if there is no response within 30 seconds then the
4257 // peer should consider the other side to have rejected the connection. This
4258 // is signaled by the state transitioning to "failed".
4259 constexpr int kConsentTimeout = 30000;
4260 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4261 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004262 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004263}
4264
4265// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
4266// and that the statistics in the metric observers are updated correctly.
4267TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) {
4268 ASSERT_TRUE(CreatePeerConnectionWrappers());
4269 ConnectFakeSignaling();
4270 SetPortAllocatorFlags();
4271 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08004272 caller()->AddAudioVideoTracks();
4273 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004274 caller()->CreateAndSetAndSignalOffer();
4275
4276 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08004277 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4278 caller()->ice_connection_state(), kDefaultTimeout);
4279 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4280 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07004281
Qingsi Wang7fc821d2018-07-12 12:54:53 -07004282 // TODO(bugs.webrtc.org/9456): Fix it.
4283 const int num_best_ipv4 = webrtc::metrics::NumEvents(
4284 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
4285 const int num_best_ipv6 = webrtc::metrics::NumEvents(
4286 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004287 if (TestIPv6()) {
4288 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
4289 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01004290 EXPECT_METRIC_EQ(0, num_best_ipv4);
4291 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004292 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01004293 EXPECT_METRIC_EQ(1, num_best_ipv4);
4294 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004295 }
4296
Ying Wangef3998f2019-12-09 13:06:53 +01004297 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
4298 "WebRTC.PeerConnection.CandidatePairType_UDP",
4299 webrtc::kIceCandidatePairHostHost));
4300 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
4301 "WebRTC.PeerConnection.CandidatePairType_UDP",
4302 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07004303}
4304
4305constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
4306 cricket::PORTALLOCATOR_DISABLE_STUN |
4307 cricket::PORTALLOCATOR_DISABLE_RELAY;
4308constexpr uint32_t kFlagsIPv6NoStun =
4309 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
4310 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
4311constexpr uint32_t kFlagsIPv4Stun =
4312 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
4313
Mirko Bonadeic84f6612019-01-31 12:20:57 +01004314INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004315 PeerConnectionIntegrationTest,
4316 PeerConnectionIntegrationIceStatesTest,
4317 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4318 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
4319 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
4320 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07004321
Yves Gerey100fe632020-01-17 19:15:53 +01004322INSTANTIATE_TEST_SUITE_P(
4323 PeerConnectionIntegrationTest,
4324 PeerConnectionIntegrationIceStatesTestWithFakeClock,
4325 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4326 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
4327 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
4328 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
4329
deadbeef1dcb1642017-03-29 21:08:16 -07004330// This test sets up a call between two parties with audio and video.
4331// During the call, the caller restarts ICE and the test verifies that
4332// new ICE candidates are generated and audio and video still can flow, and the
4333// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004334TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07004335 ASSERT_TRUE(CreatePeerConnectionWrappers());
4336 ConnectFakeSignaling();
4337 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08004338 caller()->AddAudioVideoTracks();
4339 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004340 caller()->CreateAndSetAndSignalOffer();
4341 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4342 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4343 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00004344 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4345 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07004346
4347 // To verify that the ICE restart actually occurs, get
4348 // ufrag/password/candidates before and after restart.
4349 // Create an SDP string of the first audio candidate for both clients.
4350 const webrtc::IceCandidateCollection* audio_candidates_caller =
4351 caller()->pc()->local_description()->candidates(0);
4352 const webrtc::IceCandidateCollection* audio_candidates_callee =
4353 callee()->pc()->local_description()->candidates(0);
4354 ASSERT_GT(audio_candidates_caller->count(), 0u);
4355 ASSERT_GT(audio_candidates_callee->count(), 0u);
4356 std::string caller_candidate_pre_restart;
4357 ASSERT_TRUE(
4358 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
4359 std::string callee_candidate_pre_restart;
4360 ASSERT_TRUE(
4361 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
4362 const cricket::SessionDescription* desc =
4363 caller()->pc()->local_description()->description();
4364 std::string caller_ufrag_pre_restart =
4365 desc->transport_infos()[0].description.ice_ufrag;
4366 desc = callee()->pc()->local_description()->description();
4367 std::string callee_ufrag_pre_restart =
4368 desc->transport_infos()[0].description.ice_ufrag;
4369
Alex Drake00c7ecf2019-08-06 10:54:47 -07004370 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07004371 // Have the caller initiate an ICE restart.
4372 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
4373 caller()->CreateAndSetAndSignalOffer();
4374 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4375 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4376 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00004377 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07004378 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4379
4380 // Grab the ufrags/candidates again.
4381 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
4382 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
4383 ASSERT_GT(audio_candidates_caller->count(), 0u);
4384 ASSERT_GT(audio_candidates_callee->count(), 0u);
4385 std::string caller_candidate_post_restart;
4386 ASSERT_TRUE(
4387 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
4388 std::string callee_candidate_post_restart;
4389 ASSERT_TRUE(
4390 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
4391 desc = caller()->pc()->local_description()->description();
4392 std::string caller_ufrag_post_restart =
4393 desc->transport_infos()[0].description.ice_ufrag;
4394 desc = callee()->pc()->local_description()->description();
4395 std::string callee_ufrag_post_restart =
4396 desc->transport_infos()[0].description.ice_ufrag;
4397 // Sanity check that an ICE restart was actually negotiated in SDP.
4398 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
4399 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
4400 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
4401 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07004402 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07004403
4404 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004405 MediaExpectations media_expectations;
4406 media_expectations.ExpectBidirectionalAudioAndVideo();
4407 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004408}
4409
4410// Verify that audio/video can be received end-to-end when ICE renomination is
4411// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004412TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07004413 PeerConnectionInterface::RTCConfiguration config;
4414 config.enable_ice_renomination = true;
4415 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
4416 ConnectFakeSignaling();
4417 // Do normal offer/answer and wait for some frames to be received in each
4418 // direction.
Steve Anton15324772018-01-16 10:26:49 -08004419 caller()->AddAudioVideoTracks();
4420 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004421 caller()->CreateAndSetAndSignalOffer();
4422 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4423 // Sanity check that ICE renomination was actually negotiated.
4424 const cricket::SessionDescription* desc =
4425 caller()->pc()->local_description()->description();
4426 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08004427 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07004428 }
4429 desc = callee()->pc()->local_description()->description();
4430 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08004431 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07004432 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08004433 MediaExpectations media_expectations;
4434 media_expectations.ExpectBidirectionalAudioAndVideo();
4435 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004436}
4437
Steve Anton6f25b092017-10-23 09:39:20 -07004438// With a max bundle policy and RTCP muxing, adding a new media description to
4439// the connection should not affect ICE at all because the new media will use
4440// the existing connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004441TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08004442 AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07004443 PeerConnectionInterface::RTCConfiguration config;
4444 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
4445 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
4446 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
4447 config, PeerConnectionInterface::RTCConfiguration()));
4448 ConnectFakeSignaling();
4449
Steve Anton15324772018-01-16 10:26:49 -08004450 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07004451 caller()->CreateAndSetAndSignalOffer();
4452 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07004453 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4454 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07004455
4456 caller()->clear_ice_connection_state_history();
4457
Steve Anton15324772018-01-16 10:26:49 -08004458 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07004459 caller()->CreateAndSetAndSignalOffer();
4460 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4461
4462 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
4463}
4464
deadbeef1dcb1642017-03-29 21:08:16 -07004465// This test sets up a call between two parties with audio and video. It then
4466// renegotiates setting the video m-line to "port 0", then later renegotiates
4467// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004468TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07004469 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
4470 ASSERT_TRUE(CreatePeerConnectionWrappers());
4471 ConnectFakeSignaling();
4472
4473 // Do initial negotiation, only sending media from the caller. Will result in
4474 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08004475 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004476 caller()->CreateAndSetAndSignalOffer();
4477 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4478
4479 // Negotiate again, disabling the video "m=" section (the callee will set the
4480 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08004481 if (sdp_semantics_ == SdpSemantics::kPlanB) {
4482 PeerConnectionInterface::RTCOfferAnswerOptions options;
4483 options.offer_to_receive_video = 0;
4484 callee()->SetOfferAnswerOptions(options);
4485 } else {
4486 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02004487 callee()
4488 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
4489 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08004490 });
4491 }
deadbeef1dcb1642017-03-29 21:08:16 -07004492 caller()->CreateAndSetAndSignalOffer();
4493 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4494 // Sanity check that video "m=" section was actually rejected.
4495 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
4496 callee()->pc()->local_description()->description());
4497 ASSERT_NE(nullptr, answer_video_content);
4498 ASSERT_TRUE(answer_video_content->rejected);
4499
4500 // Enable video and do negotiation again, making sure video is received
4501 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004502 if (sdp_semantics_ == SdpSemantics::kPlanB) {
4503 PeerConnectionInterface::RTCOfferAnswerOptions options;
4504 options.offer_to_receive_video = 1;
4505 callee()->SetOfferAnswerOptions(options);
4506 } else {
4507 // The caller's transceiver is stopped, so we need to add another track.
4508 auto caller_transceiver =
4509 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02004510 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08004511 caller()->AddVideoTrack();
4512 }
4513 callee()->AddVideoTrack();
4514 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07004515 caller()->CreateAndSetAndSignalOffer();
4516 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004517
deadbeef1dcb1642017-03-29 21:08:16 -07004518 // Verify the caller receives frames from the newly added stream, and the
4519 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004520 MediaExpectations media_expectations;
4521 media_expectations.CalleeExpectsSomeAudio();
4522 media_expectations.ExpectBidirectionalVideo();
4523 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004524}
4525
deadbeef1dcb1642017-03-29 21:08:16 -07004526// This tests that if we negotiate after calling CreateSender but before we
4527// have a track, then set a track later, frames from the newly-set track are
4528// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004529TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07004530 MediaFlowsAfterEarlyWarmupWithCreateSender) {
4531 ASSERT_TRUE(CreatePeerConnectionWrappers());
4532 ConnectFakeSignaling();
4533 auto caller_audio_sender =
4534 caller()->pc()->CreateSender("audio", "caller_stream");
4535 auto caller_video_sender =
4536 caller()->pc()->CreateSender("video", "caller_stream");
4537 auto callee_audio_sender =
4538 callee()->pc()->CreateSender("audio", "callee_stream");
4539 auto callee_video_sender =
4540 callee()->pc()->CreateSender("video", "callee_stream");
4541 caller()->CreateAndSetAndSignalOffer();
4542 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4543 // Wait for ICE to complete, without any tracks being set.
4544 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4545 caller()->ice_connection_state(), kMaxWaitForFramesMs);
4546 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4547 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4548 // Now set the tracks, and expect frames to immediately start flowing.
4549 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
4550 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
4551 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
4552 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08004553 MediaExpectations media_expectations;
4554 media_expectations.ExpectBidirectionalAudioAndVideo();
4555 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4556}
4557
4558// This tests that if we negotiate after calling AddTransceiver but before we
4559// have a track, then set a track later, frames from the newly-set tracks are
4560// received end-to-end.
4561TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
4562 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
4563 ASSERT_TRUE(CreatePeerConnectionWrappers());
4564 ConnectFakeSignaling();
4565 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
4566 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
4567 auto caller_audio_sender = audio_result.MoveValue()->sender();
4568 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
4569 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
4570 auto caller_video_sender = video_result.MoveValue()->sender();
4571 callee()->SetRemoteOfferHandler([this] {
4572 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02004573 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004574 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02004575 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004576 RtpTransceiverDirection::kSendRecv);
4577 });
4578 caller()->CreateAndSetAndSignalOffer();
4579 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4580 // Wait for ICE to complete, without any tracks being set.
4581 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4582 caller()->ice_connection_state(), kMaxWaitForFramesMs);
4583 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4584 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4585 // Now set the tracks, and expect frames to immediately start flowing.
4586 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
4587 auto callee_video_sender = callee()->pc()->GetSenders()[1];
4588 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
4589 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
4590 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
4591 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
4592 MediaExpectations media_expectations;
4593 media_expectations.ExpectBidirectionalAudioAndVideo();
4594 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004595}
4596
4597// This test verifies that a remote video track can be added via AddStream,
4598// and sent end-to-end. For this particular test, it's simply echoed back
4599// from the caller to the callee, rather than being forwarded to a third
4600// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004601TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07004602 ASSERT_TRUE(CreatePeerConnectionWrappers());
4603 ConnectFakeSignaling();
4604 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08004605 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07004606 caller()->CreateAndSetAndSignalOffer();
4607 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02004608 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07004609
4610 // Echo the stream back, and do a new offer/anwer (initiated by callee this
4611 // time).
4612 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
4613 callee()->CreateAndSetAndSignalOffer();
4614 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4615
Seth Hampson2f0d7022018-02-20 11:54:42 -08004616 MediaExpectations media_expectations;
4617 media_expectations.ExpectBidirectionalVideo();
4618 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004619}
4620
4621// Test that we achieve the expected end-to-end connection time, using a
4622// fake clock and simulated latency on the media and signaling paths.
4623// We use a TURN<->TURN connection because this is usually the quickest to
4624// set up initially, especially when we're confident the connection will work
4625// and can start sending media before we get a STUN response.
4626//
4627// With various optimizations enabled, here are the network delays we expect to
4628// be on the critical path:
4629// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
4630// signaling answer (with DTLS fingerprint).
4631// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
4632// using TURN<->TURN pair, and DTLS exchange is 4 packets,
4633// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01004634TEST_P(PeerConnectionIntegrationTestWithFakeClock,
4635 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07004636 static constexpr int media_hop_delay_ms = 50;
4637 static constexpr int signaling_trip_delay_ms = 500;
4638 // For explanation of these values, see comment above.
4639 static constexpr int required_media_hops = 9;
4640 static constexpr int required_signaling_trips = 2;
4641 // For internal delays (such as posting an event asychronously).
4642 static constexpr int allowed_internal_delay_ms = 20;
4643 static constexpr int total_connection_time_ms =
4644 media_hop_delay_ms * required_media_hops +
4645 signaling_trip_delay_ms * required_signaling_trips +
4646 allowed_internal_delay_ms;
4647
4648 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4649 3478};
4650 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4651 0};
4652 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4653 3478};
4654 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4655 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004656 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
4657 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004658
Seth Hampsonaed71642018-06-11 07:41:32 -07004659 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
4660 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07004661 // Bypass permission check on received packets so media can be sent before
4662 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07004663 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
4664 turn_server_1->set_enable_permission_checks(false);
4665 });
4666 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
4667 turn_server_2->set_enable_permission_checks(false);
4668 });
deadbeef1dcb1642017-03-29 21:08:16 -07004669
4670 PeerConnectionInterface::RTCConfiguration client_1_config;
4671 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4672 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4673 ice_server_1.username = "test";
4674 ice_server_1.password = "test";
4675 client_1_config.servers.push_back(ice_server_1);
4676 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4677 client_1_config.presume_writable_when_fully_relayed = true;
4678
4679 PeerConnectionInterface::RTCConfiguration client_2_config;
4680 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4681 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4682 ice_server_2.username = "test";
4683 ice_server_2.password = "test";
4684 client_2_config.servers.push_back(ice_server_2);
4685 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4686 client_2_config.presume_writable_when_fully_relayed = true;
4687
4688 ASSERT_TRUE(
4689 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4690 // Set up the simulated delays.
4691 SetSignalingDelayMs(signaling_trip_delay_ms);
4692 ConnectFakeSignaling();
4693 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
4694 virtual_socket_server()->UpdateDelayDistribution();
4695
4696 // Set "offer to receive audio/video" without adding any tracks, so we just
4697 // set up ICE/DTLS with no media.
4698 PeerConnectionInterface::RTCOfferAnswerOptions options;
4699 options.offer_to_receive_audio = 1;
4700 options.offer_to_receive_video = 1;
4701 caller()->SetOfferAnswerOptions(options);
4702 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07004703 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01004704 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07004705 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
4706 // If this is not done a DCHECK can be hit in ports.cc, because a large
4707 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07004708 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07004709}
4710
Jonas Orelandbdcee282017-10-10 14:01:40 +02004711// Verify that a TurnCustomizer passed in through RTCConfiguration
4712// is actually used by the underlying TURN candidate pair.
4713// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004714TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02004715 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4716 3478};
4717 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4718 0};
4719 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4720 3478};
4721 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4722 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004723 CreateTurnServer(turn_server_1_internal_address,
4724 turn_server_1_external_address);
4725 CreateTurnServer(turn_server_2_internal_address,
4726 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004727
4728 PeerConnectionInterface::RTCConfiguration client_1_config;
4729 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4730 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4731 ice_server_1.username = "test";
4732 ice_server_1.password = "test";
4733 client_1_config.servers.push_back(ice_server_1);
4734 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004735 auto* customizer1 = CreateTurnCustomizer();
4736 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004737
4738 PeerConnectionInterface::RTCConfiguration client_2_config;
4739 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4740 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4741 ice_server_2.username = "test";
4742 ice_server_2.password = "test";
4743 client_2_config.servers.push_back(ice_server_2);
4744 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004745 auto* customizer2 = CreateTurnCustomizer();
4746 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004747
4748 ASSERT_TRUE(
4749 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4750 ConnectFakeSignaling();
4751
4752 // Set "offer to receive audio/video" without adding any tracks, so we just
4753 // set up ICE/DTLS with no media.
4754 PeerConnectionInterface::RTCOfferAnswerOptions options;
4755 options.offer_to_receive_audio = 1;
4756 options.offer_to_receive_video = 1;
4757 caller()->SetOfferAnswerOptions(options);
4758 caller()->CreateAndSetAndSignalOffer();
4759 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4760
Seth Hampsonaed71642018-06-11 07:41:32 -07004761 ExpectTurnCustomizerCountersIncremented(customizer1);
4762 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004763}
4764
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004765// Verifies that you can use TCP instead of UDP to connect to a TURN server and
4766// send media between the caller and the callee.
4767TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
4768 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4769 3478};
4770 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4771
4772 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07004773 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4774 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004775
4776 webrtc::PeerConnectionInterface::IceServer ice_server;
4777 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
4778 ice_server.username = "test";
4779 ice_server.password = "test";
4780
4781 PeerConnectionInterface::RTCConfiguration client_1_config;
4782 client_1_config.servers.push_back(ice_server);
4783 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4784
4785 PeerConnectionInterface::RTCConfiguration client_2_config;
4786 client_2_config.servers.push_back(ice_server);
4787 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4788
4789 ASSERT_TRUE(
4790 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4791
4792 // Do normal offer/answer and wait for ICE to complete.
4793 ConnectFakeSignaling();
4794 caller()->AddAudioVideoTracks();
4795 callee()->AddAudioVideoTracks();
4796 caller()->CreateAndSetAndSignalOffer();
4797 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4798 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4799 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4800
4801 MediaExpectations media_expectations;
4802 media_expectations.ExpectBidirectionalAudioAndVideo();
4803 EXPECT_TRUE(ExpectNewFrames(media_expectations));
4804}
4805
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004806// Verify that a SSLCertificateVerifier passed in through
4807// PeerConnectionDependencies is actually used by the underlying SSL
4808// implementation to determine whether a certificate presented by the TURN
4809// server is accepted by the client. Note that openssladapter_unittest.cc
4810// contains more detailed, lower-level tests.
4811TEST_P(PeerConnectionIntegrationTest,
4812 SSLCertificateVerifierUsedForTurnConnections) {
4813 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4814 3478};
4815 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4816
4817 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4818 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004819 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4820 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004821
4822 webrtc::PeerConnectionInterface::IceServer ice_server;
4823 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4824 ice_server.username = "test";
4825 ice_server.password = "test";
4826
4827 PeerConnectionInterface::RTCConfiguration client_1_config;
4828 client_1_config.servers.push_back(ice_server);
4829 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4830
4831 PeerConnectionInterface::RTCConfiguration client_2_config;
4832 client_2_config.servers.push_back(ice_server);
4833 // Setting the type to kRelay forces the connection to go through a TURN
4834 // server.
4835 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4836
4837 // Get a copy to the pointer so we can verify calls later.
4838 rtc::TestCertificateVerifier* client_1_cert_verifier =
4839 new rtc::TestCertificateVerifier();
4840 client_1_cert_verifier->verify_certificate_ = true;
4841 rtc::TestCertificateVerifier* client_2_cert_verifier =
4842 new rtc::TestCertificateVerifier();
4843 client_2_cert_verifier->verify_certificate_ = true;
4844
4845 // Create the dependencies with the test certificate verifier.
4846 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4847 client_1_deps.tls_cert_verifier =
4848 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4849 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4850 client_2_deps.tls_cert_verifier =
4851 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4852
4853 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4854 client_1_config, std::move(client_1_deps), client_2_config,
4855 std::move(client_2_deps)));
4856 ConnectFakeSignaling();
4857
4858 // Set "offer to receive audio/video" without adding any tracks, so we just
4859 // set up ICE/DTLS with no media.
4860 PeerConnectionInterface::RTCOfferAnswerOptions options;
4861 options.offer_to_receive_audio = 1;
4862 options.offer_to_receive_video = 1;
4863 caller()->SetOfferAnswerOptions(options);
4864 caller()->CreateAndSetAndSignalOffer();
4865 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4866
4867 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4868 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004869}
4870
4871TEST_P(PeerConnectionIntegrationTest,
4872 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
4873 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4874 3478};
4875 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4876
4877 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4878 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004879 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4880 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004881
4882 webrtc::PeerConnectionInterface::IceServer ice_server;
4883 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4884 ice_server.username = "test";
4885 ice_server.password = "test";
4886
4887 PeerConnectionInterface::RTCConfiguration client_1_config;
4888 client_1_config.servers.push_back(ice_server);
4889 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4890
4891 PeerConnectionInterface::RTCConfiguration client_2_config;
4892 client_2_config.servers.push_back(ice_server);
4893 // Setting the type to kRelay forces the connection to go through a TURN
4894 // server.
4895 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4896
4897 // Get a copy to the pointer so we can verify calls later.
4898 rtc::TestCertificateVerifier* client_1_cert_verifier =
4899 new rtc::TestCertificateVerifier();
4900 client_1_cert_verifier->verify_certificate_ = false;
4901 rtc::TestCertificateVerifier* client_2_cert_verifier =
4902 new rtc::TestCertificateVerifier();
4903 client_2_cert_verifier->verify_certificate_ = false;
4904
4905 // Create the dependencies with the test certificate verifier.
4906 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4907 client_1_deps.tls_cert_verifier =
4908 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4909 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4910 client_2_deps.tls_cert_verifier =
4911 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4912
4913 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4914 client_1_config, std::move(client_1_deps), client_2_config,
4915 std::move(client_2_deps)));
4916 ConnectFakeSignaling();
4917
4918 // Set "offer to receive audio/video" without adding any tracks, so we just
4919 // set up ICE/DTLS with no media.
4920 PeerConnectionInterface::RTCOfferAnswerOptions options;
4921 options.offer_to_receive_audio = 1;
4922 options.offer_to_receive_video = 1;
4923 caller()->SetOfferAnswerOptions(options);
4924 caller()->CreateAndSetAndSignalOffer();
4925 bool wait_res = true;
4926 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
4927 // properly, should be able to just wait for a state of "failed" instead of
4928 // waiting a fixed 10 seconds.
4929 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
4930 ASSERT_FALSE(wait_res);
4931
4932 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4933 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004934}
4935
Qingsi Wang25ec8882019-11-15 12:33:05 -08004936// Test that the injected ICE transport factory is used to create ICE transports
4937// for WebRTC connections.
4938TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
4939 PeerConnectionInterface::RTCConfiguration default_config;
4940 PeerConnectionDependencies dependencies(nullptr);
4941 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
4942 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
4943 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02004944 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
4945 std::move(dependencies), nullptr,
4946 /*reset_encoder_factory=*/false,
4947 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08004948 ASSERT_TRUE(wrapper);
4949 wrapper->CreateDataChannel();
4950 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
4951 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
4952 wrapper->pc()->SetLocalDescription(observer,
4953 wrapper->CreateOfferAndWait().release());
4954}
4955
deadbeefc964d0b2017-04-03 10:03:35 -07004956// Test that audio and video flow end-to-end when codec names don't use the
4957// expected casing, given that they're supposed to be case insensitive. To test
4958// this, all but one codec is removed from each media description, and its
4959// casing is changed.
4960//
4961// In the past, this has regressed and caused crashes/black video, due to the
4962// fact that code at some layers was doing case-insensitive comparisons and
4963// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004964TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07004965 ASSERT_TRUE(CreatePeerConnectionWrappers());
4966 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004967 caller()->AddAudioVideoTracks();
4968 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07004969
4970 // Remove all but one audio/video codec (opus and VP8), and change the
4971 // casing of the caller's generated offer.
4972 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
4973 cricket::AudioContentDescription* audio =
4974 GetFirstAudioContentDescription(description);
4975 ASSERT_NE(nullptr, audio);
4976 auto audio_codecs = audio->codecs();
4977 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
4978 [](const cricket::AudioCodec& codec) {
4979 return codec.name != "opus";
4980 }),
4981 audio_codecs.end());
4982 ASSERT_EQ(1u, audio_codecs.size());
4983 audio_codecs[0].name = "OpUs";
4984 audio->set_codecs(audio_codecs);
4985
4986 cricket::VideoContentDescription* video =
4987 GetFirstVideoContentDescription(description);
4988 ASSERT_NE(nullptr, video);
4989 auto video_codecs = video->codecs();
4990 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
4991 [](const cricket::VideoCodec& codec) {
4992 return codec.name != "VP8";
4993 }),
4994 video_codecs.end());
4995 ASSERT_EQ(1u, video_codecs.size());
4996 video_codecs[0].name = "vP8";
4997 video->set_codecs(video_codecs);
4998 });
4999
5000 caller()->CreateAndSetAndSignalOffer();
5001 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5002
5003 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005004 MediaExpectations media_expectations;
5005 media_expectations.ExpectBidirectionalAudioAndVideo();
5006 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07005007}
5008
Jonas Oreland49ac5952018-09-26 16:04:32 +02005009TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07005010 ASSERT_TRUE(CreatePeerConnectionWrappers());
5011 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08005012 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07005013 caller()->CreateAndSetAndSignalOffer();
5014 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07005015 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005016 MediaExpectations media_expectations;
5017 media_expectations.CalleeExpectsSomeAudio(1);
5018 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02005019 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07005020 auto receiver = callee()->pc()->GetReceivers()[0];
5021 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02005022 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07005023 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
5024 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02005025 sources[0].source_id());
5026 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
5027}
5028
5029TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
5030 ASSERT_TRUE(CreatePeerConnectionWrappers());
5031 ConnectFakeSignaling();
5032 caller()->AddVideoTrack();
5033 caller()->CreateAndSetAndSignalOffer();
5034 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5035 // Wait for one video frame to be received by the callee.
5036 MediaExpectations media_expectations;
5037 media_expectations.CalleeExpectsSomeVideo(1);
5038 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5039 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
5040 auto receiver = callee()->pc()->GetReceivers()[0];
5041 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
5042 auto sources = receiver->GetSources();
5043 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02005044 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02005045 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
5046 sources[0].source_id());
5047 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07005048}
5049
deadbeef2f425aa2017-04-14 10:41:32 -07005050// Test that if a track is removed and added again with a different stream ID,
5051// the new stream ID is successfully communicated in SDP and media continues to
5052// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005053// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
5054// it will not reuse a transceiver that has already been sending. After creating
5055// a new transceiver it tries to create an offer with two senders of the same
5056// track ids and it fails.
5057TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07005058 ASSERT_TRUE(CreatePeerConnectionWrappers());
5059 ConnectFakeSignaling();
5060
deadbeef2f425aa2017-04-14 10:41:32 -07005061 // Add track using stream 1, do offer/answer.
5062 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
5063 caller()->CreateLocalAudioTrack();
5064 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07005065 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07005066 caller()->CreateAndSetAndSignalOffer();
5067 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005068 {
5069 MediaExpectations media_expectations;
5070 media_expectations.CalleeExpectsSomeAudio(1);
5071 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5072 }
deadbeef2f425aa2017-04-14 10:41:32 -07005073 // Remove the sender, and create a new one with the new stream.
5074 caller()->pc()->RemoveTrack(sender);
Steve Antond78323f2018-07-11 11:13:44 -07005075 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07005076 caller()->CreateAndSetAndSignalOffer();
5077 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5078 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005079 {
5080 MediaExpectations media_expectations;
5081 media_expectations.CalleeExpectsSomeAudio();
5082 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5083 }
deadbeef2f425aa2017-04-14 10:41:32 -07005084}
5085
Seth Hampson2f0d7022018-02-20 11:54:42 -08005086TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02005087 ASSERT_TRUE(CreatePeerConnectionWrappers());
5088 ConnectFakeSignaling();
5089
Mirko Bonadei317a1f02019-09-17 17:06:18 +02005090 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02005091 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
5092 ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true));
Elad Alon99c3fe52017-10-13 16:29:40 +02005093 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01005094 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
5095 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02005096
Steve Anton15324772018-01-16 10:26:49 -08005097 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02005098 caller()->CreateAndSetAndSignalOffer();
5099 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5100}
5101
Steve Antonede9ca52017-10-16 13:04:27 -07005102// Test that if candidates are only signaled by applying full session
5103// descriptions (instead of using AddIceCandidate), the peers can connect to
5104// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005105TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07005106 ASSERT_TRUE(CreatePeerConnectionWrappers());
5107 // Each side will signal the session descriptions but not candidates.
5108 ConnectFakeSignalingForSdpOnly();
5109
5110 // Add audio video track and exchange the initial offer/answer with media
5111 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08005112 caller()->AddAudioVideoTracks();
5113 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07005114 caller()->CreateAndSetAndSignalOffer();
5115
5116 // Wait for all candidates to be gathered on both the caller and callee.
5117 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
5118 caller()->ice_gathering_state(), kDefaultTimeout);
5119 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
5120 callee()->ice_gathering_state(), kDefaultTimeout);
5121
5122 // The candidates will now be included in the session description, so
5123 // signaling them will start the ICE connection.
5124 caller()->CreateAndSetAndSignalOffer();
5125 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5126
5127 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005128 MediaExpectations media_expectations;
5129 media_expectations.ExpectBidirectionalAudioAndVideo();
5130 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07005131}
5132
henrika5f6bf242017-11-01 11:06:56 +01005133// Test that SetAudioPlayout can be used to disable audio playout from the
5134// start, then later enable it. This may be useful, for example, if the caller
5135// needs to play a local ringtone until some event occurs, after which it
5136// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005137TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01005138 ASSERT_TRUE(CreatePeerConnectionWrappers());
5139 ConnectFakeSignaling();
5140
5141 // Set up audio-only call where audio playout is disabled on caller's side.
5142 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08005143 caller()->AddAudioTrack();
5144 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01005145 caller()->CreateAndSetAndSignalOffer();
5146 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5147
5148 // Pump messages for a second.
5149 WAIT(false, 1000);
5150 // Since audio playout is disabled, the caller shouldn't have received
5151 // anything (at the playout level, at least).
5152 EXPECT_EQ(0, caller()->audio_frames_received());
5153 // As a sanity check, make sure the callee (for which playout isn't disabled)
5154 // did still see frames on its audio level.
5155 ASSERT_GT(callee()->audio_frames_received(), 0);
5156
5157 // Enable playout again, and ensure audio starts flowing.
5158 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005159 MediaExpectations media_expectations;
5160 media_expectations.ExpectBidirectionalAudio();
5161 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01005162}
5163
5164double GetAudioEnergyStat(PeerConnectionWrapper* pc) {
5165 auto report = pc->NewGetStats();
5166 auto track_stats_list =
5167 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
5168 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
5169 for (const auto* track_stats : track_stats_list) {
5170 if (track_stats->remote_source.is_defined() &&
5171 *track_stats->remote_source) {
5172 remote_track_stats = track_stats;
5173 break;
5174 }
5175 }
5176
5177 if (!remote_track_stats->total_audio_energy.is_defined()) {
5178 return 0.0;
5179 }
5180 return *remote_track_stats->total_audio_energy;
5181}
5182
5183// Test that if audio playout is disabled via the SetAudioPlayout() method, then
5184// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005185TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01005186 DisableAudioPlayoutStillGeneratesAudioStats) {
5187 ASSERT_TRUE(CreatePeerConnectionWrappers());
5188 ConnectFakeSignaling();
5189
5190 // Set up audio-only call where playout is disabled but audio-processing is
5191 // still active.
Steve Anton15324772018-01-16 10:26:49 -08005192 caller()->AddAudioTrack();
5193 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01005194 caller()->pc()->SetAudioPlayout(false);
5195
5196 caller()->CreateAndSetAndSignalOffer();
5197 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5198
5199 // Wait for the callee to receive audio stats.
5200 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
5201}
5202
henrika4f167df2017-11-01 14:45:55 +01005203// Test that SetAudioRecording can be used to disable audio recording from the
5204// start, then later enable it. This may be useful, for example, if the caller
5205// wants to ensure that no audio resources are active before a certain state
5206// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005207TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01005208 ASSERT_TRUE(CreatePeerConnectionWrappers());
5209 ConnectFakeSignaling();
5210
5211 // Set up audio-only call where audio recording is disabled on caller's side.
5212 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08005213 caller()->AddAudioTrack();
5214 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01005215 caller()->CreateAndSetAndSignalOffer();
5216 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5217
5218 // Pump messages for a second.
5219 WAIT(false, 1000);
5220 // Since caller has disabled audio recording, the callee shouldn't have
5221 // received anything.
5222 EXPECT_EQ(0, callee()->audio_frames_received());
5223 // As a sanity check, make sure the caller did still see frames on its
5224 // audio level since audio recording is enabled on the calle side.
5225 ASSERT_GT(caller()->audio_frames_received(), 0);
5226
5227 // Enable audio recording again, and ensure audio starts flowing.
5228 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005229 MediaExpectations media_expectations;
5230 media_expectations.ExpectBidirectionalAudio();
5231 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01005232}
5233
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005234// Test that after closing PeerConnections, they stop sending any packets (ICE,
5235// DTLS, RTP...).
Seth Hampson2f0d7022018-02-20 11:54:42 -08005236TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005237 // Set up audio/video/data, wait for some frames to be received.
5238 ASSERT_TRUE(CreatePeerConnectionWrappers());
5239 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08005240 caller()->AddAudioVideoTracks();
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005241#ifdef WEBRTC_HAVE_SCTP
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005242 caller()->CreateDataChannel();
5243#endif
5244 caller()->CreateAndSetAndSignalOffer();
5245 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005246 MediaExpectations media_expectations;
5247 media_expectations.CalleeExpectsSomeAudioAndVideo();
5248 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005249 // Close PeerConnections.
Steve Antond91969e2019-05-30 12:27:03 -07005250 ClosePeerConnections();
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005251 // Pump messages for a second, and ensure no new packets end up sent.
5252 uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
5253 WAIT(false, 1000);
5254 uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
5255 EXPECT_EQ(sent_packets_a, sent_packets_b);
5256}
5257
Steve Anton7eca0932018-03-30 15:18:41 -07005258// Test that transport stats are generated by the RTCStatsCollector for a
5259// connection that only involves data channels. This is a regression test for
5260// crbug.com/826972.
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005261#ifdef WEBRTC_HAVE_SCTP
Steve Anton7eca0932018-03-30 15:18:41 -07005262TEST_P(PeerConnectionIntegrationTest,
5263 TransportStatsReportedForDataChannelOnlyConnection) {
5264 ASSERT_TRUE(CreatePeerConnectionWrappers());
5265 ConnectFakeSignaling();
5266 caller()->CreateDataChannel();
5267
5268 caller()->CreateAndSetAndSignalOffer();
5269 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5270 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
5271
5272 auto caller_report = caller()->NewGetStats();
5273 EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
5274 auto callee_report = callee()->NewGetStats();
5275 EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
5276}
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005277#endif // WEBRTC_HAVE_SCTP
Steve Anton7eca0932018-03-30 15:18:41 -07005278
Qingsi Wang7685e862018-06-11 20:15:46 -07005279TEST_P(PeerConnectionIntegrationTest,
5280 IceEventsGeneratedAndLoggedInRtcEventLog) {
5281 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
5282 ConnectFakeSignaling();
5283 PeerConnectionInterface::RTCOfferAnswerOptions options;
5284 options.offer_to_receive_audio = 1;
5285 caller()->SetOfferAnswerOptions(options);
5286 caller()->CreateAndSetAndSignalOffer();
5287 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
5288 ASSERT_NE(nullptr, caller()->event_log_factory());
5289 ASSERT_NE(nullptr, callee()->event_log_factory());
5290 webrtc::FakeRtcEventLog* caller_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01005291 caller()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07005292 webrtc::FakeRtcEventLog* callee_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01005293 callee()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07005294 ASSERT_NE(nullptr, caller_event_log);
5295 ASSERT_NE(nullptr, callee_event_log);
5296 int caller_ice_config_count = caller_event_log->GetEventCount(
5297 webrtc::RtcEvent::Type::IceCandidatePairConfig);
5298 int caller_ice_event_count = caller_event_log->GetEventCount(
5299 webrtc::RtcEvent::Type::IceCandidatePairEvent);
5300 int callee_ice_config_count = callee_event_log->GetEventCount(
5301 webrtc::RtcEvent::Type::IceCandidatePairConfig);
5302 int callee_ice_event_count = callee_event_log->GetEventCount(
5303 webrtc::RtcEvent::Type::IceCandidatePairEvent);
5304 EXPECT_LT(0, caller_ice_config_count);
5305 EXPECT_LT(0, caller_ice_event_count);
5306 EXPECT_LT(0, callee_ice_config_count);
5307 EXPECT_LT(0, callee_ice_event_count);
5308}
5309
Qingsi Wangc129c352019-04-18 10:41:58 -07005310TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07005311 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
5312 3478};
5313 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
5314
5315 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
5316
5317 webrtc::PeerConnectionInterface::IceServer ice_server;
5318 ice_server.urls.push_back("turn:88.88.88.0:3478");
5319 ice_server.username = "test";
5320 ice_server.password = "test";
5321
5322 PeerConnectionInterface::RTCConfiguration caller_config;
5323 caller_config.servers.push_back(ice_server);
5324 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5325 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005326 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07005327
5328 PeerConnectionInterface::RTCConfiguration callee_config;
5329 callee_config.servers.push_back(ice_server);
5330 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5331 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005332 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07005333
5334 ASSERT_TRUE(
5335 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5336
5337 // Do normal offer/answer and wait for ICE to complete.
5338 ConnectFakeSignaling();
5339 caller()->AddAudioVideoTracks();
5340 callee()->AddAudioVideoTracks();
5341 caller()->CreateAndSetAndSignalOffer();
5342 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5343 // Since we are doing continual gathering, the ICE transport does not reach
5344 // kIceGatheringComplete (see
5345 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
5346 // kIceConnectionComplete.
5347 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
5348 caller()->ice_connection_state(), kDefaultTimeout);
5349 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
5350 callee()->ice_connection_state(), kDefaultTimeout);
5351 // Note that we cannot use the metric
5352 // |WebRTC.PeerConnection.CandidatePairType_UDP| in this test since this
5353 // metric is only populated when we reach kIceConnectionComplete in the
5354 // current implementation.
5355 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
5356 caller()->last_candidate_gathered().type());
5357 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
5358 callee()->last_candidate_gathered().type());
5359
5360 // Loosen the caller's candidate filter.
5361 caller_config = caller()->pc()->GetConfiguration();
5362 caller_config.type = webrtc::PeerConnectionInterface::kAll;
5363 caller()->pc()->SetConfiguration(caller_config);
5364 // We should have gathered a new host candidate.
5365 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
5366 caller()->last_candidate_gathered().type(), kDefaultTimeout);
5367
5368 // Loosen the callee's candidate filter.
5369 callee_config = callee()->pc()->GetConfiguration();
5370 callee_config.type = webrtc::PeerConnectionInterface::kAll;
5371 callee()->pc()->SetConfiguration(callee_config);
5372 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
5373 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02005374
5375 // Create an offer and verify that it does not contain an ICE restart (i.e new
5376 // ice credentials).
5377 std::string caller_ufrag_pre_offer = caller()
5378 ->pc()
5379 ->local_description()
5380 ->description()
5381 ->transport_infos()[0]
5382 .description.ice_ufrag;
5383 caller()->CreateAndSetAndSignalOffer();
5384 std::string caller_ufrag_post_offer = caller()
5385 ->pc()
5386 ->local_description()
5387 ->description()
5388 ->transport_infos()[0]
5389 .description.ice_ufrag;
5390 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07005391}
5392
Eldar Relloda13ea22019-06-01 12:23:43 +03005393TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03005394 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
5395 3478};
5396 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
5397
5398 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
5399
5400 webrtc::PeerConnectionInterface::IceServer ice_server;
5401 ice_server.urls.push_back("turn:88.88.88.0:3478");
5402 ice_server.username = "test";
5403 ice_server.password = "123";
5404
5405 PeerConnectionInterface::RTCConfiguration caller_config;
5406 caller_config.servers.push_back(ice_server);
5407 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5408 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5409
5410 PeerConnectionInterface::RTCConfiguration callee_config;
5411 callee_config.servers.push_back(ice_server);
5412 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5413 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5414
5415 ASSERT_TRUE(
5416 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5417
5418 // Do normal offer/answer and wait for ICE to complete.
5419 ConnectFakeSignaling();
5420 caller()->AddAudioVideoTracks();
5421 callee()->AddAudioVideoTracks();
5422 caller()->CreateAndSetAndSignalOffer();
5423 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5424 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
5425 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
5426 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02005427 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03005428}
5429
Eldar Rellofa8019c2020-05-14 11:59:33 +03005430TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
5431 webrtc::PeerConnectionInterface::IceServer ice_server;
5432 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
5433 ice_server.username = "test";
5434 ice_server.password = "test";
5435
5436 PeerConnectionInterface::RTCConfiguration caller_config;
5437 caller_config.servers.push_back(ice_server);
5438 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5439 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5440
5441 PeerConnectionInterface::RTCConfiguration callee_config;
5442 callee_config.servers.push_back(ice_server);
5443 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5444 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5445
5446 ASSERT_TRUE(
5447 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5448
5449 // Do normal offer/answer and wait for ICE to complete.
5450 ConnectFakeSignaling();
5451 caller()->AddAudioVideoTracks();
5452 callee()->AddAudioVideoTracks();
5453 caller()->CreateAndSetAndSignalOffer();
5454 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5455 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
5456 EXPECT_EQ(caller()->error_event().address, "");
5457}
5458
Eldar Rello5ab79e62019-10-09 18:29:44 +03005459TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5460 AudioKeepsFlowingAfterImplicitRollback) {
5461 PeerConnectionInterface::RTCConfiguration config;
5462 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5463 config.enable_implicit_rollback = true;
5464 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5465 ConnectFakeSignaling();
5466 caller()->AddAudioTrack();
5467 callee()->AddAudioTrack();
5468 caller()->CreateAndSetAndSignalOffer();
5469 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5470 MediaExpectations media_expectations;
5471 media_expectations.ExpectBidirectionalAudio();
5472 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5473 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
5474 caller()->AddVideoTrack();
5475 callee()->AddVideoTrack();
5476 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
5477 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5478 callee()->pc()->SetLocalDescription(observer,
5479 callee()->CreateOfferAndWait().release());
5480 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
5481 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
5482 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5483 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5484}
5485
5486TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5487 ImplicitRollbackVisitsStableState) {
5488 RTCConfiguration config;
5489 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5490 config.enable_implicit_rollback = true;
5491
5492 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5493
5494 rtc::scoped_refptr<MockSetSessionDescriptionObserver> sld_observer(
5495 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5496 callee()->pc()->SetLocalDescription(sld_observer,
5497 callee()->CreateOfferAndWait().release());
5498 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
5499 EXPECT_EQ(sld_observer->error(), "");
5500
5501 rtc::scoped_refptr<MockSetSessionDescriptionObserver> srd_observer(
5502 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5503 callee()->pc()->SetRemoteDescription(
5504 srd_observer, caller()->CreateOfferAndWait().release());
5505 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
5506 EXPECT_EQ(srd_observer->error(), "");
5507
5508 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
5509 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
5510 PeerConnectionInterface::kStable,
5511 PeerConnectionInterface::kHaveRemoteOffer));
5512}
5513
Eldar Rellobd9c33a2020-10-01 17:52:45 +03005514TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5515 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
5516 ASSERT_TRUE(CreatePeerConnectionWrappers());
5517 ConnectFakeSignaling();
5518 caller()->AddVideoTrack();
5519 callee()->AddVideoTrack();
5520 auto munger = [](cricket::SessionDescription* desc) {
5521 cricket::VideoContentDescription* video =
5522 GetFirstVideoContentDescription(desc);
5523 auto codecs = video->codecs();
5524 for (auto&& codec : codecs) {
5525 if (codec.name == "H264") {
5526 std::string value;
5527 // The parameter is not supposed to be present in SDP by default.
5528 EXPECT_FALSE(
5529 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
5530 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
5531 std::string(""));
5532 }
5533 }
5534 video->set_codecs(codecs);
5535 };
5536 // Munge local offer for SLD.
5537 caller()->SetGeneratedSdpMunger(munger);
5538 // Munge remote answer for SRD.
5539 caller()->SetReceivedSdpMunger(munger);
5540 caller()->CreateAndSetAndSignalOffer();
5541 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5542 // Observe that after munging the parameter is present in generated SDP.
5543 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
5544 cricket::VideoContentDescription* video =
5545 GetFirstVideoContentDescription(desc);
5546 for (auto&& codec : video->codecs()) {
5547 if (codec.name == "H264") {
5548 std::string value;
5549 EXPECT_TRUE(
5550 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
5551 }
5552 }
5553 });
5554 caller()->CreateOfferAndWait();
5555}
5556
Harald Alvestrand1a9be302020-12-11 14:53:59 +00005557TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00005558 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00005559 PeerConnectionInterface::RTCConfiguration config;
5560 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5561 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5562 ConnectFakeSignaling();
5563 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
5564
5565 caller()->CreateAndSetAndSignalOffer();
5566 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5567 int current_size = caller()->pc()->GetTransceivers().size();
5568 // Add more tracks until we get close to having issues.
5569 // Issues have been seen at:
5570 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005571 // - 16 tracks on android_arm_dbg (flaky)
5572 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00005573 // Double the number of tracks
5574 for (int i = 0; i < current_size; i++) {
5575 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
5576 }
5577 current_size = caller()->pc()->GetTransceivers().size();
5578 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
5579 auto start_time_ms = rtc::TimeMillis();
5580 caller()->CreateAndSetAndSignalOffer();
5581 // We want to stop when the time exceeds one second.
5582 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5583 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
5584 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
5585 ASSERT_GT(1000, elapsed_time_ms)
5586 << "Audio transceivers: Negotiation took too long after "
5587 << current_size << " tracks added";
5588 }
5589}
5590
5591TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5592 RenegotiateManyVideoTransceivers) {
5593 PeerConnectionInterface::RTCConfiguration config;
5594 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5595 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5596 ConnectFakeSignaling();
5597 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
5598
5599 caller()->CreateAndSetAndSignalOffer();
5600 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5601 int current_size = caller()->pc()->GetTransceivers().size();
5602 // Add more tracks until we get close to having issues.
5603 // Issues have been seen at:
5604 // - 96 on a Linux workstation
5605 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
5606 // - 32 on android_arm64_rel and linux_dbg bots
5607 while (current_size < 16) {
5608 // Double the number of tracks
5609 for (int i = 0; i < current_size; i++) {
5610 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
5611 }
5612 current_size = caller()->pc()->GetTransceivers().size();
5613 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
5614 auto start_time_ms = rtc::TimeMillis();
5615 caller()->CreateAndSetAndSignalOffer();
5616 // We want to stop when the time exceeds one second.
5617 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5618 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
5619 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
5620 ASSERT_GT(1000, elapsed_time_ms)
5621 << "Video transceivers: Negotiation took too long after "
5622 << current_size << " tracks added";
5623 }
5624}
5625
Harald Alvestrand94324f22021-01-13 12:31:53 +00005626TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5627 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
5628 PeerConnectionInterface::RTCConfiguration config;
5629 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5630 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5631 ConnectFakeSignaling();
5632 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005633 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00005634 caller()->CreateAndSetAndSignalOffer();
5635 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5636 // Wait until we can see the audio flowing.
5637 MediaExpectations media_expectations;
5638 media_expectations.CalleeExpectsSomeAudio();
5639 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5640
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005641 // Get the baseline numbers for audio_packets and audio_delay
5642 // in both directions.
5643 caller()->StartWatchingDelayStats();
5644 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00005645
5646 int current_size = caller()->pc()->GetTransceivers().size();
5647 // Add more tracks until we get close to having issues.
5648 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005649 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00005650 // Double the number of tracks
5651 for (int i = 0; i < current_size; i++) {
5652 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
5653 }
5654 current_size = caller()->pc()->GetTransceivers().size();
5655 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
5656 auto start_time_ms = rtc::TimeMillis();
5657 caller()->CreateAndSetAndSignalOffer();
5658 // We want to stop when the time exceeds one second.
5659 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5660 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
5661 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
5662 // This is a guard against the test using excessive amounts of time.
5663 ASSERT_GT(5000, elapsed_time_ms)
5664 << "Video transceivers: Negotiation took too long after "
5665 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005666 caller()->UpdateDelayStats("caller reception", current_size);
5667 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00005668 }
5669}
5670
Mirko Bonadeic84f6612019-01-31 12:20:57 +01005671INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
5672 PeerConnectionIntegrationTest,
5673 Values(SdpSemantics::kPlanB,
5674 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-17 17:41:02 -08005675
Yves Gerey100fe632020-01-17 19:15:53 +01005676INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
5677 PeerConnectionIntegrationTestWithFakeClock,
5678 Values(SdpSemantics::kPlanB,
5679 SdpSemantics::kUnifiedPlan));
5680
Steve Anton74255ff2018-01-24 18:32:57 -08005681// Tests that verify interoperability between Plan B and Unified Plan
5682// PeerConnections.
5683class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08005684 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08005685 public ::testing::WithParamInterface<
5686 std::tuple<SdpSemantics, SdpSemantics>> {
5687 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08005688 // Setting the SdpSemantics for the base test to kDefault does not matter
5689 // because we specify not to use the test semantics when creating
5690 // PeerConnectionWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08005691 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07005692 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08005693 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08005694 callee_semantics_(std::get<1>(GetParam())) {}
5695
5696 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07005697 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
5698 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08005699 }
5700
5701 const SdpSemantics caller_semantics_;
5702 const SdpSemantics callee_semantics_;
5703};
5704
5705TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
5706 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5707 ConnectFakeSignaling();
5708
5709 caller()->CreateAndSetAndSignalOffer();
5710 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5711}
5712
5713TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
5714 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5715 ConnectFakeSignaling();
5716 auto audio_sender = caller()->AddAudioTrack();
5717
5718 caller()->CreateAndSetAndSignalOffer();
5719 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5720
5721 // Verify that one audio receiver has been created on the remote and that it
5722 // has the same track ID as the sending track.
5723 auto receivers = callee()->pc()->GetReceivers();
5724 ASSERT_EQ(1u, receivers.size());
5725 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
5726 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
5727
Seth Hampson2f0d7022018-02-20 11:54:42 -08005728 MediaExpectations media_expectations;
5729 media_expectations.CalleeExpectsSomeAudio();
5730 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005731}
5732
5733TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
5734 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5735 ConnectFakeSignaling();
5736 auto video_sender = caller()->AddVideoTrack();
5737 auto audio_sender = caller()->AddAudioTrack();
5738
5739 caller()->CreateAndSetAndSignalOffer();
5740 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5741
5742 // Verify that one audio and one video receiver have been created on the
5743 // remote and that they have the same track IDs as the sending tracks.
5744 auto audio_receivers =
5745 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
5746 ASSERT_EQ(1u, audio_receivers.size());
5747 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
5748 auto video_receivers =
5749 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
5750 ASSERT_EQ(1u, video_receivers.size());
5751 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
5752
Seth Hampson2f0d7022018-02-20 11:54:42 -08005753 MediaExpectations media_expectations;
5754 media_expectations.CalleeExpectsSomeAudioAndVideo();
5755 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005756}
5757
5758TEST_P(PeerConnectionIntegrationInteropTest,
5759 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
5760 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5761 ConnectFakeSignaling();
5762 caller()->AddAudioVideoTracks();
5763 callee()->AddAudioVideoTracks();
5764
5765 caller()->CreateAndSetAndSignalOffer();
5766 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5767
Seth Hampson2f0d7022018-02-20 11:54:42 -08005768 MediaExpectations media_expectations;
5769 media_expectations.ExpectBidirectionalAudioAndVideo();
5770 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005771}
5772
5773TEST_P(PeerConnectionIntegrationInteropTest,
5774 ReverseRolesOneAudioLocalToOneVideoRemote) {
5775 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5776 ConnectFakeSignaling();
5777 caller()->AddAudioTrack();
5778 callee()->AddVideoTrack();
5779
5780 caller()->CreateAndSetAndSignalOffer();
5781 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5782
5783 // Verify that only the audio track has been negotiated.
5784 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
5785 // Might also check that the callee's NegotiationNeeded flag is set.
5786
5787 // Reverse roles.
5788 callee()->CreateAndSetAndSignalOffer();
5789 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5790
Seth Hampson2f0d7022018-02-20 11:54:42 -08005791 MediaExpectations media_expectations;
5792 media_expectations.CallerExpectsSomeVideo();
5793 media_expectations.CalleeExpectsSomeAudio();
5794 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005795}
5796
Mirko Bonadeic84f6612019-01-31 12:20:57 +01005797INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07005798 PeerConnectionIntegrationTest,
5799 PeerConnectionIntegrationInteropTest,
5800 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
5801 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
5802
5803// Test that if the Unified Plan side offers two video tracks then the Plan B
5804// side will only see the first one and ignore the second.
5805TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07005806 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
5807 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08005808 ConnectFakeSignaling();
5809 auto first_sender = caller()->AddVideoTrack();
5810 caller()->AddVideoTrack();
5811
5812 caller()->CreateAndSetAndSignalOffer();
5813 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5814
5815 // Verify that there is only one receiver and it corresponds to the first
5816 // added track.
5817 auto receivers = callee()->pc()->GetReceivers();
5818 ASSERT_EQ(1u, receivers.size());
5819 EXPECT_TRUE(receivers[0]->track()->enabled());
5820 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
5821
Seth Hampson2f0d7022018-02-20 11:54:42 -08005822 MediaExpectations media_expectations;
5823 media_expectations.CalleeExpectsSomeVideo();
5824 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005825}
5826
Steve Anton2bed3972019-01-04 17:04:30 -08005827// Test that if the initial offer tagged BUNDLE section is rejected due to its
5828// associated RtpTransceiver being stopped and another transceiver is added,
5829// then renegotiation causes the callee to receive the new video track without
5830// error.
5831// This is a regression test for bugs.webrtc.org/9954
5832TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5833 ReOfferWithStoppedBundleTaggedTransceiver) {
5834 RTCConfiguration config;
5835 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
5836 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5837 ConnectFakeSignaling();
5838 auto audio_transceiver_or_error =
5839 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5840 ASSERT_TRUE(audio_transceiver_or_error.ok());
5841 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5842
5843 caller()->CreateAndSetAndSignalOffer();
5844 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5845 {
5846 MediaExpectations media_expectations;
5847 media_expectations.CalleeExpectsSomeAudio();
5848 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5849 }
5850
Harald Alvestrand6060df52020-08-11 09:54:02 +02005851 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08005852 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
5853
5854 caller()->CreateAndSetAndSignalOffer();
5855 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5856 {
5857 MediaExpectations media_expectations;
5858 media_expectations.CalleeExpectsSomeVideo();
5859 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5860 }
5861}
5862
Harald Alvestrandbedb6052020-08-20 14:50:10 +02005863TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5864 StopTransceiverRemovesDtlsTransports) {
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
5876 audio_transceiver->StopStandard();
5877 caller()->CreateAndSetAndSignalOffer();
5878 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5879 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
5880 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
5881 caller()->pc()->ice_gathering_state());
5882 EXPECT_THAT(caller()->ice_gathering_state_history(),
5883 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
5884 PeerConnectionInterface::kIceGatheringComplete,
5885 PeerConnectionInterface::kIceGatheringNew));
5886}
5887
Harald Alvestrand1ee33252020-09-24 13:31:15 +00005888TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00005889 StopTransceiverStopsAndRemovesTransceivers) {
5890 RTCConfiguration config;
5891 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5892 ConnectFakeSignaling();
5893 auto audio_transceiver_or_error =
5894 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5895 ASSERT_TRUE(audio_transceiver_or_error.ok());
5896 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
5897
5898 caller()->CreateAndSetAndSignalOffer();
5899 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5900 caller_transceiver->StopStandard();
5901
5902 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
5903 caller()->CreateAndSetAndSignalOffer();
5904 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5905 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
5906 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
5907 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
5908 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
5909 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
5910 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
5911 EXPECT_TRUE(caller_transceiver->stopped());
5912 EXPECT_TRUE(callee_transceiver->stopped());
5913}
5914
5915TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00005916 StopTransceiverEndsIncomingAudioTrack) {
5917 RTCConfiguration config;
5918 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5919 ConnectFakeSignaling();
5920 auto audio_transceiver_or_error =
5921 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5922 ASSERT_TRUE(audio_transceiver_or_error.ok());
5923 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5924
5925 caller()->CreateAndSetAndSignalOffer();
5926 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5927 auto caller_track = audio_transceiver->receiver()->track();
5928 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
5929 audio_transceiver->StopStandard();
5930 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
5931 caller_track->state());
5932 caller()->CreateAndSetAndSignalOffer();
5933 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5934 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
5935 callee_track->state());
5936}
5937
5938TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5939 StopTransceiverEndsIncomingVideoTrack) {
5940 RTCConfiguration config;
5941 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5942 ConnectFakeSignaling();
5943 auto audio_transceiver_or_error =
5944 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
5945 ASSERT_TRUE(audio_transceiver_or_error.ok());
5946 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5947
5948 caller()->CreateAndSetAndSignalOffer();
5949 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5950 auto caller_track = audio_transceiver->receiver()->track();
5951 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
5952 audio_transceiver->StopStandard();
5953 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
5954 caller_track->state());
5955 caller()->CreateAndSetAndSignalOffer();
5956 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5957 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
5958 callee_track->state());
5959}
5960
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005961#ifdef WEBRTC_HAVE_SCTP
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02005962
5963TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5964 EndToEndCallWithBundledSctpDataChannel) {
5965 ASSERT_TRUE(CreatePeerConnectionWrappers());
5966 ConnectFakeSignaling();
5967 caller()->CreateDataChannel();
5968 caller()->AddAudioVideoTracks();
5969 callee()->AddAudioVideoTracks();
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02005970 caller()->CreateAndSetAndSignalOffer();
5971 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Tomas Gunnarsson6cd40582021-02-08 14:20:08 +01005972 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
5973 ASSERT_EQ_WAIT(SctpTransportState::kConnected,
5974 caller()->pc()->GetSctpTransport()->Information().state(),
5975 kDefaultTimeout);
5976 });
Harald Alvestrand17ea0682019-12-13 11:51:04 +01005977 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
5978 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5979}
5980
5981TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5982 EndToEndCallWithDataChannelOnlyConnects) {
5983 ASSERT_TRUE(CreatePeerConnectionWrappers());
5984 ConnectFakeSignaling();
5985 caller()->CreateDataChannel();
5986 caller()->CreateAndSetAndSignalOffer();
5987 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5988 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
5989 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5990 ASSERT_TRUE(caller()->data_observer()->IsOpen());
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02005991}
5992
Harald Alvestrand2697ac12019-12-16 10:37:04 +01005993TEST_F(PeerConnectionIntegrationTestUnifiedPlan, DataChannelClosesWhenClosed) {
5994 ASSERT_TRUE(CreatePeerConnectionWrappers());
5995 ConnectFakeSignaling();
5996 caller()->CreateDataChannel();
5997 caller()->CreateAndSetAndSignalOffer();
5998 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5999 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
6000 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
6001 caller()->data_channel()->Close();
6002 ASSERT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
6003}
6004
6005TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
6006 DataChannelClosesWhenClosedReverse) {
6007 ASSERT_TRUE(CreatePeerConnectionWrappers());
6008 ConnectFakeSignaling();
6009 caller()->CreateDataChannel();
6010 caller()->CreateAndSetAndSignalOffer();
6011 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
6012 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
6013 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
6014 callee()->data_channel()->Close();
6015 ASSERT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
6016}
6017
6018TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
6019 DataChannelClosesWhenPeerConnectionClosed) {
6020 ASSERT_TRUE(CreatePeerConnectionWrappers());
6021 ConnectFakeSignaling();
6022 caller()->CreateDataChannel();
6023 caller()->CreateAndSetAndSignalOffer();
6024 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
6025 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
6026 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
6027 caller()->pc()->Close();
6028 ASSERT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
6029}
6030
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01006031#endif // WEBRTC_HAVE_SCTP
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02006032
deadbeef1dcb1642017-03-29 21:08:16 -07006033} // namespace
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01006034} // namespace webrtc
deadbeef1dcb1642017-03-29 21:08:16 -07006035
6036#endif // if !defined(THREAD_SANITIZER)