blob: d9a29ec4dbf6b58953fb02b70d2df9f9e9f8ea28 [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
Harald Alvestrand8bf61a32021-02-10 19:19:43 +00002402#ifdef WEBRTC_HAVE_SCTP
2403
2404// This test causes a PeerConnection to enter Disconnected state, and
2405// sends data on a DataChannel while disconnected.
2406// The data should be surfaced when the connection reestablishes.
2407TEST_P(PeerConnectionIntegrationTest, DataChannelWhileDisconnected) {
2408 CreatePeerConnectionWrappers();
2409 ConnectFakeSignaling();
2410 caller()->CreateDataChannel();
2411 caller()->CreateAndSetAndSignalOffer();
2412 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2413 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
2414 std::string data1 = "hello first";
2415 caller()->data_channel()->Send(DataBuffer(data1));
2416 EXPECT_EQ_WAIT(data1, callee()->data_observer()->last_message(),
2417 kDefaultTimeout);
2418 // Cause a network outage
2419 virtual_socket_server()->set_drop_probability(1.0);
2420 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
2421 caller()->standardized_ice_connection_state(),
2422 kDefaultTimeout);
2423 std::string data2 = "hello second";
2424 caller()->data_channel()->Send(DataBuffer(data2));
2425 // Remove the network outage. The connection should reestablish.
2426 virtual_socket_server()->set_drop_probability(0.0);
2427 EXPECT_EQ_WAIT(data2, callee()->data_observer()->last_message(),
2428 kDefaultTimeout);
2429}
2430
2431// This test causes a PeerConnection to enter Disconnected state,
2432// sends data on a DataChannel while disconnected, and then triggers
2433// an ICE restart.
2434// The data should be surfaced when the connection reestablishes.
2435TEST_P(PeerConnectionIntegrationTest, DataChannelWhileDisconnectedIceRestart) {
2436 CreatePeerConnectionWrappers();
2437 ConnectFakeSignaling();
2438 caller()->CreateDataChannel();
2439 caller()->CreateAndSetAndSignalOffer();
2440 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2441 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
2442 std::string data1 = "hello first";
2443 caller()->data_channel()->Send(DataBuffer(data1));
2444 EXPECT_EQ_WAIT(data1, callee()->data_observer()->last_message(),
2445 kDefaultTimeout);
2446 // Cause a network outage
2447 virtual_socket_server()->set_drop_probability(1.0);
2448 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
2449 caller()->standardized_ice_connection_state(),
2450 kDefaultTimeout);
2451 std::string data2 = "hello second";
2452 caller()->data_channel()->Send(DataBuffer(data2));
2453
2454 // Trigger an ICE restart. The signaling channel is not affected by
2455 // the network outage.
2456 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2457 caller()->CreateAndSetAndSignalOffer();
2458 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2459 // Remove the network outage. The connection should reestablish.
2460 virtual_socket_server()->set_drop_probability(0.0);
2461 EXPECT_EQ_WAIT(data2, callee()->data_observer()->last_message(),
2462 kDefaultTimeout);
2463}
2464
2465#endif // WEBRTC_HAVE_SCTP
2466
deadbeef1dcb1642017-03-29 21:08:16 -07002467// This test sets up a non-bundled call and negotiates bundling at the same
2468// time as starting an ICE restart. When bundling is in effect in the restart,
2469// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002470TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -07002471 ASSERT_TRUE(CreatePeerConnectionWrappers());
2472 ConnectFakeSignaling();
2473
Steve Anton15324772018-01-16 10:26:49 -08002474 caller()->AddAudioVideoTracks();
2475 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002476 // Remove the bundle group from the SDP received by the callee.
2477 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2478 desc->RemoveGroupByName("BUNDLE");
2479 });
2480 caller()->CreateAndSetAndSignalOffer();
2481 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002482 {
2483 MediaExpectations media_expectations;
2484 media_expectations.ExpectBidirectionalAudioAndVideo();
2485 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2486 }
deadbeef1dcb1642017-03-29 21:08:16 -07002487 // Now stop removing the BUNDLE group, and trigger an ICE restart.
2488 callee()->SetReceivedSdpMunger(nullptr);
2489 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2490 caller()->CreateAndSetAndSignalOffer();
2491 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2492
2493 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002494 {
2495 MediaExpectations media_expectations;
2496 media_expectations.ExpectBidirectionalAudioAndVideo();
2497 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2498 }
deadbeef1dcb1642017-03-29 21:08:16 -07002499}
2500
2501// Test CVO (Coordination of Video Orientation). If a video source is rotated
2502// and both peers support the CVO RTP header extension, the actual video frames
2503// don't need to be encoded in different resolutions, since the rotation is
2504// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002505TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002506 ASSERT_TRUE(CreatePeerConnectionWrappers());
2507 ConnectFakeSignaling();
2508 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002509 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002510 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002511 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002512 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2513
2514 // Wait for video frames to be received by both sides.
2515 caller()->CreateAndSetAndSignalOffer();
2516 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2517 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2518 callee()->min_video_frames_received_per_track() > 0,
2519 kMaxWaitForFramesMs);
2520
2521 // Ensure that the aspect ratio is unmodified.
2522 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2523 // not just assumed.
2524 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
2525 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
2526 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
2527 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
2528 // Ensure that the CVO bits were surfaced to the renderer.
2529 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
2530 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
2531}
2532
2533// Test that when the CVO extension isn't supported, video is rotated the
2534// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002535TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002536 ASSERT_TRUE(CreatePeerConnectionWrappers());
2537 ConnectFakeSignaling();
2538 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002539 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002540 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002541 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002542 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2543
2544 // Remove the CVO extension from the offered SDP.
2545 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2546 cricket::VideoContentDescription* video =
2547 GetFirstVideoContentDescription(desc);
2548 video->ClearRtpHeaderExtensions();
2549 });
2550 // Wait for video frames to be received by both sides.
2551 caller()->CreateAndSetAndSignalOffer();
2552 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2553 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2554 callee()->min_video_frames_received_per_track() > 0,
2555 kMaxWaitForFramesMs);
2556
2557 // Expect that the aspect ratio is inversed to account for the 90/270 degree
2558 // rotation.
2559 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2560 // not just assumed.
2561 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
2562 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
2563 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
2564 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
2565 // Expect that each endpoint is unaware of the rotation of the other endpoint.
2566 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
2567 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
2568}
2569
deadbeef1dcb1642017-03-29 21:08:16 -07002570// Test that if the answerer rejects the audio m= section, no audio is sent or
2571// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002572TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002573 ASSERT_TRUE(CreatePeerConnectionWrappers());
2574 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002575 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002576 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2577 // Only add video track for callee, and set offer_to_receive_audio to 0, so
2578 // it will reject the audio m= section completely.
2579 PeerConnectionInterface::RTCOfferAnswerOptions options;
2580 options.offer_to_receive_audio = 0;
2581 callee()->SetOfferAnswerOptions(options);
2582 } else {
2583 // Stopping the audio RtpTransceiver will cause the media section to be
2584 // rejected in the answer.
2585 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002586 callee()
2587 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
2588 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002589 });
2590 }
Steve Anton15324772018-01-16 10:26:49 -08002591 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002592 // Do offer/answer and wait for successful end-to-end video frames.
2593 caller()->CreateAndSetAndSignalOffer();
2594 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002595 MediaExpectations media_expectations;
2596 media_expectations.ExpectBidirectionalVideo();
2597 media_expectations.ExpectNoAudio();
2598 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2599
deadbeef1dcb1642017-03-29 21:08:16 -07002600 // Sanity check that the callee's description has a rejected audio section.
2601 ASSERT_NE(nullptr, callee()->pc()->local_description());
2602 const ContentInfo* callee_audio_content =
2603 GetFirstAudioContent(callee()->pc()->local_description()->description());
2604 ASSERT_NE(nullptr, callee_audio_content);
2605 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002606 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002607 // The caller's transceiver should have stopped after receiving the answer,
2608 // and thus no longer listed in transceivers.
2609 EXPECT_EQ(nullptr,
2610 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002611 }
deadbeef1dcb1642017-03-29 21:08:16 -07002612}
2613
2614// Test that if the answerer rejects the video m= section, no video is sent or
2615// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002616TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002617 ASSERT_TRUE(CreatePeerConnectionWrappers());
2618 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002619 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002620 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2621 // Only add audio track for callee, and set offer_to_receive_video to 0, so
2622 // it will reject the video m= section completely.
2623 PeerConnectionInterface::RTCOfferAnswerOptions options;
2624 options.offer_to_receive_video = 0;
2625 callee()->SetOfferAnswerOptions(options);
2626 } else {
2627 // Stopping the video RtpTransceiver will cause the media section to be
2628 // rejected in the answer.
2629 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002630 callee()
2631 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2632 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002633 });
2634 }
Steve Anton15324772018-01-16 10:26:49 -08002635 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002636 // Do offer/answer and wait for successful end-to-end audio frames.
2637 caller()->CreateAndSetAndSignalOffer();
2638 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002639 MediaExpectations media_expectations;
2640 media_expectations.ExpectBidirectionalAudio();
2641 media_expectations.ExpectNoVideo();
2642 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2643
deadbeef1dcb1642017-03-29 21:08:16 -07002644 // Sanity check that the callee's description has a rejected video section.
2645 ASSERT_NE(nullptr, callee()->pc()->local_description());
2646 const ContentInfo* callee_video_content =
2647 GetFirstVideoContent(callee()->pc()->local_description()->description());
2648 ASSERT_NE(nullptr, callee_video_content);
2649 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002650 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002651 // The caller's transceiver should have stopped after receiving the answer,
2652 // and thus is no longer present.
2653 EXPECT_EQ(nullptr,
2654 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002655 }
deadbeef1dcb1642017-03-29 21:08:16 -07002656}
2657
2658// Test that if the answerer rejects both audio and video m= sections, nothing
2659// bad happens.
2660// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
2661// test anything but the fact that negotiation succeeds, which doesn't mean
2662// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002663TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -07002664 ASSERT_TRUE(CreatePeerConnectionWrappers());
2665 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002666 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002667 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2668 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
2669 // will reject both audio and video m= sections.
2670 PeerConnectionInterface::RTCOfferAnswerOptions options;
2671 options.offer_to_receive_audio = 0;
2672 options.offer_to_receive_video = 0;
2673 callee()->SetOfferAnswerOptions(options);
2674 } else {
2675 callee()->SetRemoteOfferHandler([this] {
2676 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +01002677 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002678 transceiver->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002679 }
2680 });
2681 }
deadbeef1dcb1642017-03-29 21:08:16 -07002682 // Do offer/answer and wait for stable signaling state.
2683 caller()->CreateAndSetAndSignalOffer();
2684 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002685
deadbeef1dcb1642017-03-29 21:08:16 -07002686 // Sanity check that the callee's description has rejected m= sections.
2687 ASSERT_NE(nullptr, callee()->pc()->local_description());
2688 const ContentInfo* callee_audio_content =
2689 GetFirstAudioContent(callee()->pc()->local_description()->description());
2690 ASSERT_NE(nullptr, callee_audio_content);
2691 EXPECT_TRUE(callee_audio_content->rejected);
2692 const ContentInfo* callee_video_content =
2693 GetFirstVideoContent(callee()->pc()->local_description()->description());
2694 ASSERT_NE(nullptr, callee_video_content);
2695 EXPECT_TRUE(callee_video_content->rejected);
2696}
2697
2698// This test sets up an audio and video call between two parties. After the
2699// call runs for a while, the caller sends an updated offer with video being
2700// rejected. Once the re-negotiation is done, the video flow should stop and
2701// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002702TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07002703 ASSERT_TRUE(CreatePeerConnectionWrappers());
2704 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002705 caller()->AddAudioVideoTracks();
2706 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002707 caller()->CreateAndSetAndSignalOffer();
2708 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002709 {
2710 MediaExpectations media_expectations;
2711 media_expectations.ExpectBidirectionalAudioAndVideo();
2712 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2713 }
deadbeef1dcb1642017-03-29 21:08:16 -07002714 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002715 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2716 caller()->SetGeneratedSdpMunger(
2717 [](cricket::SessionDescription* description) {
2718 for (cricket::ContentInfo& content : description->contents()) {
2719 if (cricket::IsVideoContent(&content)) {
2720 content.rejected = true;
2721 }
2722 }
2723 });
2724 } else {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002725 caller()
2726 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2727 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002728 }
deadbeef1dcb1642017-03-29 21:08:16 -07002729 caller()->CreateAndSetAndSignalOffer();
2730 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2731
2732 // Sanity check that the caller's description has a rejected video section.
2733 ASSERT_NE(nullptr, caller()->pc()->local_description());
2734 const ContentInfo* caller_video_content =
2735 GetFirstVideoContent(caller()->pc()->local_description()->description());
2736 ASSERT_NE(nullptr, caller_video_content);
2737 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -07002738 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002739 {
2740 MediaExpectations media_expectations;
2741 media_expectations.ExpectBidirectionalAudio();
2742 media_expectations.ExpectNoVideo();
2743 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2744 }
deadbeef1dcb1642017-03-29 21:08:16 -07002745}
2746
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -07002747// Do one offer/answer with audio, another that disables it (rejecting the m=
2748// section), and another that re-enables it. Regression test for:
2749// bugs.webrtc.org/6023
2750TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
2751 ASSERT_TRUE(CreatePeerConnectionWrappers());
2752 ConnectFakeSignaling();
2753
2754 // Add audio track, do normal offer/answer.
2755 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2756 caller()->CreateLocalAudioTrack();
2757 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2758 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2759 caller()->CreateAndSetAndSignalOffer();
2760 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2761
2762 // Remove audio track, and set offer_to_receive_audio to false to cause the
2763 // m= section to be completely disabled, not just "recvonly".
2764 caller()->pc()->RemoveTrack(sender);
2765 PeerConnectionInterface::RTCOfferAnswerOptions options;
2766 options.offer_to_receive_audio = 0;
2767 caller()->SetOfferAnswerOptions(options);
2768 caller()->CreateAndSetAndSignalOffer();
2769 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2770
2771 // Add the audio track again, expecting negotiation to succeed and frames to
2772 // flow.
2773 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2774 options.offer_to_receive_audio = 1;
2775 caller()->SetOfferAnswerOptions(options);
2776 caller()->CreateAndSetAndSignalOffer();
2777 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2778
2779 MediaExpectations media_expectations;
2780 media_expectations.CalleeExpectsSomeAudio();
2781 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2782}
2783
deadbeef1dcb1642017-03-29 21:08:16 -07002784// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
2785// is needed to support legacy endpoints.
2786// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
2787// add a test for an end-to-end test without MID signaling either (basically,
2788// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002789TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -07002790 ASSERT_TRUE(CreatePeerConnectionWrappers());
2791 ConnectFakeSignaling();
2792 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08002793 caller()->AddAudioVideoTracks();
2794 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07002795 // Remove SSRCs and MSIDs from the received offer SDP.
2796 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07002797 caller()->CreateAndSetAndSignalOffer();
2798 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002799 MediaExpectations media_expectations;
2800 media_expectations.ExpectBidirectionalAudioAndVideo();
2801 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002802}
2803
Seth Hampson5897a6e2018-04-03 11:16:33 -07002804// Basic end-to-end test, without SSRC signaling. This means that the track
2805// was created properly and frames are delivered when the MSIDs are communicated
2806// with a=msid lines and no a=ssrc lines.
2807TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2808 EndToEndCallWithoutSsrcSignaling) {
2809 const char kStreamId[] = "streamId";
2810 ASSERT_TRUE(CreatePeerConnectionWrappers());
2811 ConnectFakeSignaling();
2812 // Add just audio tracks.
2813 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
2814 callee()->AddAudioTrack();
2815
2816 // Remove SSRCs from the received offer SDP.
2817 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
2818 caller()->CreateAndSetAndSignalOffer();
2819 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2820 MediaExpectations media_expectations;
2821 media_expectations.ExpectBidirectionalAudio();
2822 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2823}
2824
Johannes Kron3e983682020-03-29 22:17:00 +02002825TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2826 EndToEndCallAddReceiveVideoToSendOnlyCall) {
2827 ASSERT_TRUE(CreatePeerConnectionWrappers());
2828 ConnectFakeSignaling();
2829 // Add one-directional video, from caller to callee.
2830 rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
2831 caller()->CreateLocalVideoTrack();
2832
2833 RtpTransceiverInit video_transceiver_init;
2834 video_transceiver_init.stream_ids = {"video1"};
2835 video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly;
2836 auto video_sender =
2837 caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue();
2838 caller()->CreateAndSetAndSignalOffer();
2839 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2840
2841 // Add receive direction.
Harald Alvestrand6060df52020-08-11 09:54:02 +02002842 video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);
Johannes Kron3e983682020-03-29 22:17:00 +02002843
2844 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2845 callee()->CreateLocalVideoTrack();
2846
2847 callee()->AddTrack(callee_track);
2848 caller()->CreateAndSetAndSignalOffer();
2849 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2850 // Ensure that video frames are received end-to-end.
2851 MediaExpectations media_expectations;
2852 media_expectations.ExpectBidirectionalVideo();
2853 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2854}
2855
Steve Antondf527fd2018-04-27 15:52:03 -07002856// Tests that video flows between multiple video tracks when SSRCs are not
2857// signaled. This exercises the MID RTP header extension which is needed to
2858// demux the incoming video tracks.
2859TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2860 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
2861 ASSERT_TRUE(CreatePeerConnectionWrappers());
2862 ConnectFakeSignaling();
2863 caller()->AddVideoTrack();
2864 caller()->AddVideoTrack();
2865 callee()->AddVideoTrack();
2866 callee()->AddVideoTrack();
2867
2868 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2869 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2870 caller()->CreateAndSetAndSignalOffer();
2871 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2872 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2873 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2874
2875 // Expect video to be received in both directions on both tracks.
2876 MediaExpectations media_expectations;
2877 media_expectations.ExpectBidirectionalVideo();
2878 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2879}
2880
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -07002881// Used for the test below.
2882void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
2883 RemoveSsrcsAndKeepMsids(desc);
2884 desc->RemoveGroupByName("BUNDLE");
2885 for (ContentInfo& content : desc->contents()) {
2886 cricket::MediaContentDescription* media = content.media_description();
2887 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
2888 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
2889 [](const RtpExtension& extension) {
2890 return extension.uri ==
2891 RtpExtension::kMidUri;
2892 }),
2893 extensions.end());
2894 media->set_rtp_header_extensions(extensions);
2895 }
2896}
2897
2898// Tests that video flows between multiple video tracks when BUNDLE is not used,
2899// SSRCs are not signaled and the MID RTP header extension is not used. This
2900// relies on demuxing by payload type, which normally doesn't work if you have
2901// multiple media sections using the same payload type, but which should work as
2902// long as the media sections aren't bundled.
2903// Regression test for: http://crbug.com/webrtc/12023
2904TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2905 EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid) {
2906 ASSERT_TRUE(CreatePeerConnectionWrappers());
2907 ConnectFakeSignaling();
2908 caller()->AddVideoTrack();
2909 caller()->AddVideoTrack();
2910 callee()->AddVideoTrack();
2911 callee()->AddVideoTrack();
2912 caller()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
2913 callee()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
2914 caller()->CreateAndSetAndSignalOffer();
2915 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2916 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2917 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2918 // Make sure we are not bundled.
2919 ASSERT_NE(caller()->pc()->GetSenders()[0]->dtls_transport(),
2920 caller()->pc()->GetSenders()[1]->dtls_transport());
2921
2922 // Expect video to be received in both directions on both tracks.
2923 MediaExpectations media_expectations;
2924 media_expectations.ExpectBidirectionalVideo();
2925 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2926}
2927
2928// Used for the test below.
2929void ModifyPayloadTypesAndRemoveMidExtension(
2930 cricket::SessionDescription* desc) {
2931 int pt = 96;
2932 for (ContentInfo& content : desc->contents()) {
2933 cricket::MediaContentDescription* media = content.media_description();
2934 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
2935 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
2936 [](const RtpExtension& extension) {
2937 return extension.uri ==
2938 RtpExtension::kMidUri;
2939 }),
2940 extensions.end());
2941 media->set_rtp_header_extensions(extensions);
2942 cricket::VideoContentDescription* video = media->as_video();
2943 ASSERT_TRUE(video != nullptr);
2944 std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
2945 video->set_codecs(codecs);
2946 }
2947}
2948
2949// Tests that two video tracks can be demultiplexed by payload type alone, by
2950// using different payload types for the same codec in different m= sections.
2951// This practice is discouraged but historically has been supported.
2952// Regression test for: http://crbug.com/webrtc/12029
2953TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2954 EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType) {
2955 ASSERT_TRUE(CreatePeerConnectionWrappers());
2956 ConnectFakeSignaling();
2957 caller()->AddVideoTrack();
2958 caller()->AddVideoTrack();
2959 callee()->AddVideoTrack();
2960 callee()->AddVideoTrack();
2961 caller()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
2962 callee()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
2963 // We can't remove SSRCs from the generated SDP because then no send streams
2964 // would be created.
2965 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2966 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2967 caller()->CreateAndSetAndSignalOffer();
2968 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2969 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2970 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2971 // Make sure we are bundled.
2972 ASSERT_EQ(caller()->pc()->GetSenders()[0]->dtls_transport(),
2973 caller()->pc()->GetSenders()[1]->dtls_transport());
2974
2975 // Expect video to be received in both directions on both tracks.
2976 MediaExpectations media_expectations;
2977 media_expectations.ExpectBidirectionalVideo();
2978 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2979}
2980
Henrik Boström5b147782018-12-04 11:25:05 +01002981TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
2982 ASSERT_TRUE(CreatePeerConnectionWrappers());
2983 ConnectFakeSignaling();
2984 caller()->AddAudioTrack();
2985 caller()->AddVideoTrack();
2986 caller()->CreateAndSetAndSignalOffer();
2987 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2988 auto callee_receivers = callee()->pc()->GetReceivers();
2989 ASSERT_EQ(2u, callee_receivers.size());
2990 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
2991 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
2992}
2993
2994TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
2995 ASSERT_TRUE(CreatePeerConnectionWrappers());
2996 ConnectFakeSignaling();
2997 caller()->AddAudioTrack();
2998 caller()->AddVideoTrack();
2999 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3000 caller()->CreateAndSetAndSignalOffer();
3001 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3002 auto callee_receivers = callee()->pc()->GetReceivers();
3003 ASSERT_EQ(2u, callee_receivers.size());
3004 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
3005 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
3006 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
3007 callee_receivers[1]->stream_ids()[0]);
3008 EXPECT_EQ(callee_receivers[0]->streams()[0],
3009 callee_receivers[1]->streams()[0]);
3010}
3011
deadbeef1dcb1642017-03-29 21:08:16 -07003012// Test that if two video tracks are sent (from caller to callee, in this test),
3013// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003014TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07003015 ASSERT_TRUE(CreatePeerConnectionWrappers());
3016 ConnectFakeSignaling();
3017 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08003018 caller()->AddAudioVideoTracks();
3019 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07003020 caller()->CreateAndSetAndSignalOffer();
3021 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08003022 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08003023
3024 MediaExpectations media_expectations;
3025 media_expectations.CalleeExpectsSomeAudioAndVideo();
3026 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003027}
3028
3029static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
3030 bool first = true;
3031 for (cricket::ContentInfo& content : desc->contents()) {
3032 if (first) {
3033 first = false;
3034 continue;
3035 }
3036 content.bundle_only = true;
3037 }
3038 first = true;
3039 for (cricket::TransportInfo& transport : desc->transport_infos()) {
3040 if (first) {
3041 first = false;
3042 continue;
3043 }
3044 transport.description.ice_ufrag.clear();
3045 transport.description.ice_pwd.clear();
3046 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
3047 transport.description.identity_fingerprint.reset(nullptr);
3048 }
3049}
3050
3051// Test that if applying a true "max bundle" offer, which uses ports of 0,
3052// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
3053// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
3054// successfully and media flows.
3055// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
3056// TODO(deadbeef): Won't need this test once we start generating actual
3057// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003058TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003059 EndToEndCallWithSpecCompliantMaxBundleOffer) {
3060 ASSERT_TRUE(CreatePeerConnectionWrappers());
3061 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003062 caller()->AddAudioVideoTracks();
3063 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003064 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
3065 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
3066 // but the first m= section.
3067 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
3068 caller()->CreateAndSetAndSignalOffer();
3069 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003070 MediaExpectations media_expectations;
3071 media_expectations.ExpectBidirectionalAudioAndVideo();
3072 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003073}
3074
3075// Test that we can receive the audio output level from a remote audio track.
3076// TODO(deadbeef): Use a fake audio source and verify that the output level is
3077// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003078TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07003079 ASSERT_TRUE(CreatePeerConnectionWrappers());
3080 ConnectFakeSignaling();
3081 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08003082 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07003083 caller()->CreateAndSetAndSignalOffer();
3084 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3085
3086 // Get the audio output level stats. Note that the level is not available
3087 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07003088 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07003089 kMaxWaitForFramesMs);
3090}
3091
3092// Test that an audio input level is reported.
3093// TODO(deadbeef): Use a fake audio source and verify that the input level is
3094// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003095TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07003096 ASSERT_TRUE(CreatePeerConnectionWrappers());
3097 ConnectFakeSignaling();
3098 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08003099 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07003100 caller()->CreateAndSetAndSignalOffer();
3101 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3102
3103 // Get the audio input level stats. The level should be available very
3104 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07003105 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07003106 kMaxWaitForStatsMs);
3107}
3108
3109// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003110TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07003111 ASSERT_TRUE(CreatePeerConnectionWrappers());
3112 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003113 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003114 // Do offer/answer, wait for the callee to receive some frames.
3115 caller()->CreateAndSetAndSignalOffer();
3116 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003117
3118 MediaExpectations media_expectations;
3119 media_expectations.CalleeExpectsSomeAudioAndVideo();
3120 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003121
3122 // Get a handle to the remote tracks created, so they can be used as GetStats
3123 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01003124 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08003125 // We received frames, so we definitely should have nonzero "received bytes"
3126 // stats at this point.
3127 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
3128 0);
3129 }
deadbeef1dcb1642017-03-29 21:08:16 -07003130}
3131
3132// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003133TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07003134 ASSERT_TRUE(CreatePeerConnectionWrappers());
3135 ConnectFakeSignaling();
3136 auto audio_track = caller()->CreateLocalAudioTrack();
3137 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08003138 caller()->AddTrack(audio_track);
3139 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07003140 // Do offer/answer, wait for the callee to receive some frames.
3141 caller()->CreateAndSetAndSignalOffer();
3142 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003143 MediaExpectations media_expectations;
3144 media_expectations.CalleeExpectsSomeAudioAndVideo();
3145 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003146
3147 // The callee received frames, so we definitely should have nonzero "sent
3148 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07003149 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
3150 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
3151}
3152
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003153// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003154TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003155 ASSERT_TRUE(CreatePeerConnectionWrappers());
3156 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003157 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003158
Steve Anton15324772018-01-16 10:26:49 -08003159 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003160
3161 // Do offer/answer, wait for the callee to receive some frames.
3162 caller()->CreateAndSetAndSignalOffer();
3163 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3164
3165 // Get the remote audio track created on the receiver, so they can be used as
3166 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08003167 auto receivers = callee()->pc()->GetReceivers();
3168 ASSERT_EQ(1u, receivers.size());
3169 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003170
3171 // Get the audio output level stats. Note that the level is not available
3172 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07003173 EXPECT_TRUE_WAIT(
3174 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
3175 0,
3176 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003177}
3178
Steve Antona41959e2018-11-28 11:15:33 -08003179// Test that the track ID is associated with all local and remote SSRC stats
3180// using the old GetStats() and more than 1 audio and more than 1 video track.
3181// This is a regression test for crbug.com/906988
3182TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3183 OldGetStatsAssociatesTrackIdForManyMediaSections) {
3184 ASSERT_TRUE(CreatePeerConnectionWrappers());
3185 ConnectFakeSignaling();
3186 auto audio_sender_1 = caller()->AddAudioTrack();
3187 auto video_sender_1 = caller()->AddVideoTrack();
3188 auto audio_sender_2 = caller()->AddAudioTrack();
3189 auto video_sender_2 = caller()->AddVideoTrack();
3190 caller()->CreateAndSetAndSignalOffer();
3191 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3192
3193 MediaExpectations media_expectations;
3194 media_expectations.CalleeExpectsSomeAudioAndVideo();
3195 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
3196
3197 std::vector<std::string> track_ids = {
3198 audio_sender_1->track()->id(), video_sender_1->track()->id(),
3199 audio_sender_2->track()->id(), video_sender_2->track()->id()};
3200
3201 auto caller_stats = caller()->OldGetStats();
3202 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
3203 auto callee_stats = callee()->OldGetStats();
3204 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
3205}
3206
Steve Antonffa6ce42018-11-30 09:26:08 -08003207// Test that the new GetStats() returns stats for all outgoing/incoming streams
3208// with the correct track IDs if there are more than one audio and more than one
3209// video senders/receivers.
3210TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
3211 ASSERT_TRUE(CreatePeerConnectionWrappers());
3212 ConnectFakeSignaling();
3213 auto audio_sender_1 = caller()->AddAudioTrack();
3214 auto video_sender_1 = caller()->AddVideoTrack();
3215 auto audio_sender_2 = caller()->AddAudioTrack();
3216 auto video_sender_2 = caller()->AddVideoTrack();
3217 caller()->CreateAndSetAndSignalOffer();
3218 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3219
3220 MediaExpectations media_expectations;
3221 media_expectations.CalleeExpectsSomeAudioAndVideo();
3222 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
3223
3224 std::vector<std::string> track_ids = {
3225 audio_sender_1->track()->id(), video_sender_1->track()->id(),
3226 audio_sender_2->track()->id(), video_sender_2->track()->id()};
3227
3228 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
3229 caller()->NewGetStats();
3230 ASSERT_TRUE(caller_report);
3231 auto outbound_stream_stats =
3232 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
Henrik Boströma0ff50c2020-05-05 15:54:46 +02003233 ASSERT_EQ(outbound_stream_stats.size(), 4u);
Steve Antonffa6ce42018-11-30 09:26:08 -08003234 std::vector<std::string> outbound_track_ids;
3235 for (const auto& stat : outbound_stream_stats) {
3236 ASSERT_TRUE(stat->bytes_sent.is_defined());
3237 EXPECT_LT(0u, *stat->bytes_sent);
Rasmus Brandt2efae772019-06-27 14:29:34 +02003238 if (*stat->kind == "video") {
3239 ASSERT_TRUE(stat->key_frames_encoded.is_defined());
3240 EXPECT_GT(*stat->key_frames_encoded, 0u);
3241 ASSERT_TRUE(stat->frames_encoded.is_defined());
3242 EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
3243 }
Steve Antonffa6ce42018-11-30 09:26:08 -08003244 ASSERT_TRUE(stat->track_id.is_defined());
3245 const auto* track_stat =
3246 caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
3247 ASSERT_TRUE(track_stat);
3248 outbound_track_ids.push_back(*track_stat->track_identifier);
3249 }
3250 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
3251
3252 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
3253 callee()->NewGetStats();
3254 ASSERT_TRUE(callee_report);
3255 auto inbound_stream_stats =
3256 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
3257 ASSERT_EQ(4u, inbound_stream_stats.size());
3258 std::vector<std::string> inbound_track_ids;
3259 for (const auto& stat : inbound_stream_stats) {
3260 ASSERT_TRUE(stat->bytes_received.is_defined());
3261 EXPECT_LT(0u, *stat->bytes_received);
Rasmus Brandt2efae772019-06-27 14:29:34 +02003262 if (*stat->kind == "video") {
3263 ASSERT_TRUE(stat->key_frames_decoded.is_defined());
3264 EXPECT_GT(*stat->key_frames_decoded, 0u);
3265 ASSERT_TRUE(stat->frames_decoded.is_defined());
3266 EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
3267 }
Steve Antonffa6ce42018-11-30 09:26:08 -08003268 ASSERT_TRUE(stat->track_id.is_defined());
3269 const auto* track_stat =
3270 callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
3271 ASSERT_TRUE(track_stat);
3272 inbound_track_ids.push_back(*track_stat->track_identifier);
3273 }
3274 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
3275}
3276
3277// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07003278// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
3279// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003280TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07003281 GetStatsForUnsignaledStreamWithNewStatsApi) {
3282 ASSERT_TRUE(CreatePeerConnectionWrappers());
3283 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003284 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07003285 // Remove SSRCs and MSIDs from the received offer SDP.
3286 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3287 caller()->CreateAndSetAndSignalOffer();
3288 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003289 MediaExpectations media_expectations;
3290 media_expectations.CalleeExpectsSomeAudio(1);
3291 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07003292
3293 // We received a frame, so we should have nonzero "bytes received" stats for
3294 // the unsignaled stream, if stats are working for it.
3295 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
3296 callee()->NewGetStats();
3297 ASSERT_NE(nullptr, report);
3298 auto inbound_stream_stats =
3299 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
3300 ASSERT_EQ(1U, inbound_stream_stats.size());
3301 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
3302 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07003303 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
3304}
3305
Taylor Brandstettera4653442018-06-19 09:44:26 -07003306// Same as above but for the legacy stats implementation.
3307TEST_P(PeerConnectionIntegrationTest,
3308 GetStatsForUnsignaledStreamWithOldStatsApi) {
3309 ASSERT_TRUE(CreatePeerConnectionWrappers());
3310 ConnectFakeSignaling();
3311 caller()->AddAudioTrack();
3312 // Remove SSRCs and MSIDs from the received offer SDP.
3313 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3314 caller()->CreateAndSetAndSignalOffer();
3315 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3316
3317 // Note that, since the old stats implementation associates SSRCs with tracks
3318 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
3319 // associated track ID. So we can't use the track "selector" argument.
3320 //
3321 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
3322 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003323 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07003324 kDefaultTimeout);
3325}
3326
zhihuangf8164932017-05-19 13:09:47 -07003327// Test that we can successfully get the media related stats (audio level
3328// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003329TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07003330 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
3331 ASSERT_TRUE(CreatePeerConnectionWrappers());
3332 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003333 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07003334 // Remove SSRCs and MSIDs from the received offer SDP.
3335 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3336 caller()->CreateAndSetAndSignalOffer();
3337 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003338 MediaExpectations media_expectations;
3339 media_expectations.CalleeExpectsSomeAudio(1);
3340 media_expectations.CalleeExpectsSomeVideo(1);
3341 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07003342
3343 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
3344 callee()->NewGetStats();
3345 ASSERT_NE(nullptr, report);
3346
3347 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3348 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
3349 ASSERT_GE(audio_index, 0);
3350 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07003351}
3352
deadbeef4e2deab2017-09-20 13:56:21 -07003353// Helper for test below.
3354void ModifySsrcs(cricket::SessionDescription* desc) {
3355 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07003356 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08003357 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07003358 for (uint32_t& ssrc : stream.ssrcs) {
3359 ssrc = rtc::CreateRandomId();
3360 }
3361 }
3362 }
3363}
3364
3365// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
3366// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
3367// This should result in two "RTCInboundRTPStreamStats", but only one
3368// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
3369// being reset to 0 once the SSRC change occurs.
3370//
3371// Regression test for this bug:
3372// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
3373//
3374// The bug causes the track stats to only represent one of the two streams:
3375// whichever one has the higher SSRC. So with this bug, there was a 50% chance
3376// that the track stat counters would reset to 0 when the new stream is
3377// received, and a 50% chance that they'll stop updating (while
3378// "concealed_samples" continues increasing, due to silence being generated for
3379// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003380TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08003381 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07003382 ASSERT_TRUE(CreatePeerConnectionWrappers());
3383 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003384 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07003385 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
3386 // that doesn't signal SSRCs (from the callee's perspective).
3387 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3388 caller()->CreateAndSetAndSignalOffer();
3389 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3390 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003391 {
3392 MediaExpectations media_expectations;
3393 media_expectations.CalleeExpectsSomeAudio(50);
3394 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3395 }
deadbeef4e2deab2017-09-20 13:56:21 -07003396 // Some audio frames were received, so we should have nonzero "samples
3397 // received" for the track.
3398 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
3399 callee()->NewGetStats();
3400 ASSERT_NE(nullptr, report);
3401 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3402 ASSERT_EQ(1U, track_stats.size());
3403 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
3404 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
3405 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
3406
3407 // Create a new offer and munge it to cause the caller to use a new SSRC.
3408 caller()->SetGeneratedSdpMunger(ModifySsrcs);
3409 caller()->CreateAndSetAndSignalOffer();
3410 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3411 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
3412 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003413 {
3414 MediaExpectations media_expectations;
3415 media_expectations.CalleeExpectsSomeAudio(25);
3416 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3417 }
deadbeef4e2deab2017-09-20 13:56:21 -07003418
3419 report = callee()->NewGetStats();
3420 ASSERT_NE(nullptr, report);
3421 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3422 ASSERT_EQ(1U, track_stats.size());
3423 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
3424 // The "total samples received" stat should only be greater than it was
3425 // before.
3426 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
3427 // Right now, the new SSRC will cause the counters to reset to 0.
3428 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
3429
3430 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08003431 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07003432 // good sign that we're seeing stats from the old stream that's no longer
3433 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08003434 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07003435 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
3436 EXPECT_LT(*track_stats[0]->concealed_samples,
3437 *track_stats[0]->total_samples_received *
3438 kAcceptableConcealedSamplesPercentage);
3439
3440 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
3441 // sanity check that the SSRC really changed.
3442 // TODO(deadbeef): This isn't working right now, because we're not returning
3443 // *any* stats for the inactive stream. Uncomment when the bug is completely
3444 // fixed.
3445 // auto inbound_stream_stats =
3446 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
3447 // ASSERT_EQ(2U, inbound_stream_stats.size());
3448}
3449
deadbeef1dcb1642017-03-29 21:08:16 -07003450// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003451TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07003452 PeerConnectionFactory::Options dtls_10_options;
3453 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3454 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
3455 dtls_10_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 getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003469TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07003470 PeerConnectionFactory::Options dtls_10_options;
3471 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3472 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
3473 dtls_10_options));
3474 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003475 caller()->AddAudioVideoTracks();
3476 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003477 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003478 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07003479 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07003480 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07003481 kDefaultTimeout);
3482 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07003483 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003484 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01003485 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
3486 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
3487 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07003488}
3489
3490// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003491TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07003492 PeerConnectionFactory::Options dtls_12_options;
3493 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3494 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
3495 dtls_12_options));
3496 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003497 caller()->AddAudioVideoTracks();
3498 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003499 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003500 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07003501 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07003502 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07003503 kDefaultTimeout);
3504 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07003505 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003506 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01003507 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
3508 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
3509 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07003510}
3511
3512// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
3513// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003514TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07003515 PeerConnectionFactory::Options caller_options;
3516 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3517 PeerConnectionFactory::Options callee_options;
3518 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3519 ASSERT_TRUE(
3520 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
3521 ConnectFakeSignaling();
3522 // Do normal offer/answer and wait for some frames to be received in each
3523 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003524 caller()->AddAudioVideoTracks();
3525 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003526 caller()->CreateAndSetAndSignalOffer();
3527 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003528 MediaExpectations media_expectations;
3529 media_expectations.ExpectBidirectionalAudioAndVideo();
3530 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003531}
3532
3533// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
3534// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003535TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07003536 PeerConnectionFactory::Options caller_options;
3537 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3538 PeerConnectionFactory::Options callee_options;
3539 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3540 ASSERT_TRUE(
3541 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
3542 ConnectFakeSignaling();
3543 // Do normal offer/answer and wait for some frames to be received in each
3544 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003545 caller()->AddAudioVideoTracks();
3546 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003547 caller()->CreateAndSetAndSignalOffer();
3548 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003549 MediaExpectations media_expectations;
3550 media_expectations.ExpectBidirectionalAudioAndVideo();
3551 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003552}
3553
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003554// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
3555// works as expected; the cipher should only be used if enabled by both sides.
3556TEST_P(PeerConnectionIntegrationTest,
3557 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
3558 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003559 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003560 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003561 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
3562 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003563 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
3564 TestNegotiatedCipherSuite(caller_options, callee_options,
3565 expected_cipher_suite);
3566}
3567
3568TEST_P(PeerConnectionIntegrationTest,
3569 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
3570 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003571 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
3572 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003573 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003574 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003575 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
3576 TestNegotiatedCipherSuite(caller_options, callee_options,
3577 expected_cipher_suite);
3578}
3579
3580TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
3581 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003582 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003583 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003584 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003585 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
3586 TestNegotiatedCipherSuite(caller_options, callee_options,
3587 expected_cipher_suite);
3588}
3589
deadbeef1dcb1642017-03-29 21:08:16 -07003590// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003591TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07003592 bool local_gcm_enabled = false;
3593 bool remote_gcm_enabled = false;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003594 bool aes_ctr_enabled = true;
deadbeef1dcb1642017-03-29 21:08:16 -07003595 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
3596 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003597 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07003598}
3599
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003600// Test that a GCM cipher is used if both ends support it and non-GCM is
3601// disabled.
3602TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07003603 bool local_gcm_enabled = true;
3604 bool remote_gcm_enabled = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003605 bool aes_ctr_enabled = false;
deadbeef1dcb1642017-03-29 21:08:16 -07003606 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
3607 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003608 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07003609}
3610
deadbeef7914b8c2017-04-21 03:23:33 -07003611// Verify that media can be transmitted end-to-end when GCM crypto suites are
3612// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
3613// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
3614// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003615TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07003616 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003617 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003618 gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false;
deadbeef7914b8c2017-04-21 03:23:33 -07003619 ASSERT_TRUE(
3620 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
3621 ConnectFakeSignaling();
3622 // Do normal offer/answer and wait for some frames to be received in each
3623 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003624 caller()->AddAudioVideoTracks();
3625 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003626 caller()->CreateAndSetAndSignalOffer();
3627 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003628 MediaExpectations media_expectations;
3629 media_expectations.ExpectBidirectionalAudioAndVideo();
3630 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003631}
3632
deadbeef1dcb1642017-03-29 21:08:16 -07003633// This test sets up a call between two parties with audio, video and an RTP
3634// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003635TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003636 PeerConnectionInterface::RTCConfiguration rtc_config;
3637 rtc_config.enable_rtp_data_channel = true;
3638 rtc_config.enable_dtls_srtp = false;
3639 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003640 ConnectFakeSignaling();
3641 // Expect that data channel created on caller side will show up for callee as
3642 // well.
3643 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003644 caller()->AddAudioVideoTracks();
3645 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003646 caller()->CreateAndSetAndSignalOffer();
3647 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3648 // Ensure the existence of the RTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003649 MediaExpectations media_expectations;
3650 media_expectations.ExpectBidirectionalAudioAndVideo();
3651 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003652 ASSERT_NE(nullptr, caller()->data_channel());
3653 ASSERT_NE(nullptr, callee()->data_channel());
3654 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3655 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3656
3657 // Ensure data can be sent in both directions.
3658 std::string data = "hello world";
3659 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3660 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3661 kDefaultTimeout);
3662 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3663 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3664 kDefaultTimeout);
3665}
3666
Eldar Rellod9ebe012020-03-18 20:41:45 +02003667TEST_P(PeerConnectionIntegrationTest, RtpDataChannelWorksAfterRollback) {
3668 PeerConnectionInterface::RTCConfiguration rtc_config;
3669 rtc_config.enable_rtp_data_channel = true;
3670 rtc_config.enable_dtls_srtp = false;
3671 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
3672 ConnectFakeSignaling();
3673 auto data_channel = caller()->pc()->CreateDataChannel("label_1", nullptr);
3674 ASSERT_TRUE(data_channel.get() != nullptr);
3675 caller()->CreateAndSetAndSignalOffer();
3676 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3677
3678 caller()->CreateDataChannel("label_2", nullptr);
3679 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
3680 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
3681 caller()->pc()->SetLocalDescription(observer,
3682 caller()->CreateOfferAndWait().release());
3683 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3684 caller()->Rollback();
3685
3686 std::string data = "hello world";
3687 SendRtpDataWithRetries(data_channel, data, 5);
3688 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3689 kDefaultTimeout);
3690}
3691
deadbeef1dcb1642017-03-29 21:08:16 -07003692// Ensure that an RTP data channel is signaled as closed for the caller when
3693// the callee rejects it in a subsequent offer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003694TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003695 RtpDataChannelSignaledClosedInCalleeOffer) {
3696 // Same procedure as above test.
Niels Möllerf06f9232018-08-07 12:32:18 +02003697 PeerConnectionInterface::RTCConfiguration rtc_config;
3698 rtc_config.enable_rtp_data_channel = true;
3699 rtc_config.enable_dtls_srtp = false;
3700 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003701 ConnectFakeSignaling();
3702 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003703 caller()->AddAudioVideoTracks();
3704 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003705 caller()->CreateAndSetAndSignalOffer();
3706 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3707 ASSERT_NE(nullptr, caller()->data_channel());
3708 ASSERT_NE(nullptr, callee()->data_channel());
3709 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3710 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3711
3712 // Close the data channel on the callee, and do an updated offer/answer.
3713 callee()->data_channel()->Close();
3714 callee()->CreateAndSetAndSignalOffer();
3715 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3716 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3717 EXPECT_FALSE(callee()->data_observer()->IsOpen());
3718}
3719
3720// Tests that data is buffered in an RTP data channel until an observer is
3721// registered for it.
3722//
3723// NOTE: RTP data channels can receive data before the underlying
3724// transport has detected that a channel is writable and thus data can be
3725// received before the data channel state changes to open. That is hard to test
3726// but the same buffering is expected to be used in that case.
Yves Gerey100fe632020-01-17 19:15:53 +01003727//
3728// Use fake clock and simulated network delay so that we predictably can wait
3729// until an SCTP message has been delivered without "sleep()"ing.
3730TEST_P(PeerConnectionIntegrationTestWithFakeClock,
deadbeef1dcb1642017-03-29 21:08:16 -07003731 DataBufferedUntilRtpDataChannelObserverRegistered) {
deadbeef1dcb1642017-03-29 21:08:16 -07003732 virtual_socket_server()->set_delay_mean(5); // 5 ms per hop.
3733 virtual_socket_server()->UpdateDelayDistribution();
3734
Niels Möllerf06f9232018-08-07 12:32:18 +02003735 PeerConnectionInterface::RTCConfiguration rtc_config;
3736 rtc_config.enable_rtp_data_channel = true;
3737 rtc_config.enable_dtls_srtp = false;
3738 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003739 ConnectFakeSignaling();
3740 caller()->CreateDataChannel();
3741 caller()->CreateAndSetAndSignalOffer();
3742 ASSERT_TRUE(caller()->data_channel() != nullptr);
3743 ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr,
Yves Gerey100fe632020-01-17 19:15:53 +01003744 kDefaultTimeout, FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003745 ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(),
Yves Gerey100fe632020-01-17 19:15:53 +01003746 kDefaultTimeout, FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003747 ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen,
3748 callee()->data_channel()->state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01003749 FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003750
3751 // Unregister the observer which is normally automatically registered.
3752 callee()->data_channel()->UnregisterObserver();
3753 // Send data and advance fake clock until it should have been received.
3754 std::string data = "hello world";
3755 caller()->data_channel()->Send(DataBuffer(data));
Yves Gerey100fe632020-01-17 19:15:53 +01003756 SIMULATED_WAIT(false, 50, FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003757
3758 // Attach data channel and expect data to be received immediately. Note that
3759 // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any
3760 // further, but data can be received even if the callback is asynchronous.
3761 MockDataChannelObserver new_observer(callee()->data_channel());
3762 EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01003763 FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003764}
3765
3766// This test sets up a call between two parties with audio, video and but only
3767// the caller client supports RTP data channels.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003768TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003769 PeerConnectionInterface::RTCConfiguration rtc_config_1;
3770 rtc_config_1.enable_rtp_data_channel = true;
deadbeef1dcb1642017-03-29 21:08:16 -07003771 // Must disable DTLS to make negotiation succeed.
Niels Möllerf06f9232018-08-07 12:32:18 +02003772 rtc_config_1.enable_dtls_srtp = false;
3773 PeerConnectionInterface::RTCConfiguration rtc_config_2;
3774 rtc_config_2.enable_dtls_srtp = false;
3775 rtc_config_2.enable_dtls_srtp = false;
3776 ASSERT_TRUE(
3777 CreatePeerConnectionWrappersWithConfig(rtc_config_1, rtc_config_2));
deadbeef1dcb1642017-03-29 21:08:16 -07003778 ConnectFakeSignaling();
3779 caller()->CreateDataChannel();
Harald Alvestrandf3736ed2019-04-08 13:09:30 +02003780 ASSERT_TRUE(caller()->data_channel() != nullptr);
Steve Anton15324772018-01-16 10:26:49 -08003781 caller()->AddAudioVideoTracks();
3782 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003783 caller()->CreateAndSetAndSignalOffer();
3784 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3785 // The caller should still have a data channel, but it should be closed, and
3786 // one should ever have been created for the callee.
3787 EXPECT_TRUE(caller()->data_channel() != nullptr);
3788 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3789 EXPECT_EQ(nullptr, callee()->data_channel());
3790}
3791
3792// This test sets up a call between two parties with audio, and video. When
3793// audio and video is setup and flowing, an RTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003794TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003795 PeerConnectionInterface::RTCConfiguration rtc_config;
3796 rtc_config.enable_rtp_data_channel = true;
3797 rtc_config.enable_dtls_srtp = false;
3798 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003799 ConnectFakeSignaling();
3800 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003801 caller()->AddAudioVideoTracks();
3802 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003803 caller()->CreateAndSetAndSignalOffer();
3804 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3805 // Create data channel and do new offer and answer.
3806 caller()->CreateDataChannel();
3807 caller()->CreateAndSetAndSignalOffer();
3808 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3809 ASSERT_NE(nullptr, caller()->data_channel());
3810 ASSERT_NE(nullptr, callee()->data_channel());
3811 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3812 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3813 // Ensure data can be sent in both directions.
3814 std::string data = "hello world";
3815 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3816 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3817 kDefaultTimeout);
3818 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3819 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3820 kDefaultTimeout);
3821}
3822
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01003823#ifdef WEBRTC_HAVE_SCTP
deadbeef1dcb1642017-03-29 21:08:16 -07003824
3825// This test sets up a call between two parties with audio, video and an SCTP
3826// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003827TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003828 ASSERT_TRUE(CreatePeerConnectionWrappers());
3829 ConnectFakeSignaling();
3830 // Expect that data channel created on caller side will show up for callee as
3831 // well.
3832 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003833 caller()->AddAudioVideoTracks();
3834 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003835 caller()->CreateAndSetAndSignalOffer();
3836 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3837 // Ensure the existence of the SCTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003838 MediaExpectations media_expectations;
3839 media_expectations.ExpectBidirectionalAudioAndVideo();
3840 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003841 // Caller data channel should already exist (it created one). Callee data
3842 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3843 ASSERT_NE(nullptr, caller()->data_channel());
3844 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3845 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3846 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3847
3848 // Ensure data can be sent in both directions.
3849 std::string data = "hello world";
3850 caller()->data_channel()->Send(DataBuffer(data));
3851 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3852 kDefaultTimeout);
3853 callee()->data_channel()->Send(DataBuffer(data));
3854 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3855 kDefaultTimeout);
3856}
3857
3858// Ensure that when the callee closes an SCTP data channel, the closing
3859// procedure results in the data channel being closed for the caller as well.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003860TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003861 // Same procedure as above test.
3862 ASSERT_TRUE(CreatePeerConnectionWrappers());
3863 ConnectFakeSignaling();
3864 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003865 caller()->AddAudioVideoTracks();
3866 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003867 caller()->CreateAndSetAndSignalOffer();
3868 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3869 ASSERT_NE(nullptr, caller()->data_channel());
3870 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3871 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3872 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3873
3874 // Close the data channel on the callee side, and wait for it to reach the
3875 // "closed" state on both sides.
3876 callee()->data_channel()->Close();
3877 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3878 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3879}
3880
Seth Hampson2f0d7022018-02-20 11:54:42 -08003881TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
Steve Antonda6c0952017-10-23 11:41:54 -07003882 ASSERT_TRUE(CreatePeerConnectionWrappers());
3883 ConnectFakeSignaling();
3884 webrtc::DataChannelInit init;
3885 init.id = 53;
3886 init.maxRetransmits = 52;
3887 caller()->CreateDataChannel("data-channel", &init);
Steve Anton15324772018-01-16 10:26:49 -08003888 caller()->AddAudioVideoTracks();
3889 callee()->AddAudioVideoTracks();
Steve Antonda6c0952017-10-23 11:41:54 -07003890 caller()->CreateAndSetAndSignalOffer();
3891 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton074dece2017-10-24 13:04:12 -07003892 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3893 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Harald Alvestrand5c4d2ee2019-04-01 12:58:15 +02003894 // Since "negotiated" is false, the "id" parameter should be ignored.
3895 EXPECT_NE(init.id, callee()->data_channel()->id());
Steve Antonda6c0952017-10-23 11:41:54 -07003896 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3897 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3898 EXPECT_FALSE(callee()->data_channel()->negotiated());
3899}
3900
deadbeef1dcb1642017-03-29 21:08:16 -07003901// Test usrsctp's ability to process unordered data stream, where data actually
3902// arrives out of order using simulated delays. Previously there have been some
3903// bugs in this area.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003904TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003905 // Introduce random network delays.
3906 // Otherwise it's not a true "unordered" test.
3907 virtual_socket_server()->set_delay_mean(20);
3908 virtual_socket_server()->set_delay_stddev(5);
3909 virtual_socket_server()->UpdateDelayDistribution();
3910 // Normal procedure, but with unordered data channel config.
3911 ASSERT_TRUE(CreatePeerConnectionWrappers());
3912 ConnectFakeSignaling();
3913 webrtc::DataChannelInit init;
3914 init.ordered = false;
3915 caller()->CreateDataChannel(&init);
3916 caller()->CreateAndSetAndSignalOffer();
3917 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3918 ASSERT_NE(nullptr, caller()->data_channel());
3919 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3920 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3921 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3922
3923 static constexpr int kNumMessages = 100;
3924 // Deliberately chosen to be larger than the MTU so messages get fragmented.
3925 static constexpr size_t kMaxMessageSize = 4096;
3926 // Create and send random messages.
3927 std::vector<std::string> sent_messages;
3928 for (int i = 0; i < kNumMessages; ++i) {
3929 size_t length =
3930 (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand)
3931 std::string message;
3932 ASSERT_TRUE(rtc::CreateRandomString(length, &message));
3933 caller()->data_channel()->Send(DataBuffer(message));
3934 callee()->data_channel()->Send(DataBuffer(message));
3935 sent_messages.push_back(message);
3936 }
3937
3938 // Wait for all messages to be received.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003939 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003940 caller()->data_observer()->received_message_count(),
3941 kDefaultTimeout);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003942 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003943 callee()->data_observer()->received_message_count(),
3944 kDefaultTimeout);
3945
3946 // Sort and compare to make sure none of the messages were corrupted.
3947 std::vector<std::string> caller_received_messages =
3948 caller()->data_observer()->messages();
3949 std::vector<std::string> callee_received_messages =
3950 callee()->data_observer()->messages();
Steve Anton64b626b2019-01-28 17:25:26 -08003951 absl::c_sort(sent_messages);
3952 absl::c_sort(caller_received_messages);
3953 absl::c_sort(callee_received_messages);
deadbeef1dcb1642017-03-29 21:08:16 -07003954 EXPECT_EQ(sent_messages, caller_received_messages);
3955 EXPECT_EQ(sent_messages, callee_received_messages);
3956}
3957
3958// This test sets up a call between two parties with audio, and video. When
3959// audio and video are setup and flowing, an SCTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003960TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07003961 ASSERT_TRUE(CreatePeerConnectionWrappers());
3962 ConnectFakeSignaling();
3963 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003964 caller()->AddAudioVideoTracks();
3965 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003966 caller()->CreateAndSetAndSignalOffer();
3967 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3968 // Create data channel and do new offer and answer.
3969 caller()->CreateDataChannel();
3970 caller()->CreateAndSetAndSignalOffer();
3971 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3972 // Caller data channel should already exist (it created one). Callee data
3973 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3974 ASSERT_NE(nullptr, caller()->data_channel());
3975 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3976 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3977 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3978 // Ensure data can be sent in both directions.
3979 std::string data = "hello world";
3980 caller()->data_channel()->Send(DataBuffer(data));
3981 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3982 kDefaultTimeout);
3983 callee()->data_channel()->Send(DataBuffer(data));
3984 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3985 kDefaultTimeout);
3986}
3987
deadbeef7914b8c2017-04-21 03:23:33 -07003988// Set up a connection initially just using SCTP data channels, later upgrading
3989// to audio/video, ensuring frames are received end-to-end. Effectively the
3990// inverse of the test above.
3991// This was broken in M57; see https://crbug.com/711243
Seth Hampson2f0d7022018-02-20 11:54:42 -08003992TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
deadbeef7914b8c2017-04-21 03:23:33 -07003993 ASSERT_TRUE(CreatePeerConnectionWrappers());
3994 ConnectFakeSignaling();
3995 // Do initial offer/answer with just data channel.
3996 caller()->CreateDataChannel();
3997 caller()->CreateAndSetAndSignalOffer();
3998 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3999 // Wait until data can be sent over the data channel.
4000 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
4001 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
4002 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
4003
4004 // Do subsequent offer/answer with two-way audio and video. Audio and video
4005 // should end up bundled on the DTLS/ICE transport already used for data.
Steve Anton15324772018-01-16 10:26:49 -08004006 caller()->AddAudioVideoTracks();
4007 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07004008 caller()->CreateAndSetAndSignalOffer();
4009 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004010 MediaExpectations media_expectations;
4011 media_expectations.ExpectBidirectionalAudioAndVideo();
4012 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07004013}
4014
deadbeef8b7e9ad2017-05-25 09:38:55 -07004015static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
Harald Alvestrand5fc28b12019-05-13 13:36:16 +02004016 cricket::SctpDataContentDescription* dcd_offer =
4017 GetFirstSctpDataContentDescription(desc);
Harald Alvestrand17ea0682019-12-13 11:51:04 +01004018 // See https://crbug.com/webrtc/11211 - this function is a no-op
Steve Antonb1c1de12017-12-21 15:14:30 -08004019 ASSERT_TRUE(dcd_offer);
deadbeef8b7e9ad2017-05-25 09:38:55 -07004020 dcd_offer->set_use_sctpmap(false);
4021 dcd_offer->set_protocol("UDP/DTLS/SCTP");
4022}
4023
4024// Test that the data channel works when a spec-compliant SCTP m= section is
4025// offered (using "a=sctp-port" instead of "a=sctpmap", and using
4026// "UDP/DTLS/SCTP" as the protocol).
Seth Hampson2f0d7022018-02-20 11:54:42 -08004027TEST_P(PeerConnectionIntegrationTest,
deadbeef8b7e9ad2017-05-25 09:38:55 -07004028 DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
4029 ASSERT_TRUE(CreatePeerConnectionWrappers());
4030 ConnectFakeSignaling();
4031 caller()->CreateDataChannel();
4032 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
4033 caller()->CreateAndSetAndSignalOffer();
4034 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4035 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
4036 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
4037 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
4038
4039 // Ensure data can be sent in both directions.
4040 std::string data = "hello world";
4041 caller()->data_channel()->Send(DataBuffer(data));
4042 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
4043 kDefaultTimeout);
4044 callee()->data_channel()->Send(DataBuffer(data));
4045 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
4046 kDefaultTimeout);
4047}
4048
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01004049#endif // WEBRTC_HAVE_SCTP
deadbeef1dcb1642017-03-29 21:08:16 -07004050
4051// Test that the ICE connection and gathering states eventually reach
4052// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08004053TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07004054 ASSERT_TRUE(CreatePeerConnectionWrappers());
4055 ConnectFakeSignaling();
4056 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08004057 caller()->AddAudioVideoTracks();
4058 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004059 caller()->CreateAndSetAndSignalOffer();
4060 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4061 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
4062 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
4063 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
4064 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
4065 // After the best candidate pair is selected and all candidates are signaled,
4066 // the ICE connection state should reach "complete".
4067 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
4068 // answerer/"callee" by default) only reaches "connected". When this is
4069 // fixed, this test should be updated.
4070 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4071 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00004072 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4073 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07004074}
4075
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004076constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
4077 cricket::PORTALLOCATOR_DISABLE_RELAY |
4078 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004079
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004080// Use a mock resolver to resolve the hostname back to the original IP on both
4081// sides and check that the ICE connection connects.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004082TEST_P(PeerConnectionIntegrationTest,
4083 IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004084 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004085 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004086 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004087 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004088 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
4089 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004090
4091 // This also verifies that the injected AsyncResolverFactory is used by
4092 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004093 EXPECT_CALL(*caller_resolver_factory, Create())
4094 .WillOnce(Return(&caller_async_resolver));
4095 webrtc::PeerConnectionDependencies caller_deps(nullptr);
4096 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
4097
4098 EXPECT_CALL(*callee_resolver_factory, Create())
4099 .WillOnce(Return(&callee_async_resolver));
4100 webrtc::PeerConnectionDependencies callee_deps(nullptr);
4101 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
4102
4103 PeerConnectionInterface::RTCConfiguration config;
4104 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
4105 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
4106
4107 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4108 config, std::move(caller_deps), config, std::move(callee_deps)));
4109
4110 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
4111 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
4112
4113 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07004114 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004115 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07004116 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004117 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004118
4119 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004120
4121 ConnectFakeSignaling();
4122 caller()->AddAudioVideoTracks();
4123 callee()->AddAudioVideoTracks();
4124 caller()->CreateAndSetAndSignalOffer();
4125 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4126 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4127 caller()->ice_connection_state(), kDefaultTimeout);
4128 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4129 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08004130
Ying Wangef3998f2019-12-09 13:06:53 +01004131 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
4132 "WebRTC.PeerConnection.CandidatePairType_UDP",
4133 webrtc::kIceCandidatePairHostNameHostName));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004134}
4135
Steve Antonede9ca52017-10-16 13:04:27 -07004136// Test that firewalling the ICE connection causes the clients to identify the
4137// disconnected state and then removing the firewall causes them to reconnect.
4138class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08004139 : public PeerConnectionIntegrationBaseTest,
4140 public ::testing::WithParamInterface<
4141 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07004142 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08004143 PeerConnectionIntegrationIceStatesTest()
4144 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
4145 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07004146 }
4147
4148 void StartStunServer(const SocketAddress& server_address) {
4149 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01004150 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07004151 }
4152
4153 bool TestIPv6() {
4154 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
4155 }
4156
4157 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004158 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
4159 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07004160 }
4161
4162 std::vector<SocketAddress> CallerAddresses() {
4163 std::vector<SocketAddress> addresses;
4164 addresses.push_back(SocketAddress("1.1.1.1", 0));
4165 if (TestIPv6()) {
4166 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
4167 }
4168 return addresses;
4169 }
4170
4171 std::vector<SocketAddress> CalleeAddresses() {
4172 std::vector<SocketAddress> addresses;
4173 addresses.push_back(SocketAddress("2.2.2.2", 0));
4174 if (TestIPv6()) {
4175 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
4176 }
4177 return addresses;
4178 }
4179
4180 void SetUpNetworkInterfaces() {
4181 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07004182 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
4183 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07004184
4185 // Add network addresses for test.
4186 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07004187 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07004188 }
4189 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07004190 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07004191 }
4192 }
4193
4194 private:
4195 uint32_t port_allocator_flags_;
4196 std::unique_ptr<cricket::TestStunServer> stun_server_;
4197};
4198
Yves Gerey100fe632020-01-17 19:15:53 +01004199// Ensure FakeClockForTest is constructed first (see class for rationale).
4200class PeerConnectionIntegrationIceStatesTestWithFakeClock
4201 : public FakeClockForTest,
4202 public PeerConnectionIntegrationIceStatesTest {};
4203
Steve Antonede9ca52017-10-16 13:04:27 -07004204// Tests that the PeerConnection goes through all the ICE gathering/connection
4205// states over the duration of the call. This includes Disconnected and Failed
4206// states, induced by putting a firewall between the peers and waiting for them
4207// to time out.
Yves Gerey100fe632020-01-17 19:15:53 +01004208TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock, VerifyIceStates) {
Steve Antonede9ca52017-10-16 13:04:27 -07004209 const SocketAddress kStunServerAddress =
4210 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
4211 StartStunServer(kStunServerAddress);
4212
4213 PeerConnectionInterface::RTCConfiguration config;
4214 PeerConnectionInterface::IceServer ice_stun_server;
4215 ice_stun_server.urls.push_back(
4216 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
4217 kStunServerAddress.PortAsString());
4218 config.servers.push_back(ice_stun_server);
4219
4220 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
4221 ConnectFakeSignaling();
4222 SetPortAllocatorFlags();
4223 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08004224 caller()->AddAudioVideoTracks();
4225 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004226
4227 // Initial state before anything happens.
4228 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
4229 caller()->ice_gathering_state());
4230 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
4231 caller()->ice_connection_state());
Jonas Olsson7a6739e2019-01-15 16:31:55 +01004232 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
4233 caller()->standardized_ice_connection_state());
Steve Antonede9ca52017-10-16 13:04:27 -07004234
4235 // Start the call by creating the offer, setting it as the local description,
4236 // then sending it to the peer who will respond with an answer. This happens
4237 // asynchronously so that we can watch the states as it runs in the
4238 // background.
4239 caller()->CreateAndSetAndSignalOffer();
4240
Steve Antona9b67ce2020-01-16 14:00:44 -08004241 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4242 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004243 FakeClock());
Steve Antona9b67ce2020-01-16 14:00:44 -08004244 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4245 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004246 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004247
4248 // Verify that the observer was notified of the intermediate transitions.
4249 EXPECT_THAT(caller()->ice_connection_state_history(),
4250 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
4251 PeerConnectionInterface::kIceConnectionConnected,
4252 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olssonacd8ae72019-02-25 15:26:24 +01004253 EXPECT_THAT(caller()->standardized_ice_connection_state_history(),
4254 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
4255 PeerConnectionInterface::kIceConnectionConnected,
4256 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olsson635474e2018-10-18 15:58:17 +02004257 EXPECT_THAT(
4258 caller()->peer_connection_state_history(),
4259 ElementsAre(PeerConnectionInterface::PeerConnectionState::kConnecting,
Jonas Olsson635474e2018-10-18 15:58:17 +02004260 PeerConnectionInterface::PeerConnectionState::kConnected));
Steve Antonede9ca52017-10-16 13:04:27 -07004261 EXPECT_THAT(caller()->ice_gathering_state_history(),
4262 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
4263 PeerConnectionInterface::kIceGatheringComplete));
4264
4265 // Block connections to/from the caller and wait for ICE to become
4266 // disconnected.
4267 for (const auto& caller_address : CallerAddresses()) {
4268 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4269 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01004270 RTC_LOG(LS_INFO) << "Firewall rules applied";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004271 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
4272 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004273 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004274 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
4275 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004276 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004277
4278 // Let ICE re-establish by removing the firewall rules.
4279 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01004280 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004281 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4282 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004283 FakeClock());
Jonas Olssonacd8ae72019-02-25 15:26:24 +01004284 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004285 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004286 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004287
4288 // According to RFC7675, if there is no response within 30 seconds then the
4289 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08004290 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07004291 constexpr int kConsentTimeout = 30000;
4292 for (const auto& caller_address : CallerAddresses()) {
4293 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4294 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01004295 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004296 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4297 caller()->ice_connection_state(), kConsentTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004298 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004299 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4300 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004301 kConsentTimeout, FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004302}
4303
4304// Tests that if the connection doesn't get set up properly we eventually reach
4305// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01004306TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
4307 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004308 // Block connections to/from the caller and wait for ICE to become
4309 // disconnected.
4310 for (const auto& caller_address : CallerAddresses()) {
4311 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4312 }
4313
4314 ASSERT_TRUE(CreatePeerConnectionWrappers());
4315 ConnectFakeSignaling();
4316 SetPortAllocatorFlags();
4317 SetUpNetworkInterfaces();
4318 caller()->AddAudioVideoTracks();
4319 caller()->CreateAndSetAndSignalOffer();
4320
4321 // According to RFC7675, if there is no response within 30 seconds then the
4322 // peer should consider the other side to have rejected the connection. This
4323 // is signaled by the state transitioning to "failed".
4324 constexpr int kConsentTimeout = 30000;
4325 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4326 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004327 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004328}
4329
4330// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
4331// and that the statistics in the metric observers are updated correctly.
4332TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) {
4333 ASSERT_TRUE(CreatePeerConnectionWrappers());
4334 ConnectFakeSignaling();
4335 SetPortAllocatorFlags();
4336 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08004337 caller()->AddAudioVideoTracks();
4338 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004339 caller()->CreateAndSetAndSignalOffer();
4340
4341 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08004342 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4343 caller()->ice_connection_state(), kDefaultTimeout);
4344 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4345 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07004346
Qingsi Wang7fc821d2018-07-12 12:54:53 -07004347 // TODO(bugs.webrtc.org/9456): Fix it.
4348 const int num_best_ipv4 = webrtc::metrics::NumEvents(
4349 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
4350 const int num_best_ipv6 = webrtc::metrics::NumEvents(
4351 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004352 if (TestIPv6()) {
4353 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
4354 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01004355 EXPECT_METRIC_EQ(0, num_best_ipv4);
4356 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004357 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01004358 EXPECT_METRIC_EQ(1, num_best_ipv4);
4359 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004360 }
4361
Ying Wangef3998f2019-12-09 13:06:53 +01004362 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
4363 "WebRTC.PeerConnection.CandidatePairType_UDP",
4364 webrtc::kIceCandidatePairHostHost));
4365 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
4366 "WebRTC.PeerConnection.CandidatePairType_UDP",
4367 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07004368}
4369
4370constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
4371 cricket::PORTALLOCATOR_DISABLE_STUN |
4372 cricket::PORTALLOCATOR_DISABLE_RELAY;
4373constexpr uint32_t kFlagsIPv6NoStun =
4374 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
4375 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
4376constexpr uint32_t kFlagsIPv4Stun =
4377 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
4378
Mirko Bonadeic84f6612019-01-31 12:20:57 +01004379INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004380 PeerConnectionIntegrationTest,
4381 PeerConnectionIntegrationIceStatesTest,
4382 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4383 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
4384 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
4385 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07004386
Yves Gerey100fe632020-01-17 19:15:53 +01004387INSTANTIATE_TEST_SUITE_P(
4388 PeerConnectionIntegrationTest,
4389 PeerConnectionIntegrationIceStatesTestWithFakeClock,
4390 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4391 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
4392 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
4393 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
4394
deadbeef1dcb1642017-03-29 21:08:16 -07004395// This test sets up a call between two parties with audio and video.
4396// During the call, the caller restarts ICE and the test verifies that
4397// new ICE candidates are generated and audio and video still can flow, and the
4398// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004399TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07004400 ASSERT_TRUE(CreatePeerConnectionWrappers());
4401 ConnectFakeSignaling();
4402 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08004403 caller()->AddAudioVideoTracks();
4404 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004405 caller()->CreateAndSetAndSignalOffer();
4406 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4407 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4408 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00004409 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4410 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07004411
4412 // To verify that the ICE restart actually occurs, get
4413 // ufrag/password/candidates before and after restart.
4414 // Create an SDP string of the first audio candidate for both clients.
4415 const webrtc::IceCandidateCollection* audio_candidates_caller =
4416 caller()->pc()->local_description()->candidates(0);
4417 const webrtc::IceCandidateCollection* audio_candidates_callee =
4418 callee()->pc()->local_description()->candidates(0);
4419 ASSERT_GT(audio_candidates_caller->count(), 0u);
4420 ASSERT_GT(audio_candidates_callee->count(), 0u);
4421 std::string caller_candidate_pre_restart;
4422 ASSERT_TRUE(
4423 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
4424 std::string callee_candidate_pre_restart;
4425 ASSERT_TRUE(
4426 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
4427 const cricket::SessionDescription* desc =
4428 caller()->pc()->local_description()->description();
4429 std::string caller_ufrag_pre_restart =
4430 desc->transport_infos()[0].description.ice_ufrag;
4431 desc = callee()->pc()->local_description()->description();
4432 std::string callee_ufrag_pre_restart =
4433 desc->transport_infos()[0].description.ice_ufrag;
4434
Alex Drake00c7ecf2019-08-06 10:54:47 -07004435 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07004436 // Have the caller initiate an ICE restart.
4437 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
4438 caller()->CreateAndSetAndSignalOffer();
4439 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4440 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4441 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00004442 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07004443 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4444
4445 // Grab the ufrags/candidates again.
4446 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
4447 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
4448 ASSERT_GT(audio_candidates_caller->count(), 0u);
4449 ASSERT_GT(audio_candidates_callee->count(), 0u);
4450 std::string caller_candidate_post_restart;
4451 ASSERT_TRUE(
4452 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
4453 std::string callee_candidate_post_restart;
4454 ASSERT_TRUE(
4455 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
4456 desc = caller()->pc()->local_description()->description();
4457 std::string caller_ufrag_post_restart =
4458 desc->transport_infos()[0].description.ice_ufrag;
4459 desc = callee()->pc()->local_description()->description();
4460 std::string callee_ufrag_post_restart =
4461 desc->transport_infos()[0].description.ice_ufrag;
4462 // Sanity check that an ICE restart was actually negotiated in SDP.
4463 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
4464 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
4465 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
4466 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07004467 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07004468
4469 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004470 MediaExpectations media_expectations;
4471 media_expectations.ExpectBidirectionalAudioAndVideo();
4472 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004473}
4474
4475// Verify that audio/video can be received end-to-end when ICE renomination is
4476// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004477TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07004478 PeerConnectionInterface::RTCConfiguration config;
4479 config.enable_ice_renomination = true;
4480 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
4481 ConnectFakeSignaling();
4482 // Do normal offer/answer and wait for some frames to be received in each
4483 // direction.
Steve Anton15324772018-01-16 10:26:49 -08004484 caller()->AddAudioVideoTracks();
4485 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004486 caller()->CreateAndSetAndSignalOffer();
4487 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4488 // Sanity check that ICE renomination was actually negotiated.
4489 const cricket::SessionDescription* desc =
4490 caller()->pc()->local_description()->description();
4491 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08004492 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07004493 }
4494 desc = callee()->pc()->local_description()->description();
4495 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08004496 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07004497 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08004498 MediaExpectations media_expectations;
4499 media_expectations.ExpectBidirectionalAudioAndVideo();
4500 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004501}
4502
Steve Anton6f25b092017-10-23 09:39:20 -07004503// With a max bundle policy and RTCP muxing, adding a new media description to
4504// the connection should not affect ICE at all because the new media will use
4505// the existing connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004506TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08004507 AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07004508 PeerConnectionInterface::RTCConfiguration config;
4509 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
4510 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
4511 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
4512 config, PeerConnectionInterface::RTCConfiguration()));
4513 ConnectFakeSignaling();
4514
Steve Anton15324772018-01-16 10:26:49 -08004515 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07004516 caller()->CreateAndSetAndSignalOffer();
4517 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07004518 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4519 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07004520
4521 caller()->clear_ice_connection_state_history();
4522
Steve Anton15324772018-01-16 10:26:49 -08004523 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07004524 caller()->CreateAndSetAndSignalOffer();
4525 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4526
4527 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
4528}
4529
deadbeef1dcb1642017-03-29 21:08:16 -07004530// This test sets up a call between two parties with audio and video. It then
4531// renegotiates setting the video m-line to "port 0", then later renegotiates
4532// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004533TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07004534 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
4535 ASSERT_TRUE(CreatePeerConnectionWrappers());
4536 ConnectFakeSignaling();
4537
4538 // Do initial negotiation, only sending media from the caller. Will result in
4539 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08004540 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004541 caller()->CreateAndSetAndSignalOffer();
4542 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4543
4544 // Negotiate again, disabling the video "m=" section (the callee will set the
4545 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08004546 if (sdp_semantics_ == SdpSemantics::kPlanB) {
4547 PeerConnectionInterface::RTCOfferAnswerOptions options;
4548 options.offer_to_receive_video = 0;
4549 callee()->SetOfferAnswerOptions(options);
4550 } else {
4551 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02004552 callee()
4553 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
4554 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08004555 });
4556 }
deadbeef1dcb1642017-03-29 21:08:16 -07004557 caller()->CreateAndSetAndSignalOffer();
4558 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4559 // Sanity check that video "m=" section was actually rejected.
4560 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
4561 callee()->pc()->local_description()->description());
4562 ASSERT_NE(nullptr, answer_video_content);
4563 ASSERT_TRUE(answer_video_content->rejected);
4564
4565 // Enable video and do negotiation again, making sure video is received
4566 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004567 if (sdp_semantics_ == SdpSemantics::kPlanB) {
4568 PeerConnectionInterface::RTCOfferAnswerOptions options;
4569 options.offer_to_receive_video = 1;
4570 callee()->SetOfferAnswerOptions(options);
4571 } else {
4572 // The caller's transceiver is stopped, so we need to add another track.
4573 auto caller_transceiver =
4574 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02004575 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08004576 caller()->AddVideoTrack();
4577 }
4578 callee()->AddVideoTrack();
4579 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07004580 caller()->CreateAndSetAndSignalOffer();
4581 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004582
deadbeef1dcb1642017-03-29 21:08:16 -07004583 // Verify the caller receives frames from the newly added stream, and the
4584 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004585 MediaExpectations media_expectations;
4586 media_expectations.CalleeExpectsSomeAudio();
4587 media_expectations.ExpectBidirectionalVideo();
4588 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004589}
4590
deadbeef1dcb1642017-03-29 21:08:16 -07004591// This tests that if we negotiate after calling CreateSender but before we
4592// have a track, then set a track later, frames from the newly-set track are
4593// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004594TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07004595 MediaFlowsAfterEarlyWarmupWithCreateSender) {
4596 ASSERT_TRUE(CreatePeerConnectionWrappers());
4597 ConnectFakeSignaling();
4598 auto caller_audio_sender =
4599 caller()->pc()->CreateSender("audio", "caller_stream");
4600 auto caller_video_sender =
4601 caller()->pc()->CreateSender("video", "caller_stream");
4602 auto callee_audio_sender =
4603 callee()->pc()->CreateSender("audio", "callee_stream");
4604 auto callee_video_sender =
4605 callee()->pc()->CreateSender("video", "callee_stream");
4606 caller()->CreateAndSetAndSignalOffer();
4607 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4608 // Wait for ICE to complete, without any tracks being set.
4609 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4610 caller()->ice_connection_state(), kMaxWaitForFramesMs);
4611 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4612 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4613 // Now set the tracks, and expect frames to immediately start flowing.
4614 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
4615 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
4616 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
4617 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08004618 MediaExpectations media_expectations;
4619 media_expectations.ExpectBidirectionalAudioAndVideo();
4620 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4621}
4622
4623// This tests that if we negotiate after calling AddTransceiver but before we
4624// have a track, then set a track later, frames from the newly-set tracks are
4625// received end-to-end.
4626TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
4627 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
4628 ASSERT_TRUE(CreatePeerConnectionWrappers());
4629 ConnectFakeSignaling();
4630 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
4631 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
4632 auto caller_audio_sender = audio_result.MoveValue()->sender();
4633 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
4634 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
4635 auto caller_video_sender = video_result.MoveValue()->sender();
4636 callee()->SetRemoteOfferHandler([this] {
4637 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02004638 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004639 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02004640 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004641 RtpTransceiverDirection::kSendRecv);
4642 });
4643 caller()->CreateAndSetAndSignalOffer();
4644 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4645 // Wait for ICE to complete, without any tracks being set.
4646 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4647 caller()->ice_connection_state(), kMaxWaitForFramesMs);
4648 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4649 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4650 // Now set the tracks, and expect frames to immediately start flowing.
4651 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
4652 auto callee_video_sender = callee()->pc()->GetSenders()[1];
4653 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
4654 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
4655 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
4656 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
4657 MediaExpectations media_expectations;
4658 media_expectations.ExpectBidirectionalAudioAndVideo();
4659 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004660}
4661
4662// This test verifies that a remote video track can be added via AddStream,
4663// and sent end-to-end. For this particular test, it's simply echoed back
4664// from the caller to the callee, rather than being forwarded to a third
4665// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004666TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07004667 ASSERT_TRUE(CreatePeerConnectionWrappers());
4668 ConnectFakeSignaling();
4669 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08004670 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07004671 caller()->CreateAndSetAndSignalOffer();
4672 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02004673 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07004674
4675 // Echo the stream back, and do a new offer/anwer (initiated by callee this
4676 // time).
4677 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
4678 callee()->CreateAndSetAndSignalOffer();
4679 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4680
Seth Hampson2f0d7022018-02-20 11:54:42 -08004681 MediaExpectations media_expectations;
4682 media_expectations.ExpectBidirectionalVideo();
4683 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004684}
4685
4686// Test that we achieve the expected end-to-end connection time, using a
4687// fake clock and simulated latency on the media and signaling paths.
4688// We use a TURN<->TURN connection because this is usually the quickest to
4689// set up initially, especially when we're confident the connection will work
4690// and can start sending media before we get a STUN response.
4691//
4692// With various optimizations enabled, here are the network delays we expect to
4693// be on the critical path:
4694// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
4695// signaling answer (with DTLS fingerprint).
4696// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
4697// using TURN<->TURN pair, and DTLS exchange is 4 packets,
4698// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01004699TEST_P(PeerConnectionIntegrationTestWithFakeClock,
4700 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07004701 static constexpr int media_hop_delay_ms = 50;
4702 static constexpr int signaling_trip_delay_ms = 500;
4703 // For explanation of these values, see comment above.
4704 static constexpr int required_media_hops = 9;
4705 static constexpr int required_signaling_trips = 2;
4706 // For internal delays (such as posting an event asychronously).
4707 static constexpr int allowed_internal_delay_ms = 20;
4708 static constexpr int total_connection_time_ms =
4709 media_hop_delay_ms * required_media_hops +
4710 signaling_trip_delay_ms * required_signaling_trips +
4711 allowed_internal_delay_ms;
4712
4713 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4714 3478};
4715 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4716 0};
4717 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4718 3478};
4719 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4720 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004721 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
4722 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004723
Seth Hampsonaed71642018-06-11 07:41:32 -07004724 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
4725 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07004726 // Bypass permission check on received packets so media can be sent before
4727 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07004728 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
4729 turn_server_1->set_enable_permission_checks(false);
4730 });
4731 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
4732 turn_server_2->set_enable_permission_checks(false);
4733 });
deadbeef1dcb1642017-03-29 21:08:16 -07004734
4735 PeerConnectionInterface::RTCConfiguration client_1_config;
4736 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4737 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4738 ice_server_1.username = "test";
4739 ice_server_1.password = "test";
4740 client_1_config.servers.push_back(ice_server_1);
4741 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4742 client_1_config.presume_writable_when_fully_relayed = true;
4743
4744 PeerConnectionInterface::RTCConfiguration client_2_config;
4745 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4746 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4747 ice_server_2.username = "test";
4748 ice_server_2.password = "test";
4749 client_2_config.servers.push_back(ice_server_2);
4750 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4751 client_2_config.presume_writable_when_fully_relayed = true;
4752
4753 ASSERT_TRUE(
4754 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4755 // Set up the simulated delays.
4756 SetSignalingDelayMs(signaling_trip_delay_ms);
4757 ConnectFakeSignaling();
4758 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
4759 virtual_socket_server()->UpdateDelayDistribution();
4760
4761 // Set "offer to receive audio/video" without adding any tracks, so we just
4762 // set up ICE/DTLS with no media.
4763 PeerConnectionInterface::RTCOfferAnswerOptions options;
4764 options.offer_to_receive_audio = 1;
4765 options.offer_to_receive_video = 1;
4766 caller()->SetOfferAnswerOptions(options);
4767 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07004768 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01004769 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07004770 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
4771 // If this is not done a DCHECK can be hit in ports.cc, because a large
4772 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07004773 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07004774}
4775
Jonas Orelandbdcee282017-10-10 14:01:40 +02004776// Verify that a TurnCustomizer passed in through RTCConfiguration
4777// is actually used by the underlying TURN candidate pair.
4778// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004779TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02004780 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4781 3478};
4782 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4783 0};
4784 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4785 3478};
4786 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4787 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004788 CreateTurnServer(turn_server_1_internal_address,
4789 turn_server_1_external_address);
4790 CreateTurnServer(turn_server_2_internal_address,
4791 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004792
4793 PeerConnectionInterface::RTCConfiguration client_1_config;
4794 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4795 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4796 ice_server_1.username = "test";
4797 ice_server_1.password = "test";
4798 client_1_config.servers.push_back(ice_server_1);
4799 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004800 auto* customizer1 = CreateTurnCustomizer();
4801 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004802
4803 PeerConnectionInterface::RTCConfiguration client_2_config;
4804 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4805 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4806 ice_server_2.username = "test";
4807 ice_server_2.password = "test";
4808 client_2_config.servers.push_back(ice_server_2);
4809 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004810 auto* customizer2 = CreateTurnCustomizer();
4811 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004812
4813 ASSERT_TRUE(
4814 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4815 ConnectFakeSignaling();
4816
4817 // Set "offer to receive audio/video" without adding any tracks, so we just
4818 // set up ICE/DTLS with no media.
4819 PeerConnectionInterface::RTCOfferAnswerOptions options;
4820 options.offer_to_receive_audio = 1;
4821 options.offer_to_receive_video = 1;
4822 caller()->SetOfferAnswerOptions(options);
4823 caller()->CreateAndSetAndSignalOffer();
4824 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4825
Seth Hampsonaed71642018-06-11 07:41:32 -07004826 ExpectTurnCustomizerCountersIncremented(customizer1);
4827 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004828}
4829
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004830// Verifies that you can use TCP instead of UDP to connect to a TURN server and
4831// send media between the caller and the callee.
4832TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
4833 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4834 3478};
4835 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4836
4837 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07004838 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4839 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004840
4841 webrtc::PeerConnectionInterface::IceServer ice_server;
4842 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
4843 ice_server.username = "test";
4844 ice_server.password = "test";
4845
4846 PeerConnectionInterface::RTCConfiguration client_1_config;
4847 client_1_config.servers.push_back(ice_server);
4848 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4849
4850 PeerConnectionInterface::RTCConfiguration client_2_config;
4851 client_2_config.servers.push_back(ice_server);
4852 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4853
4854 ASSERT_TRUE(
4855 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4856
4857 // Do normal offer/answer and wait for ICE to complete.
4858 ConnectFakeSignaling();
4859 caller()->AddAudioVideoTracks();
4860 callee()->AddAudioVideoTracks();
4861 caller()->CreateAndSetAndSignalOffer();
4862 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4863 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4864 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4865
4866 MediaExpectations media_expectations;
4867 media_expectations.ExpectBidirectionalAudioAndVideo();
4868 EXPECT_TRUE(ExpectNewFrames(media_expectations));
4869}
4870
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004871// Verify that a SSLCertificateVerifier passed in through
4872// PeerConnectionDependencies is actually used by the underlying SSL
4873// implementation to determine whether a certificate presented by the TURN
4874// server is accepted by the client. Note that openssladapter_unittest.cc
4875// contains more detailed, lower-level tests.
4876TEST_P(PeerConnectionIntegrationTest,
4877 SSLCertificateVerifierUsedForTurnConnections) {
4878 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4879 3478};
4880 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4881
4882 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4883 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004884 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4885 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004886
4887 webrtc::PeerConnectionInterface::IceServer ice_server;
4888 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4889 ice_server.username = "test";
4890 ice_server.password = "test";
4891
4892 PeerConnectionInterface::RTCConfiguration client_1_config;
4893 client_1_config.servers.push_back(ice_server);
4894 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4895
4896 PeerConnectionInterface::RTCConfiguration client_2_config;
4897 client_2_config.servers.push_back(ice_server);
4898 // Setting the type to kRelay forces the connection to go through a TURN
4899 // server.
4900 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4901
4902 // Get a copy to the pointer so we can verify calls later.
4903 rtc::TestCertificateVerifier* client_1_cert_verifier =
4904 new rtc::TestCertificateVerifier();
4905 client_1_cert_verifier->verify_certificate_ = true;
4906 rtc::TestCertificateVerifier* client_2_cert_verifier =
4907 new rtc::TestCertificateVerifier();
4908 client_2_cert_verifier->verify_certificate_ = true;
4909
4910 // Create the dependencies with the test certificate verifier.
4911 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4912 client_1_deps.tls_cert_verifier =
4913 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4914 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4915 client_2_deps.tls_cert_verifier =
4916 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4917
4918 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4919 client_1_config, std::move(client_1_deps), client_2_config,
4920 std::move(client_2_deps)));
4921 ConnectFakeSignaling();
4922
4923 // Set "offer to receive audio/video" without adding any tracks, so we just
4924 // set up ICE/DTLS with no media.
4925 PeerConnectionInterface::RTCOfferAnswerOptions options;
4926 options.offer_to_receive_audio = 1;
4927 options.offer_to_receive_video = 1;
4928 caller()->SetOfferAnswerOptions(options);
4929 caller()->CreateAndSetAndSignalOffer();
4930 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
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
4936TEST_P(PeerConnectionIntegrationTest,
4937 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
4938 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4939 3478};
4940 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4941
4942 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4943 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004944 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4945 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004946
4947 webrtc::PeerConnectionInterface::IceServer ice_server;
4948 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4949 ice_server.username = "test";
4950 ice_server.password = "test";
4951
4952 PeerConnectionInterface::RTCConfiguration client_1_config;
4953 client_1_config.servers.push_back(ice_server);
4954 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4955
4956 PeerConnectionInterface::RTCConfiguration client_2_config;
4957 client_2_config.servers.push_back(ice_server);
4958 // Setting the type to kRelay forces the connection to go through a TURN
4959 // server.
4960 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4961
4962 // Get a copy to the pointer so we can verify calls later.
4963 rtc::TestCertificateVerifier* client_1_cert_verifier =
4964 new rtc::TestCertificateVerifier();
4965 client_1_cert_verifier->verify_certificate_ = false;
4966 rtc::TestCertificateVerifier* client_2_cert_verifier =
4967 new rtc::TestCertificateVerifier();
4968 client_2_cert_verifier->verify_certificate_ = false;
4969
4970 // Create the dependencies with the test certificate verifier.
4971 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4972 client_1_deps.tls_cert_verifier =
4973 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4974 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4975 client_2_deps.tls_cert_verifier =
4976 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4977
4978 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4979 client_1_config, std::move(client_1_deps), client_2_config,
4980 std::move(client_2_deps)));
4981 ConnectFakeSignaling();
4982
4983 // Set "offer to receive audio/video" without adding any tracks, so we just
4984 // set up ICE/DTLS with no media.
4985 PeerConnectionInterface::RTCOfferAnswerOptions options;
4986 options.offer_to_receive_audio = 1;
4987 options.offer_to_receive_video = 1;
4988 caller()->SetOfferAnswerOptions(options);
4989 caller()->CreateAndSetAndSignalOffer();
4990 bool wait_res = true;
4991 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
4992 // properly, should be able to just wait for a state of "failed" instead of
4993 // waiting a fixed 10 seconds.
4994 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
4995 ASSERT_FALSE(wait_res);
4996
4997 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4998 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004999}
5000
Qingsi Wang25ec8882019-11-15 12:33:05 -08005001// Test that the injected ICE transport factory is used to create ICE transports
5002// for WebRTC connections.
5003TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
5004 PeerConnectionInterface::RTCConfiguration default_config;
5005 PeerConnectionDependencies dependencies(nullptr);
5006 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
5007 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
5008 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02005009 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
5010 std::move(dependencies), nullptr,
5011 /*reset_encoder_factory=*/false,
5012 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08005013 ASSERT_TRUE(wrapper);
5014 wrapper->CreateDataChannel();
5015 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
5016 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5017 wrapper->pc()->SetLocalDescription(observer,
5018 wrapper->CreateOfferAndWait().release());
5019}
5020
deadbeefc964d0b2017-04-03 10:03:35 -07005021// Test that audio and video flow end-to-end when codec names don't use the
5022// expected casing, given that they're supposed to be case insensitive. To test
5023// this, all but one codec is removed from each media description, and its
5024// casing is changed.
5025//
5026// In the past, this has regressed and caused crashes/black video, due to the
5027// fact that code at some layers was doing case-insensitive comparisons and
5028// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005029TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07005030 ASSERT_TRUE(CreatePeerConnectionWrappers());
5031 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08005032 caller()->AddAudioVideoTracks();
5033 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07005034
5035 // Remove all but one audio/video codec (opus and VP8), and change the
5036 // casing of the caller's generated offer.
5037 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
5038 cricket::AudioContentDescription* audio =
5039 GetFirstAudioContentDescription(description);
5040 ASSERT_NE(nullptr, audio);
5041 auto audio_codecs = audio->codecs();
5042 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
5043 [](const cricket::AudioCodec& codec) {
5044 return codec.name != "opus";
5045 }),
5046 audio_codecs.end());
5047 ASSERT_EQ(1u, audio_codecs.size());
5048 audio_codecs[0].name = "OpUs";
5049 audio->set_codecs(audio_codecs);
5050
5051 cricket::VideoContentDescription* video =
5052 GetFirstVideoContentDescription(description);
5053 ASSERT_NE(nullptr, video);
5054 auto video_codecs = video->codecs();
5055 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
5056 [](const cricket::VideoCodec& codec) {
5057 return codec.name != "VP8";
5058 }),
5059 video_codecs.end());
5060 ASSERT_EQ(1u, video_codecs.size());
5061 video_codecs[0].name = "vP8";
5062 video->set_codecs(video_codecs);
5063 });
5064
5065 caller()->CreateAndSetAndSignalOffer();
5066 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5067
5068 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005069 MediaExpectations media_expectations;
5070 media_expectations.ExpectBidirectionalAudioAndVideo();
5071 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07005072}
5073
Jonas Oreland49ac5952018-09-26 16:04:32 +02005074TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07005075 ASSERT_TRUE(CreatePeerConnectionWrappers());
5076 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08005077 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07005078 caller()->CreateAndSetAndSignalOffer();
5079 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07005080 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005081 MediaExpectations media_expectations;
5082 media_expectations.CalleeExpectsSomeAudio(1);
5083 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02005084 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07005085 auto receiver = callee()->pc()->GetReceivers()[0];
5086 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02005087 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07005088 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
5089 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02005090 sources[0].source_id());
5091 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
5092}
5093
5094TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
5095 ASSERT_TRUE(CreatePeerConnectionWrappers());
5096 ConnectFakeSignaling();
5097 caller()->AddVideoTrack();
5098 caller()->CreateAndSetAndSignalOffer();
5099 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5100 // Wait for one video frame to be received by the callee.
5101 MediaExpectations media_expectations;
5102 media_expectations.CalleeExpectsSomeVideo(1);
5103 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5104 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
5105 auto receiver = callee()->pc()->GetReceivers()[0];
5106 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
5107 auto sources = receiver->GetSources();
5108 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02005109 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02005110 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
5111 sources[0].source_id());
5112 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07005113}
5114
deadbeef2f425aa2017-04-14 10:41:32 -07005115// Test that if a track is removed and added again with a different stream ID,
5116// the new stream ID is successfully communicated in SDP and media continues to
5117// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005118// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
5119// it will not reuse a transceiver that has already been sending. After creating
5120// a new transceiver it tries to create an offer with two senders of the same
5121// track ids and it fails.
5122TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07005123 ASSERT_TRUE(CreatePeerConnectionWrappers());
5124 ConnectFakeSignaling();
5125
deadbeef2f425aa2017-04-14 10:41:32 -07005126 // Add track using stream 1, do offer/answer.
5127 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
5128 caller()->CreateLocalAudioTrack();
5129 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07005130 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07005131 caller()->CreateAndSetAndSignalOffer();
5132 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005133 {
5134 MediaExpectations media_expectations;
5135 media_expectations.CalleeExpectsSomeAudio(1);
5136 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5137 }
deadbeef2f425aa2017-04-14 10:41:32 -07005138 // Remove the sender, and create a new one with the new stream.
5139 caller()->pc()->RemoveTrack(sender);
Steve Antond78323f2018-07-11 11:13:44 -07005140 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07005141 caller()->CreateAndSetAndSignalOffer();
5142 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5143 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005144 {
5145 MediaExpectations media_expectations;
5146 media_expectations.CalleeExpectsSomeAudio();
5147 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5148 }
deadbeef2f425aa2017-04-14 10:41:32 -07005149}
5150
Seth Hampson2f0d7022018-02-20 11:54:42 -08005151TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02005152 ASSERT_TRUE(CreatePeerConnectionWrappers());
5153 ConnectFakeSignaling();
5154
Mirko Bonadei317a1f02019-09-17 17:06:18 +02005155 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02005156 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
5157 ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true));
Elad Alon99c3fe52017-10-13 16:29:40 +02005158 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01005159 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
5160 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02005161
Steve Anton15324772018-01-16 10:26:49 -08005162 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02005163 caller()->CreateAndSetAndSignalOffer();
5164 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5165}
5166
Steve Antonede9ca52017-10-16 13:04:27 -07005167// Test that if candidates are only signaled by applying full session
5168// descriptions (instead of using AddIceCandidate), the peers can connect to
5169// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005170TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07005171 ASSERT_TRUE(CreatePeerConnectionWrappers());
5172 // Each side will signal the session descriptions but not candidates.
5173 ConnectFakeSignalingForSdpOnly();
5174
5175 // Add audio video track and exchange the initial offer/answer with media
5176 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08005177 caller()->AddAudioVideoTracks();
5178 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07005179 caller()->CreateAndSetAndSignalOffer();
5180
5181 // Wait for all candidates to be gathered on both the caller and callee.
5182 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
5183 caller()->ice_gathering_state(), kDefaultTimeout);
5184 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
5185 callee()->ice_gathering_state(), kDefaultTimeout);
5186
5187 // The candidates will now be included in the session description, so
5188 // signaling them will start the ICE connection.
5189 caller()->CreateAndSetAndSignalOffer();
5190 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5191
5192 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005193 MediaExpectations media_expectations;
5194 media_expectations.ExpectBidirectionalAudioAndVideo();
5195 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07005196}
5197
henrika5f6bf242017-11-01 11:06:56 +01005198// Test that SetAudioPlayout can be used to disable audio playout from the
5199// start, then later enable it. This may be useful, for example, if the caller
5200// needs to play a local ringtone until some event occurs, after which it
5201// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005202TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01005203 ASSERT_TRUE(CreatePeerConnectionWrappers());
5204 ConnectFakeSignaling();
5205
5206 // Set up audio-only call where audio playout is disabled on caller's side.
5207 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08005208 caller()->AddAudioTrack();
5209 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01005210 caller()->CreateAndSetAndSignalOffer();
5211 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5212
5213 // Pump messages for a second.
5214 WAIT(false, 1000);
5215 // Since audio playout is disabled, the caller shouldn't have received
5216 // anything (at the playout level, at least).
5217 EXPECT_EQ(0, caller()->audio_frames_received());
5218 // As a sanity check, make sure the callee (for which playout isn't disabled)
5219 // did still see frames on its audio level.
5220 ASSERT_GT(callee()->audio_frames_received(), 0);
5221
5222 // Enable playout again, and ensure audio starts flowing.
5223 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005224 MediaExpectations media_expectations;
5225 media_expectations.ExpectBidirectionalAudio();
5226 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01005227}
5228
5229double GetAudioEnergyStat(PeerConnectionWrapper* pc) {
5230 auto report = pc->NewGetStats();
5231 auto track_stats_list =
5232 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
5233 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
5234 for (const auto* track_stats : track_stats_list) {
5235 if (track_stats->remote_source.is_defined() &&
5236 *track_stats->remote_source) {
5237 remote_track_stats = track_stats;
5238 break;
5239 }
5240 }
5241
5242 if (!remote_track_stats->total_audio_energy.is_defined()) {
5243 return 0.0;
5244 }
5245 return *remote_track_stats->total_audio_energy;
5246}
5247
5248// Test that if audio playout is disabled via the SetAudioPlayout() method, then
5249// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005250TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01005251 DisableAudioPlayoutStillGeneratesAudioStats) {
5252 ASSERT_TRUE(CreatePeerConnectionWrappers());
5253 ConnectFakeSignaling();
5254
5255 // Set up audio-only call where playout is disabled but audio-processing is
5256 // still active.
Steve Anton15324772018-01-16 10:26:49 -08005257 caller()->AddAudioTrack();
5258 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01005259 caller()->pc()->SetAudioPlayout(false);
5260
5261 caller()->CreateAndSetAndSignalOffer();
5262 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5263
5264 // Wait for the callee to receive audio stats.
5265 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
5266}
5267
henrika4f167df2017-11-01 14:45:55 +01005268// Test that SetAudioRecording can be used to disable audio recording from the
5269// start, then later enable it. This may be useful, for example, if the caller
5270// wants to ensure that no audio resources are active before a certain state
5271// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005272TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01005273 ASSERT_TRUE(CreatePeerConnectionWrappers());
5274 ConnectFakeSignaling();
5275
5276 // Set up audio-only call where audio recording is disabled on caller's side.
5277 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08005278 caller()->AddAudioTrack();
5279 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01005280 caller()->CreateAndSetAndSignalOffer();
5281 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5282
5283 // Pump messages for a second.
5284 WAIT(false, 1000);
5285 // Since caller has disabled audio recording, the callee shouldn't have
5286 // received anything.
5287 EXPECT_EQ(0, callee()->audio_frames_received());
5288 // As a sanity check, make sure the caller did still see frames on its
5289 // audio level since audio recording is enabled on the calle side.
5290 ASSERT_GT(caller()->audio_frames_received(), 0);
5291
5292 // Enable audio recording again, and ensure audio starts flowing.
5293 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005294 MediaExpectations media_expectations;
5295 media_expectations.ExpectBidirectionalAudio();
5296 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01005297}
5298
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005299// Test that after closing PeerConnections, they stop sending any packets (ICE,
5300// DTLS, RTP...).
Seth Hampson2f0d7022018-02-20 11:54:42 -08005301TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005302 // Set up audio/video/data, wait for some frames to be received.
5303 ASSERT_TRUE(CreatePeerConnectionWrappers());
5304 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08005305 caller()->AddAudioVideoTracks();
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005306#ifdef WEBRTC_HAVE_SCTP
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005307 caller()->CreateDataChannel();
5308#endif
5309 caller()->CreateAndSetAndSignalOffer();
5310 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005311 MediaExpectations media_expectations;
5312 media_expectations.CalleeExpectsSomeAudioAndVideo();
5313 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005314 // Close PeerConnections.
Steve Antond91969e2019-05-30 12:27:03 -07005315 ClosePeerConnections();
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005316 // Pump messages for a second, and ensure no new packets end up sent.
5317 uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
5318 WAIT(false, 1000);
5319 uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
5320 EXPECT_EQ(sent_packets_a, sent_packets_b);
5321}
5322
Steve Anton7eca0932018-03-30 15:18:41 -07005323// Test that transport stats are generated by the RTCStatsCollector for a
5324// connection that only involves data channels. This is a regression test for
5325// crbug.com/826972.
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005326#ifdef WEBRTC_HAVE_SCTP
Steve Anton7eca0932018-03-30 15:18:41 -07005327TEST_P(PeerConnectionIntegrationTest,
5328 TransportStatsReportedForDataChannelOnlyConnection) {
5329 ASSERT_TRUE(CreatePeerConnectionWrappers());
5330 ConnectFakeSignaling();
5331 caller()->CreateDataChannel();
5332
5333 caller()->CreateAndSetAndSignalOffer();
5334 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5335 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
5336
5337 auto caller_report = caller()->NewGetStats();
5338 EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
5339 auto callee_report = callee()->NewGetStats();
5340 EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
5341}
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005342#endif // WEBRTC_HAVE_SCTP
Steve Anton7eca0932018-03-30 15:18:41 -07005343
Qingsi Wang7685e862018-06-11 20:15:46 -07005344TEST_P(PeerConnectionIntegrationTest,
5345 IceEventsGeneratedAndLoggedInRtcEventLog) {
5346 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
5347 ConnectFakeSignaling();
5348 PeerConnectionInterface::RTCOfferAnswerOptions options;
5349 options.offer_to_receive_audio = 1;
5350 caller()->SetOfferAnswerOptions(options);
5351 caller()->CreateAndSetAndSignalOffer();
5352 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
5353 ASSERT_NE(nullptr, caller()->event_log_factory());
5354 ASSERT_NE(nullptr, callee()->event_log_factory());
5355 webrtc::FakeRtcEventLog* caller_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01005356 caller()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07005357 webrtc::FakeRtcEventLog* callee_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01005358 callee()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07005359 ASSERT_NE(nullptr, caller_event_log);
5360 ASSERT_NE(nullptr, callee_event_log);
5361 int caller_ice_config_count = caller_event_log->GetEventCount(
5362 webrtc::RtcEvent::Type::IceCandidatePairConfig);
5363 int caller_ice_event_count = caller_event_log->GetEventCount(
5364 webrtc::RtcEvent::Type::IceCandidatePairEvent);
5365 int callee_ice_config_count = callee_event_log->GetEventCount(
5366 webrtc::RtcEvent::Type::IceCandidatePairConfig);
5367 int callee_ice_event_count = callee_event_log->GetEventCount(
5368 webrtc::RtcEvent::Type::IceCandidatePairEvent);
5369 EXPECT_LT(0, caller_ice_config_count);
5370 EXPECT_LT(0, caller_ice_event_count);
5371 EXPECT_LT(0, callee_ice_config_count);
5372 EXPECT_LT(0, callee_ice_event_count);
5373}
5374
Qingsi Wangc129c352019-04-18 10:41:58 -07005375TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07005376 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
5377 3478};
5378 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
5379
5380 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
5381
5382 webrtc::PeerConnectionInterface::IceServer ice_server;
5383 ice_server.urls.push_back("turn:88.88.88.0:3478");
5384 ice_server.username = "test";
5385 ice_server.password = "test";
5386
5387 PeerConnectionInterface::RTCConfiguration caller_config;
5388 caller_config.servers.push_back(ice_server);
5389 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5390 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005391 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07005392
5393 PeerConnectionInterface::RTCConfiguration callee_config;
5394 callee_config.servers.push_back(ice_server);
5395 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5396 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005397 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07005398
5399 ASSERT_TRUE(
5400 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5401
5402 // Do normal offer/answer and wait for ICE to complete.
5403 ConnectFakeSignaling();
5404 caller()->AddAudioVideoTracks();
5405 callee()->AddAudioVideoTracks();
5406 caller()->CreateAndSetAndSignalOffer();
5407 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5408 // Since we are doing continual gathering, the ICE transport does not reach
5409 // kIceGatheringComplete (see
5410 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
5411 // kIceConnectionComplete.
5412 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
5413 caller()->ice_connection_state(), kDefaultTimeout);
5414 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
5415 callee()->ice_connection_state(), kDefaultTimeout);
5416 // Note that we cannot use the metric
5417 // |WebRTC.PeerConnection.CandidatePairType_UDP| in this test since this
5418 // metric is only populated when we reach kIceConnectionComplete in the
5419 // current implementation.
5420 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
5421 caller()->last_candidate_gathered().type());
5422 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
5423 callee()->last_candidate_gathered().type());
5424
5425 // Loosen the caller's candidate filter.
5426 caller_config = caller()->pc()->GetConfiguration();
5427 caller_config.type = webrtc::PeerConnectionInterface::kAll;
5428 caller()->pc()->SetConfiguration(caller_config);
5429 // We should have gathered a new host candidate.
5430 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
5431 caller()->last_candidate_gathered().type(), kDefaultTimeout);
5432
5433 // Loosen the callee's candidate filter.
5434 callee_config = callee()->pc()->GetConfiguration();
5435 callee_config.type = webrtc::PeerConnectionInterface::kAll;
5436 callee()->pc()->SetConfiguration(callee_config);
5437 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
5438 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02005439
5440 // Create an offer and verify that it does not contain an ICE restart (i.e new
5441 // ice credentials).
5442 std::string caller_ufrag_pre_offer = caller()
5443 ->pc()
5444 ->local_description()
5445 ->description()
5446 ->transport_infos()[0]
5447 .description.ice_ufrag;
5448 caller()->CreateAndSetAndSignalOffer();
5449 std::string caller_ufrag_post_offer = caller()
5450 ->pc()
5451 ->local_description()
5452 ->description()
5453 ->transport_infos()[0]
5454 .description.ice_ufrag;
5455 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07005456}
5457
Eldar Relloda13ea22019-06-01 12:23:43 +03005458TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03005459 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
5460 3478};
5461 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
5462
5463 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
5464
5465 webrtc::PeerConnectionInterface::IceServer ice_server;
5466 ice_server.urls.push_back("turn:88.88.88.0:3478");
5467 ice_server.username = "test";
5468 ice_server.password = "123";
5469
5470 PeerConnectionInterface::RTCConfiguration caller_config;
5471 caller_config.servers.push_back(ice_server);
5472 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5473 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5474
5475 PeerConnectionInterface::RTCConfiguration callee_config;
5476 callee_config.servers.push_back(ice_server);
5477 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5478 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5479
5480 ASSERT_TRUE(
5481 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5482
5483 // Do normal offer/answer and wait for ICE to complete.
5484 ConnectFakeSignaling();
5485 caller()->AddAudioVideoTracks();
5486 callee()->AddAudioVideoTracks();
5487 caller()->CreateAndSetAndSignalOffer();
5488 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5489 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
5490 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
5491 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02005492 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03005493}
5494
Eldar Rellofa8019c2020-05-14 11:59:33 +03005495TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
5496 webrtc::PeerConnectionInterface::IceServer ice_server;
5497 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
5498 ice_server.username = "test";
5499 ice_server.password = "test";
5500
5501 PeerConnectionInterface::RTCConfiguration caller_config;
5502 caller_config.servers.push_back(ice_server);
5503 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5504 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5505
5506 PeerConnectionInterface::RTCConfiguration callee_config;
5507 callee_config.servers.push_back(ice_server);
5508 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5509 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5510
5511 ASSERT_TRUE(
5512 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5513
5514 // Do normal offer/answer and wait for ICE to complete.
5515 ConnectFakeSignaling();
5516 caller()->AddAudioVideoTracks();
5517 callee()->AddAudioVideoTracks();
5518 caller()->CreateAndSetAndSignalOffer();
5519 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5520 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
5521 EXPECT_EQ(caller()->error_event().address, "");
5522}
5523
Eldar Rello5ab79e62019-10-09 18:29:44 +03005524TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5525 AudioKeepsFlowingAfterImplicitRollback) {
5526 PeerConnectionInterface::RTCConfiguration config;
5527 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5528 config.enable_implicit_rollback = true;
5529 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5530 ConnectFakeSignaling();
5531 caller()->AddAudioTrack();
5532 callee()->AddAudioTrack();
5533 caller()->CreateAndSetAndSignalOffer();
5534 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5535 MediaExpectations media_expectations;
5536 media_expectations.ExpectBidirectionalAudio();
5537 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5538 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
5539 caller()->AddVideoTrack();
5540 callee()->AddVideoTrack();
5541 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
5542 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5543 callee()->pc()->SetLocalDescription(observer,
5544 callee()->CreateOfferAndWait().release());
5545 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
5546 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
5547 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5548 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5549}
5550
5551TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5552 ImplicitRollbackVisitsStableState) {
5553 RTCConfiguration config;
5554 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5555 config.enable_implicit_rollback = true;
5556
5557 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5558
5559 rtc::scoped_refptr<MockSetSessionDescriptionObserver> sld_observer(
5560 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5561 callee()->pc()->SetLocalDescription(sld_observer,
5562 callee()->CreateOfferAndWait().release());
5563 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
5564 EXPECT_EQ(sld_observer->error(), "");
5565
5566 rtc::scoped_refptr<MockSetSessionDescriptionObserver> srd_observer(
5567 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5568 callee()->pc()->SetRemoteDescription(
5569 srd_observer, caller()->CreateOfferAndWait().release());
5570 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
5571 EXPECT_EQ(srd_observer->error(), "");
5572
5573 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
5574 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
5575 PeerConnectionInterface::kStable,
5576 PeerConnectionInterface::kHaveRemoteOffer));
5577}
5578
Eldar Rellobd9c33a2020-10-01 17:52:45 +03005579TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5580 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
5581 ASSERT_TRUE(CreatePeerConnectionWrappers());
5582 ConnectFakeSignaling();
5583 caller()->AddVideoTrack();
5584 callee()->AddVideoTrack();
5585 auto munger = [](cricket::SessionDescription* desc) {
5586 cricket::VideoContentDescription* video =
5587 GetFirstVideoContentDescription(desc);
5588 auto codecs = video->codecs();
5589 for (auto&& codec : codecs) {
5590 if (codec.name == "H264") {
5591 std::string value;
5592 // The parameter is not supposed to be present in SDP by default.
5593 EXPECT_FALSE(
5594 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
5595 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
5596 std::string(""));
5597 }
5598 }
5599 video->set_codecs(codecs);
5600 };
5601 // Munge local offer for SLD.
5602 caller()->SetGeneratedSdpMunger(munger);
5603 // Munge remote answer for SRD.
5604 caller()->SetReceivedSdpMunger(munger);
5605 caller()->CreateAndSetAndSignalOffer();
5606 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5607 // Observe that after munging the parameter is present in generated SDP.
5608 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
5609 cricket::VideoContentDescription* video =
5610 GetFirstVideoContentDescription(desc);
5611 for (auto&& codec : video->codecs()) {
5612 if (codec.name == "H264") {
5613 std::string value;
5614 EXPECT_TRUE(
5615 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
5616 }
5617 }
5618 });
5619 caller()->CreateOfferAndWait();
5620}
5621
Harald Alvestrand1a9be302020-12-11 14:53:59 +00005622TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00005623 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00005624 PeerConnectionInterface::RTCConfiguration config;
5625 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5626 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5627 ConnectFakeSignaling();
5628 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
5629
5630 caller()->CreateAndSetAndSignalOffer();
5631 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5632 int current_size = caller()->pc()->GetTransceivers().size();
5633 // Add more tracks until we get close to having issues.
5634 // Issues have been seen at:
5635 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005636 // - 16 tracks on android_arm_dbg (flaky)
5637 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00005638 // Double the number of tracks
5639 for (int i = 0; i < current_size; i++) {
5640 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
5641 }
5642 current_size = caller()->pc()->GetTransceivers().size();
5643 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
5644 auto start_time_ms = rtc::TimeMillis();
5645 caller()->CreateAndSetAndSignalOffer();
5646 // We want to stop when the time exceeds one second.
5647 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5648 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
5649 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
5650 ASSERT_GT(1000, elapsed_time_ms)
5651 << "Audio transceivers: Negotiation took too long after "
5652 << current_size << " tracks added";
5653 }
5654}
5655
5656TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5657 RenegotiateManyVideoTransceivers) {
5658 PeerConnectionInterface::RTCConfiguration config;
5659 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5660 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5661 ConnectFakeSignaling();
5662 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
5663
5664 caller()->CreateAndSetAndSignalOffer();
5665 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5666 int current_size = caller()->pc()->GetTransceivers().size();
5667 // Add more tracks until we get close to having issues.
5668 // Issues have been seen at:
5669 // - 96 on a Linux workstation
5670 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
5671 // - 32 on android_arm64_rel and linux_dbg bots
5672 while (current_size < 16) {
5673 // Double the number of tracks
5674 for (int i = 0; i < current_size; i++) {
5675 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
5676 }
5677 current_size = caller()->pc()->GetTransceivers().size();
5678 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
5679 auto start_time_ms = rtc::TimeMillis();
5680 caller()->CreateAndSetAndSignalOffer();
5681 // We want to stop when the time exceeds one second.
5682 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5683 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
5684 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
5685 ASSERT_GT(1000, elapsed_time_ms)
5686 << "Video transceivers: Negotiation took too long after "
5687 << current_size << " tracks added";
5688 }
5689}
5690
Harald Alvestrand94324f22021-01-13 12:31:53 +00005691TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5692 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
5693 PeerConnectionInterface::RTCConfiguration config;
5694 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5695 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5696 ConnectFakeSignaling();
5697 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005698 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00005699 caller()->CreateAndSetAndSignalOffer();
5700 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5701 // Wait until we can see the audio flowing.
5702 MediaExpectations media_expectations;
5703 media_expectations.CalleeExpectsSomeAudio();
5704 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5705
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005706 // Get the baseline numbers for audio_packets and audio_delay
5707 // in both directions.
5708 caller()->StartWatchingDelayStats();
5709 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00005710
5711 int current_size = caller()->pc()->GetTransceivers().size();
5712 // Add more tracks until we get close to having issues.
5713 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005714 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00005715 // Double the number of tracks
5716 for (int i = 0; i < current_size; i++) {
5717 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
5718 }
5719 current_size = caller()->pc()->GetTransceivers().size();
5720 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
5721 auto start_time_ms = rtc::TimeMillis();
5722 caller()->CreateAndSetAndSignalOffer();
5723 // We want to stop when the time exceeds one second.
5724 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5725 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
5726 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
5727 // This is a guard against the test using excessive amounts of time.
5728 ASSERT_GT(5000, elapsed_time_ms)
5729 << "Video transceivers: Negotiation took too long after "
5730 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005731 caller()->UpdateDelayStats("caller reception", current_size);
5732 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00005733 }
5734}
5735
Mirko Bonadeic84f6612019-01-31 12:20:57 +01005736INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
5737 PeerConnectionIntegrationTest,
5738 Values(SdpSemantics::kPlanB,
5739 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-17 17:41:02 -08005740
Yves Gerey100fe632020-01-17 19:15:53 +01005741INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
5742 PeerConnectionIntegrationTestWithFakeClock,
5743 Values(SdpSemantics::kPlanB,
5744 SdpSemantics::kUnifiedPlan));
5745
Steve Anton74255ff2018-01-24 18:32:57 -08005746// Tests that verify interoperability between Plan B and Unified Plan
5747// PeerConnections.
5748class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08005749 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08005750 public ::testing::WithParamInterface<
5751 std::tuple<SdpSemantics, SdpSemantics>> {
5752 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08005753 // Setting the SdpSemantics for the base test to kDefault does not matter
5754 // because we specify not to use the test semantics when creating
5755 // PeerConnectionWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08005756 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07005757 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08005758 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08005759 callee_semantics_(std::get<1>(GetParam())) {}
5760
5761 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07005762 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
5763 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08005764 }
5765
5766 const SdpSemantics caller_semantics_;
5767 const SdpSemantics callee_semantics_;
5768};
5769
5770TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
5771 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5772 ConnectFakeSignaling();
5773
5774 caller()->CreateAndSetAndSignalOffer();
5775 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5776}
5777
5778TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
5779 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5780 ConnectFakeSignaling();
5781 auto audio_sender = caller()->AddAudioTrack();
5782
5783 caller()->CreateAndSetAndSignalOffer();
5784 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5785
5786 // Verify that one audio receiver has been created on the remote and that it
5787 // has the same track ID as the sending track.
5788 auto receivers = callee()->pc()->GetReceivers();
5789 ASSERT_EQ(1u, receivers.size());
5790 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
5791 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
5792
Seth Hampson2f0d7022018-02-20 11:54:42 -08005793 MediaExpectations media_expectations;
5794 media_expectations.CalleeExpectsSomeAudio();
5795 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005796}
5797
5798TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
5799 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5800 ConnectFakeSignaling();
5801 auto video_sender = caller()->AddVideoTrack();
5802 auto audio_sender = caller()->AddAudioTrack();
5803
5804 caller()->CreateAndSetAndSignalOffer();
5805 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5806
5807 // Verify that one audio and one video receiver have been created on the
5808 // remote and that they have the same track IDs as the sending tracks.
5809 auto audio_receivers =
5810 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
5811 ASSERT_EQ(1u, audio_receivers.size());
5812 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
5813 auto video_receivers =
5814 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
5815 ASSERT_EQ(1u, video_receivers.size());
5816 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
5817
Seth Hampson2f0d7022018-02-20 11:54:42 -08005818 MediaExpectations media_expectations;
5819 media_expectations.CalleeExpectsSomeAudioAndVideo();
5820 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005821}
5822
5823TEST_P(PeerConnectionIntegrationInteropTest,
5824 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
5825 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5826 ConnectFakeSignaling();
5827 caller()->AddAudioVideoTracks();
5828 callee()->AddAudioVideoTracks();
5829
5830 caller()->CreateAndSetAndSignalOffer();
5831 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5832
Seth Hampson2f0d7022018-02-20 11:54:42 -08005833 MediaExpectations media_expectations;
5834 media_expectations.ExpectBidirectionalAudioAndVideo();
5835 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005836}
5837
5838TEST_P(PeerConnectionIntegrationInteropTest,
5839 ReverseRolesOneAudioLocalToOneVideoRemote) {
5840 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5841 ConnectFakeSignaling();
5842 caller()->AddAudioTrack();
5843 callee()->AddVideoTrack();
5844
5845 caller()->CreateAndSetAndSignalOffer();
5846 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5847
5848 // Verify that only the audio track has been negotiated.
5849 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
5850 // Might also check that the callee's NegotiationNeeded flag is set.
5851
5852 // Reverse roles.
5853 callee()->CreateAndSetAndSignalOffer();
5854 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5855
Seth Hampson2f0d7022018-02-20 11:54:42 -08005856 MediaExpectations media_expectations;
5857 media_expectations.CallerExpectsSomeVideo();
5858 media_expectations.CalleeExpectsSomeAudio();
5859 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005860}
5861
Mirko Bonadeic84f6612019-01-31 12:20:57 +01005862INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07005863 PeerConnectionIntegrationTest,
5864 PeerConnectionIntegrationInteropTest,
5865 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
5866 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
5867
5868// Test that if the Unified Plan side offers two video tracks then the Plan B
5869// side will only see the first one and ignore the second.
5870TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07005871 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
5872 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08005873 ConnectFakeSignaling();
5874 auto first_sender = caller()->AddVideoTrack();
5875 caller()->AddVideoTrack();
5876
5877 caller()->CreateAndSetAndSignalOffer();
5878 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5879
5880 // Verify that there is only one receiver and it corresponds to the first
5881 // added track.
5882 auto receivers = callee()->pc()->GetReceivers();
5883 ASSERT_EQ(1u, receivers.size());
5884 EXPECT_TRUE(receivers[0]->track()->enabled());
5885 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
5886
Seth Hampson2f0d7022018-02-20 11:54:42 -08005887 MediaExpectations media_expectations;
5888 media_expectations.CalleeExpectsSomeVideo();
5889 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005890}
5891
Steve Anton2bed3972019-01-04 17:04:30 -08005892// Test that if the initial offer tagged BUNDLE section is rejected due to its
5893// associated RtpTransceiver being stopped and another transceiver is added,
5894// then renegotiation causes the callee to receive the new video track without
5895// error.
5896// This is a regression test for bugs.webrtc.org/9954
5897TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5898 ReOfferWithStoppedBundleTaggedTransceiver) {
5899 RTCConfiguration config;
5900 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
5901 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5902 ConnectFakeSignaling();
5903 auto audio_transceiver_or_error =
5904 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5905 ASSERT_TRUE(audio_transceiver_or_error.ok());
5906 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5907
5908 caller()->CreateAndSetAndSignalOffer();
5909 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5910 {
5911 MediaExpectations media_expectations;
5912 media_expectations.CalleeExpectsSomeAudio();
5913 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5914 }
5915
Harald Alvestrand6060df52020-08-11 09:54:02 +02005916 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08005917 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
5918
5919 caller()->CreateAndSetAndSignalOffer();
5920 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5921 {
5922 MediaExpectations media_expectations;
5923 media_expectations.CalleeExpectsSomeVideo();
5924 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5925 }
5926}
5927
Harald Alvestrandbedb6052020-08-20 14:50:10 +02005928TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5929 StopTransceiverRemovesDtlsTransports) {
5930 RTCConfiguration config;
5931 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5932 ConnectFakeSignaling();
5933 auto audio_transceiver_or_error =
5934 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5935 ASSERT_TRUE(audio_transceiver_or_error.ok());
5936 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5937
5938 caller()->CreateAndSetAndSignalOffer();
5939 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5940
5941 audio_transceiver->StopStandard();
5942 caller()->CreateAndSetAndSignalOffer();
5943 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5944 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
5945 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
5946 caller()->pc()->ice_gathering_state());
5947 EXPECT_THAT(caller()->ice_gathering_state_history(),
5948 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
5949 PeerConnectionInterface::kIceGatheringComplete,
5950 PeerConnectionInterface::kIceGatheringNew));
5951}
5952
Harald Alvestrand1ee33252020-09-24 13:31:15 +00005953TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00005954 StopTransceiverStopsAndRemovesTransceivers) {
5955 RTCConfiguration config;
5956 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5957 ConnectFakeSignaling();
5958 auto audio_transceiver_or_error =
5959 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5960 ASSERT_TRUE(audio_transceiver_or_error.ok());
5961 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
5962
5963 caller()->CreateAndSetAndSignalOffer();
5964 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5965 caller_transceiver->StopStandard();
5966
5967 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
5968 caller()->CreateAndSetAndSignalOffer();
5969 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5970 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
5971 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
5972 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
5973 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
5974 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
5975 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
5976 EXPECT_TRUE(caller_transceiver->stopped());
5977 EXPECT_TRUE(callee_transceiver->stopped());
5978}
5979
5980TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00005981 StopTransceiverEndsIncomingAudioTrack) {
5982 RTCConfiguration config;
5983 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5984 ConnectFakeSignaling();
5985 auto audio_transceiver_or_error =
5986 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5987 ASSERT_TRUE(audio_transceiver_or_error.ok());
5988 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5989
5990 caller()->CreateAndSetAndSignalOffer();
5991 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5992 auto caller_track = audio_transceiver->receiver()->track();
5993 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
5994 audio_transceiver->StopStandard();
5995 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
5996 caller_track->state());
5997 caller()->CreateAndSetAndSignalOffer();
5998 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5999 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
6000 callee_track->state());
6001}
6002
6003TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
6004 StopTransceiverEndsIncomingVideoTrack) {
6005 RTCConfiguration config;
6006 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
6007 ConnectFakeSignaling();
6008 auto audio_transceiver_or_error =
6009 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
6010 ASSERT_TRUE(audio_transceiver_or_error.ok());
6011 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
6012
6013 caller()->CreateAndSetAndSignalOffer();
6014 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
6015 auto caller_track = audio_transceiver->receiver()->track();
6016 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
6017 audio_transceiver->StopStandard();
6018 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
6019 caller_track->state());
6020 caller()->CreateAndSetAndSignalOffer();
6021 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
6022 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
6023 callee_track->state());
6024}
6025
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01006026#ifdef WEBRTC_HAVE_SCTP
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02006027
6028TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
6029 EndToEndCallWithBundledSctpDataChannel) {
6030 ASSERT_TRUE(CreatePeerConnectionWrappers());
6031 ConnectFakeSignaling();
6032 caller()->CreateDataChannel();
6033 caller()->AddAudioVideoTracks();
6034 callee()->AddAudioVideoTracks();
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02006035 caller()->CreateAndSetAndSignalOffer();
6036 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +01006037 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
6038 ASSERT_EQ_WAIT(SctpTransportState::kConnected,
6039 caller()->pc()->GetSctpTransport()->Information().state(),
6040 kDefaultTimeout);
6041 });
Harald Alvestrand17ea0682019-12-13 11:51:04 +01006042 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
6043 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
6044}
6045
6046TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
6047 EndToEndCallWithDataChannelOnlyConnects) {
6048 ASSERT_TRUE(CreatePeerConnectionWrappers());
6049 ConnectFakeSignaling();
6050 caller()->CreateDataChannel();
6051 caller()->CreateAndSetAndSignalOffer();
6052 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
6053 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
6054 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
6055 ASSERT_TRUE(caller()->data_observer()->IsOpen());
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02006056}
6057
Harald Alvestrand2697ac12019-12-16 10:37:04 +01006058TEST_F(PeerConnectionIntegrationTestUnifiedPlan, DataChannelClosesWhenClosed) {
6059 ASSERT_TRUE(CreatePeerConnectionWrappers());
6060 ConnectFakeSignaling();
6061 caller()->CreateDataChannel();
6062 caller()->CreateAndSetAndSignalOffer();
6063 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
6064 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
6065 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
6066 caller()->data_channel()->Close();
6067 ASSERT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
6068}
6069
6070TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
6071 DataChannelClosesWhenClosedReverse) {
6072 ASSERT_TRUE(CreatePeerConnectionWrappers());
6073 ConnectFakeSignaling();
6074 caller()->CreateDataChannel();
6075 caller()->CreateAndSetAndSignalOffer();
6076 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
6077 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
6078 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
6079 callee()->data_channel()->Close();
6080 ASSERT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
6081}
6082
6083TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
6084 DataChannelClosesWhenPeerConnectionClosed) {
6085 ASSERT_TRUE(CreatePeerConnectionWrappers());
6086 ConnectFakeSignaling();
6087 caller()->CreateDataChannel();
6088 caller()->CreateAndSetAndSignalOffer();
6089 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
6090 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
6091 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
6092 caller()->pc()->Close();
6093 ASSERT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
6094}
6095
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01006096#endif // WEBRTC_HAVE_SCTP
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02006097
deadbeef1dcb1642017-03-29 21:08:16 -07006098} // namespace
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01006099} // namespace webrtc
deadbeef1dcb1642017-03-29 21:08:16 -07006100
6101#endif // if !defined(THREAD_SANITIZER)