blob: df8d6c15ec923258ca075c70faabc950bdf51cb6 [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;
636 // An average relative packet arrival delay over the renegotiation of
637 // > 100 ms indicates that something is dramatically wrong, and will impact
638 // quality for sure.
Harald Alvestrandcbacec52021-01-14 13:13:42 +0000639 EXPECT_GT(0.1, recent_delay) << tag << " size " << desc_size;
640 auto delta_samples =
641 *track_stats->total_samples_received - audio_samples_stat_;
642 auto delta_concealed =
643 *track_stats->concealed_samples - audio_concealed_stat_;
644 // These limits should be adjusted down as we improve:
645 //
646 // Concealing more than 4000 samples during a renegotiation is unacceptable.
647 // Concealing more than 20% of samples during a renegotiation is
648 // unacceptable.
649
650 // Current lowest scores:
651 // linux_more_configs bot at conceal rate 0.516
652 // linux_more_configs bot at conceal count 5184
653 // android_arm_rel at conceal count 9241
654 EXPECT_GT(15000U, delta_concealed) << "Concealed " << delta_concealed
655 << " of " << delta_samples << " samples";
656 if (delta_samples > 0) {
657 EXPECT_GT(0.6, 1.0 * delta_concealed / delta_samples)
658 << "Concealed " << delta_concealed << " of " << delta_samples
659 << " samples";
660 }
Harald Alvestrandcc6ae442021-01-18 08:06:23 +0000661 // Increment trailing counters
662 audio_packets_stat_ = *rtp_stats->packets_received;
663 audio_delay_stat_ = *track_stats->relative_packet_arrival_delay;
Harald Alvestrandcbacec52021-01-14 13:13:42 +0000664 audio_samples_stat_ = *track_stats->total_samples_received;
665 audio_concealed_stat_ = *track_stats->concealed_samples;
Harald Alvestrandcc6ae442021-01-18 08:06:23 +0000666 }
667
deadbeef1dcb1642017-03-29 21:08:16 -0700668 private:
669 explicit PeerConnectionWrapper(const std::string& debug_name)
670 : debug_name_(debug_name) {}
671
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800672 bool Init(
673 const PeerConnectionFactory::Options* options,
674 const PeerConnectionInterface::RTCConfiguration* config,
675 webrtc::PeerConnectionDependencies dependencies,
676 rtc::Thread* network_thread,
677 rtc::Thread* worker_thread,
678 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory,
Johannes Kron3e983682020-03-29 22:17:00 +0200679 bool reset_encoder_factory,
680 bool reset_decoder_factory) {
deadbeef1dcb1642017-03-29 21:08:16 -0700681 // There's an error in this test code if Init ends up being called twice.
682 RTC_DCHECK(!peer_connection_);
683 RTC_DCHECK(!peer_connection_factory_);
684
685 fake_network_manager_.reset(new rtc::FakeNetworkManager());
Steve Antonede9ca52017-10-16 13:04:27 -0700686 fake_network_manager_->AddInterface(kDefaultLocalAddress);
deadbeef1dcb1642017-03-29 21:08:16 -0700687
688 std::unique_ptr<cricket::PortAllocator> port_allocator(
689 new cricket::BasicPortAllocator(fake_network_manager_.get()));
Steve Antonede9ca52017-10-16 13:04:27 -0700690 port_allocator_ = port_allocator.get();
deadbeef1dcb1642017-03-29 21:08:16 -0700691 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
692 if (!fake_audio_capture_module_) {
693 return false;
694 }
deadbeef1dcb1642017-03-29 21:08:16 -0700695 rtc::Thread* const signaling_thread = rtc::Thread::Current();
Qingsi Wang7685e862018-06-11 20:15:46 -0700696
697 webrtc::PeerConnectionFactoryDependencies pc_factory_dependencies;
698 pc_factory_dependencies.network_thread = network_thread;
699 pc_factory_dependencies.worker_thread = worker_thread;
700 pc_factory_dependencies.signaling_thread = signaling_thread;
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200701 pc_factory_dependencies.task_queue_factory =
702 webrtc::CreateDefaultTaskQueueFactory();
Erik Språngceb44952020-09-22 11:36:35 +0200703 pc_factory_dependencies.trials = std::make_unique<FieldTrialBasedConfig>();
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200704 cricket::MediaEngineDependencies media_deps;
705 media_deps.task_queue_factory =
706 pc_factory_dependencies.task_queue_factory.get();
707 media_deps.adm = fake_audio_capture_module_;
708 webrtc::SetMediaEngineDefaults(&media_deps);
Johannes Kron3e983682020-03-29 22:17:00 +0200709
710 if (reset_encoder_factory) {
711 media_deps.video_encoder_factory.reset();
712 }
713 if (reset_decoder_factory) {
714 media_deps.video_decoder_factory.reset();
715 }
716
Per Åhgrencc73ed32020-04-26 23:56:17 +0200717 if (!media_deps.audio_processing) {
718 // If the standard Creation method for APM returns a null pointer, instead
719 // use the builder for testing to create an APM object.
720 media_deps.audio_processing = AudioProcessingBuilderForTesting().Create();
721 }
722
Erik Språngceb44952020-09-22 11:36:35 +0200723 media_deps.trials = pc_factory_dependencies.trials.get();
724
Qingsi Wang7685e862018-06-11 20:15:46 -0700725 pc_factory_dependencies.media_engine =
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200726 cricket::CreateMediaEngine(std::move(media_deps));
Qingsi Wang7685e862018-06-11 20:15:46 -0700727 pc_factory_dependencies.call_factory = webrtc::CreateCallFactory();
728 if (event_log_factory) {
729 event_log_factory_ = event_log_factory.get();
730 pc_factory_dependencies.event_log_factory = std::move(event_log_factory);
731 } else {
732 pc_factory_dependencies.event_log_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200733 std::make_unique<webrtc::RtcEventLogFactory>(
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200734 pc_factory_dependencies.task_queue_factory.get());
Qingsi Wang7685e862018-06-11 20:15:46 -0700735 }
736 peer_connection_factory_ = webrtc::CreateModularPeerConnectionFactory(
737 std::move(pc_factory_dependencies));
738
deadbeef1dcb1642017-03-29 21:08:16 -0700739 if (!peer_connection_factory_) {
740 return false;
741 }
742 if (options) {
743 peer_connection_factory_->SetOptions(*options);
744 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800745 if (config) {
746 sdp_semantics_ = config->sdp_semantics;
747 }
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700748
749 dependencies.allocator = std::move(port_allocator);
Niels Möllerf06f9232018-08-07 12:32:18 +0200750 peer_connection_ = CreatePeerConnection(config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700751 return peer_connection_.get() != nullptr;
752 }
753
754 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(
deadbeef1dcb1642017-03-29 21:08:16 -0700755 const PeerConnectionInterface::RTCConfiguration* config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700756 webrtc::PeerConnectionDependencies dependencies) {
deadbeef1dcb1642017-03-29 21:08:16 -0700757 PeerConnectionInterface::RTCConfiguration modified_config;
758 // If |config| is null, this will result in a default configuration being
759 // used.
760 if (config) {
761 modified_config = *config;
762 }
763 // Disable resolution adaptation; we don't want it interfering with the
764 // test results.
765 // TODO(deadbeef): Do something more robust. Since we're testing for aspect
766 // ratios and not specific resolutions, is this even necessary?
767 modified_config.set_cpu_adaptation(false);
768
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700769 dependencies.observer = this;
deadbeef1dcb1642017-03-29 21:08:16 -0700770 return peer_connection_factory_->CreatePeerConnection(
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700771 modified_config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700772 }
773
774 void set_signaling_message_receiver(
775 SignalingMessageReceiver* signaling_message_receiver) {
776 signaling_message_receiver_ = signaling_message_receiver;
777 }
778
779 void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; }
780
Steve Antonede9ca52017-10-16 13:04:27 -0700781 void set_signal_ice_candidates(bool signal) {
782 signal_ice_candidates_ = signal;
783 }
784
deadbeef1dcb1642017-03-29 21:08:16 -0700785 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
Niels Möller5c7efe72018-05-11 10:34:46 +0200786 webrtc::FakePeriodicVideoSource::Config config) {
deadbeef1dcb1642017-03-29 21:08:16 -0700787 // Set max frame rate to 10fps to reduce the risk of test flakiness.
788 // TODO(deadbeef): Do something more robust.
Niels Möller5c7efe72018-05-11 10:34:46 +0200789 config.frame_interval_ms = 100;
deadbeef1dcb1642017-03-29 21:08:16 -0700790
Niels Möller5c7efe72018-05-11 10:34:46 +0200791 video_track_sources_.emplace_back(
Niels Möller0f405822018-05-17 09:16:41 +0200792 new rtc::RefCountedObject<webrtc::FakePeriodicVideoTrackSource>(
793 config, false /* remote */));
deadbeef1dcb1642017-03-29 21:08:16 -0700794 rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
Niels Möller5c7efe72018-05-11 10:34:46 +0200795 peer_connection_factory_->CreateVideoTrack(
796 rtc::CreateRandomUuid(), video_track_sources_.back()));
deadbeef1dcb1642017-03-29 21:08:16 -0700797 if (!local_video_renderer_) {
798 local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
799 }
800 return track;
801 }
802
803 void HandleIncomingOffer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100804 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer";
Steve Antona3a92c22017-12-07 10:27:41 -0800805 std::unique_ptr<SessionDescriptionInterface> desc =
806 webrtc::CreateSessionDescription(SdpType::kOffer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700807 if (received_sdp_munger_) {
808 received_sdp_munger_(desc->description());
809 }
810
811 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
812 // Setting a remote description may have changed the number of receivers,
813 // so reset the receiver observers.
814 ResetRtpReceiverObservers();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800815 if (remote_offer_handler_) {
816 remote_offer_handler_();
817 }
deadbeef1dcb1642017-03-29 21:08:16 -0700818 auto answer = CreateAnswer();
819 ASSERT_NE(nullptr, answer);
820 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
821 }
822
823 void HandleIncomingAnswer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100824 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
Steve Antona3a92c22017-12-07 10:27:41 -0800825 std::unique_ptr<SessionDescriptionInterface> desc =
826 webrtc::CreateSessionDescription(SdpType::kAnswer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700827 if (received_sdp_munger_) {
828 received_sdp_munger_(desc->description());
829 }
830
831 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
832 // Set the RtpReceiverObserver after receivers are created.
833 ResetRtpReceiverObservers();
834 }
835
836 // Returns null on failure.
deadbeef1dcb1642017-03-29 21:08:16 -0700837 std::unique_ptr<SessionDescriptionInterface> CreateAnswer() {
838 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
839 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
840 pc()->CreateAnswer(observer, offer_answer_options_);
841 return WaitForDescriptionFromObserver(observer);
842 }
843
844 std::unique_ptr<SessionDescriptionInterface> WaitForDescriptionFromObserver(
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100845 MockCreateSessionDescriptionObserver* observer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700846 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
847 if (!observer->result()) {
848 return nullptr;
849 }
850 auto description = observer->MoveDescription();
851 if (generated_sdp_munger_) {
852 generated_sdp_munger_(description->description());
853 }
854 return description;
855 }
856
857 // Setting the local description and sending the SDP message over the fake
858 // signaling channel are combined into the same method because the SDP
859 // message needs to be sent as soon as SetLocalDescription finishes, without
860 // waiting for the observer to be called. This ensures that ICE candidates
861 // don't outrace the description.
862 bool SetLocalDescriptionAndSendSdpMessage(
863 std::unique_ptr<SessionDescriptionInterface> desc) {
864 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
865 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100866 RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage";
Steve Antona3a92c22017-12-07 10:27:41 -0800867 SdpType type = desc->GetType();
deadbeef1dcb1642017-03-29 21:08:16 -0700868 std::string sdp;
869 EXPECT_TRUE(desc->ToString(&sdp));
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700870 RTC_LOG(LS_INFO) << debug_name_ << ": local SDP contents=\n" << sdp;
deadbeef1dcb1642017-03-29 21:08:16 -0700871 pc()->SetLocalDescription(observer, desc.release());
Harald Alvestrand6060df52020-08-11 09:54:02 +0200872 RemoveUnusedVideoRenderers();
deadbeef1dcb1642017-03-29 21:08:16 -0700873 // As mentioned above, we need to send the message immediately after
874 // SetLocalDescription.
875 SendSdpMessage(type, sdp);
876 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
877 return true;
878 }
879
880 bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
881 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
882 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100883 RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription";
deadbeef1dcb1642017-03-29 21:08:16 -0700884 pc()->SetRemoteDescription(observer, desc.release());
Harald Alvestrand6060df52020-08-11 09:54:02 +0200885 RemoveUnusedVideoRenderers();
deadbeef1dcb1642017-03-29 21:08:16 -0700886 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
887 return observer->result();
888 }
889
Seth Hampson2f0d7022018-02-20 11:54:42 -0800890 // This is a work around to remove unused fake_video_renderers from
891 // transceivers that have either stopped or are no longer receiving.
892 void RemoveUnusedVideoRenderers() {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200893 if (sdp_semantics_ != SdpSemantics::kUnifiedPlan) {
894 return;
895 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800896 auto transceivers = pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +0200897 std::set<std::string> active_renderers;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800898 for (auto& transceiver : transceivers) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200899 // Note - we don't check for direction here. This function is called
900 // before direction is set, and in that case, we should not remove
901 // the renderer.
902 if (transceiver->receiver()->media_type() == cricket::MEDIA_TYPE_VIDEO) {
903 active_renderers.insert(transceiver->receiver()->track()->id());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800904 }
Harald Alvestrand6060df52020-08-11 09:54:02 +0200905 }
906 for (auto it = fake_video_renderers_.begin();
907 it != fake_video_renderers_.end();) {
908 // Remove fake video renderers belonging to any non-active transceivers.
909 if (!active_renderers.count(it->first)) {
910 it = fake_video_renderers_.erase(it);
911 } else {
912 it++;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800913 }
914 }
915 }
916
deadbeef1dcb1642017-03-29 21:08:16 -0700917 // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by
918 // default).
Steve Antona3a92c22017-12-07 10:27:41 -0800919 void SendSdpMessage(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700920 if (signaling_delay_ms_ == 0) {
921 RelaySdpMessageIfReceiverExists(type, msg);
922 } else {
923 invoker_.AsyncInvokeDelayed<void>(
924 RTC_FROM_HERE, rtc::Thread::Current(),
Niels Möller4bab23f2021-01-18 09:24:33 +0100925 [this, type, msg] { RelaySdpMessageIfReceiverExists(type, msg); },
deadbeef1dcb1642017-03-29 21:08:16 -0700926 signaling_delay_ms_);
927 }
928 }
929
Steve Antona3a92c22017-12-07 10:27:41 -0800930 void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700931 if (signaling_message_receiver_) {
932 signaling_message_receiver_->ReceiveSdpMessage(type, msg);
933 }
934 }
935
936 // Simulate trickling an ICE candidate with delay |signaling_delay_ms_| (0 by
937 // default).
938 void SendIceMessage(const std::string& sdp_mid,
939 int sdp_mline_index,
940 const std::string& msg) {
941 if (signaling_delay_ms_ == 0) {
942 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
943 } else {
944 invoker_.AsyncInvokeDelayed<void>(
945 RTC_FROM_HERE, rtc::Thread::Current(),
Niels Möller4bab23f2021-01-18 09:24:33 +0100946 [this, sdp_mid, sdp_mline_index, msg] {
947 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
948 },
deadbeef1dcb1642017-03-29 21:08:16 -0700949 signaling_delay_ms_);
950 }
951 }
952
953 void RelayIceMessageIfReceiverExists(const std::string& sdp_mid,
954 int sdp_mline_index,
955 const std::string& msg) {
956 if (signaling_message_receiver_) {
957 signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index,
958 msg);
959 }
960 }
961
962 // SignalingMessageReceiver callbacks.
Steve Antona3a92c22017-12-07 10:27:41 -0800963 void ReceiveSdpMessage(SdpType type, const std::string& msg) override {
964 if (type == SdpType::kOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700965 HandleIncomingOffer(msg);
966 } else {
967 HandleIncomingAnswer(msg);
968 }
969 }
970
971 void ReceiveIceMessage(const std::string& sdp_mid,
972 int sdp_mline_index,
973 const std::string& msg) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100974 RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage";
deadbeef1dcb1642017-03-29 21:08:16 -0700975 std::unique_ptr<webrtc::IceCandidateInterface> candidate(
976 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr));
977 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
978 }
979
980 // PeerConnectionObserver callbacks.
981 void OnSignalingChange(
982 webrtc::PeerConnectionInterface::SignalingState new_state) override {
983 EXPECT_EQ(pc()->signaling_state(), new_state);
Eldar Rello5ab79e62019-10-09 18:29:44 +0300984 peer_connection_signaling_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700985 }
Steve Anton15324772018-01-16 10:26:49 -0800986 void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
987 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
988 streams) override {
989 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
990 rtc::scoped_refptr<VideoTrackInterface> video_track(
991 static_cast<VideoTrackInterface*>(receiver->track().get()));
992 ASSERT_TRUE(fake_video_renderers_.find(video_track->id()) ==
deadbeef1dcb1642017-03-29 21:08:16 -0700993 fake_video_renderers_.end());
Steve Anton15324772018-01-16 10:26:49 -0800994 fake_video_renderers_[video_track->id()] =
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200995 std::make_unique<FakeVideoTrackRenderer>(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -0700996 }
997 }
Steve Anton15324772018-01-16 10:26:49 -0800998 void OnRemoveTrack(
999 rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
1000 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
1001 auto it = fake_video_renderers_.find(receiver->track()->id());
Harald Alvestrand6060df52020-08-11 09:54:02 +02001002 if (it != fake_video_renderers_.end()) {
1003 fake_video_renderers_.erase(it);
1004 } else {
1005 RTC_LOG(LS_ERROR) << "OnRemoveTrack called for non-active renderer";
1006 }
Steve Anton15324772018-01-16 10:26:49 -08001007 }
1008 }
deadbeef1dcb1642017-03-29 21:08:16 -07001009 void OnRenegotiationNeeded() override {}
1010 void OnIceConnectionChange(
1011 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
1012 EXPECT_EQ(pc()->ice_connection_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -07001013 ice_connection_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -07001014 }
Jonas Olssonacd8ae72019-02-25 15:26:24 +01001015 void OnStandardizedIceConnectionChange(
1016 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
1017 standardized_ice_connection_state_history_.push_back(new_state);
1018 }
Jonas Olsson635474e2018-10-18 15:58:17 +02001019 void OnConnectionChange(
1020 webrtc::PeerConnectionInterface::PeerConnectionState new_state) override {
1021 peer_connection_state_history_.push_back(new_state);
1022 }
1023
deadbeef1dcb1642017-03-29 21:08:16 -07001024 void OnIceGatheringChange(
1025 webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
deadbeef1dcb1642017-03-29 21:08:16 -07001026 EXPECT_EQ(pc()->ice_gathering_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -07001027 ice_gathering_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -07001028 }
Alex Drake00c7ecf2019-08-06 10:54:47 -07001029
1030 void OnIceSelectedCandidatePairChanged(
1031 const cricket::CandidatePairChangeEvent& event) {
1032 ice_candidate_pair_change_history_.push_back(event);
1033 }
Alex Drake43faee02019-08-12 16:27:34 -07001034
deadbeef1dcb1642017-03-29 21:08:16 -07001035 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001036 RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate";
deadbeef1dcb1642017-03-29 21:08:16 -07001037
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001038 if (remote_async_resolver_) {
1039 const auto& local_candidate = candidate->candidate();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001040 if (local_candidate.address().IsUnresolvedIP()) {
1041 RTC_DCHECK(local_candidate.type() == cricket::LOCAL_PORT_TYPE);
1042 rtc::SocketAddress resolved_addr(local_candidate.address());
Qingsi Wangecd30542019-05-22 14:34:56 -07001043 const auto resolved_ip = mdns_responder_->GetMappedAddressForName(
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001044 local_candidate.address().hostname());
1045 RTC_DCHECK(!resolved_ip.IsNil());
1046 resolved_addr.SetResolvedIP(resolved_ip);
1047 EXPECT_CALL(*remote_async_resolver_, GetResolvedAddress(_, _))
1048 .WillOnce(DoAll(SetArgPointee<1>(resolved_addr), Return(true)));
1049 EXPECT_CALL(*remote_async_resolver_, Destroy(_));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001050 }
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001051 }
1052
deadbeef1dcb1642017-03-29 21:08:16 -07001053 std::string ice_sdp;
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001054 EXPECT_TRUE(candidate->ToString(&ice_sdp));
Steve Antonede9ca52017-10-16 13:04:27 -07001055 if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) {
deadbeef1dcb1642017-03-29 21:08:16 -07001056 // Remote party may be deleted.
1057 return;
1058 }
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001059 SendIceMessage(candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp);
Qingsi Wangc129c352019-04-18 10:41:58 -07001060 last_candidate_gathered_ = candidate->candidate();
deadbeef1dcb1642017-03-29 21:08:16 -07001061 }
Eldar Rello0095d372019-12-02 22:22:07 +02001062 void OnIceCandidateError(const std::string& address,
1063 int port,
Eldar Relloda13ea22019-06-01 12:23:43 +03001064 const std::string& url,
1065 int error_code,
1066 const std::string& error_text) override {
Eldar Rello0095d372019-12-02 22:22:07 +02001067 error_event_ = cricket::IceCandidateErrorEvent(address, port, url,
Eldar Relloda13ea22019-06-01 12:23:43 +03001068 error_code, error_text);
1069 }
deadbeef1dcb1642017-03-29 21:08:16 -07001070 void OnDataChannel(
1071 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001072 RTC_LOG(LS_INFO) << debug_name_ << ": OnDataChannel";
deadbeef1dcb1642017-03-29 21:08:16 -07001073 data_channel_ = data_channel;
1074 data_observer_.reset(new MockDataChannelObserver(data_channel));
1075 }
1076
deadbeef1dcb1642017-03-29 21:08:16 -07001077 std::string debug_name_;
1078
1079 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
Qingsi Wangecd30542019-05-22 14:34:56 -07001080 // Reference to the mDNS responder owned by |fake_network_manager_| after set.
1081 webrtc::FakeMdnsResponder* mdns_responder_ = nullptr;
deadbeef1dcb1642017-03-29 21:08:16 -07001082
1083 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
1084 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
1085 peer_connection_factory_;
1086
Steve Antonede9ca52017-10-16 13:04:27 -07001087 cricket::PortAllocator* port_allocator_;
deadbeef1dcb1642017-03-29 21:08:16 -07001088 // Needed to keep track of number of frames sent.
1089 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
1090 // Needed to keep track of number of frames received.
1091 std::map<std::string, std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
1092 fake_video_renderers_;
1093 // Needed to ensure frames aren't received for removed tracks.
1094 std::vector<std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
1095 removed_fake_video_renderers_;
deadbeef1dcb1642017-03-29 21:08:16 -07001096
1097 // For remote peer communication.
1098 SignalingMessageReceiver* signaling_message_receiver_ = nullptr;
1099 int signaling_delay_ms_ = 0;
Steve Antonede9ca52017-10-16 13:04:27 -07001100 bool signal_ice_candidates_ = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07001101 cricket::Candidate last_candidate_gathered_;
Eldar Relloda13ea22019-06-01 12:23:43 +03001102 cricket::IceCandidateErrorEvent error_event_;
deadbeef1dcb1642017-03-29 21:08:16 -07001103
Niels Möller5c7efe72018-05-11 10:34:46 +02001104 // Store references to the video sources we've created, so that we can stop
deadbeef1dcb1642017-03-29 21:08:16 -07001105 // them, if required.
Niels Möller5c7efe72018-05-11 10:34:46 +02001106 std::vector<rtc::scoped_refptr<webrtc::VideoTrackSource>>
1107 video_track_sources_;
deadbeef1dcb1642017-03-29 21:08:16 -07001108 // |local_video_renderer_| attached to the first created local video track.
1109 std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
1110
Seth Hampson2f0d7022018-02-20 11:54:42 -08001111 SdpSemantics sdp_semantics_;
deadbeef1dcb1642017-03-29 21:08:16 -07001112 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_;
1113 std::function<void(cricket::SessionDescription*)> received_sdp_munger_;
1114 std::function<void(cricket::SessionDescription*)> generated_sdp_munger_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001115 std::function<void()> remote_offer_handler_;
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001116 rtc::MockAsyncResolver* remote_async_resolver_ = nullptr;
deadbeef1dcb1642017-03-29 21:08:16 -07001117 rtc::scoped_refptr<DataChannelInterface> data_channel_;
1118 std::unique_ptr<MockDataChannelObserver> data_observer_;
1119
1120 std::vector<std::unique_ptr<MockRtpReceiverObserver>> rtp_receiver_observers_;
1121
Steve Antonede9ca52017-10-16 13:04:27 -07001122 std::vector<PeerConnectionInterface::IceConnectionState>
1123 ice_connection_state_history_;
Jonas Olssonacd8ae72019-02-25 15:26:24 +01001124 std::vector<PeerConnectionInterface::IceConnectionState>
1125 standardized_ice_connection_state_history_;
Jonas Olsson635474e2018-10-18 15:58:17 +02001126 std::vector<PeerConnectionInterface::PeerConnectionState>
1127 peer_connection_state_history_;
Steve Antonede9ca52017-10-16 13:04:27 -07001128 std::vector<PeerConnectionInterface::IceGatheringState>
1129 ice_gathering_state_history_;
Alex Drake00c7ecf2019-08-06 10:54:47 -07001130 std::vector<cricket::CandidatePairChangeEvent>
1131 ice_candidate_pair_change_history_;
Eldar Rello5ab79e62019-10-09 18:29:44 +03001132 std::vector<PeerConnectionInterface::SignalingState>
1133 peer_connection_signaling_state_history_;
Qingsi Wang7685e862018-06-11 20:15:46 -07001134 webrtc::FakeRtcEventLogFactory* event_log_factory_;
1135
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00001136 // Variables for tracking delay stats on an audio track
1137 int audio_packets_stat_ = 0;
1138 double audio_delay_stat_ = 0.0;
Harald Alvestrandcbacec52021-01-14 13:13:42 +00001139 uint64_t audio_samples_stat_ = 0;
1140 uint64_t audio_concealed_stat_ = 0;
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00001141 std::string rtp_stats_id_;
1142 std::string audio_track_stats_id_;
1143
deadbeef1dcb1642017-03-29 21:08:16 -07001144 rtc::AsyncInvoker invoker_;
1145
Seth Hampson2f0d7022018-02-20 11:54:42 -08001146 friend class PeerConnectionIntegrationBaseTest;
deadbeef1dcb1642017-03-29 21:08:16 -07001147};
1148
Elad Alon99c3fe52017-10-13 16:29:40 +02001149class MockRtcEventLogOutput : public webrtc::RtcEventLogOutput {
1150 public:
1151 virtual ~MockRtcEventLogOutput() = default;
Danil Chapovalov3a353122020-05-15 11:16:53 +02001152 MOCK_METHOD(bool, IsActive, (), (const, override));
1153 MOCK_METHOD(bool, Write, (const std::string&), (override));
Elad Alon99c3fe52017-10-13 16:29:40 +02001154};
1155
Seth Hampson2f0d7022018-02-20 11:54:42 -08001156// This helper object is used for both specifying how many audio/video frames
1157// are expected to be received for a caller/callee. It provides helper functions
1158// to specify these expectations. The object initially starts in a state of no
1159// expectations.
1160class MediaExpectations {
1161 public:
1162 enum ExpectFrames {
1163 kExpectSomeFrames,
1164 kExpectNoFrames,
1165 kNoExpectation,
1166 };
1167
1168 void ExpectBidirectionalAudioAndVideo() {
1169 ExpectBidirectionalAudio();
1170 ExpectBidirectionalVideo();
1171 }
1172
1173 void ExpectBidirectionalAudio() {
1174 CallerExpectsSomeAudio();
1175 CalleeExpectsSomeAudio();
1176 }
1177
1178 void ExpectNoAudio() {
1179 CallerExpectsNoAudio();
1180 CalleeExpectsNoAudio();
1181 }
1182
1183 void ExpectBidirectionalVideo() {
1184 CallerExpectsSomeVideo();
1185 CalleeExpectsSomeVideo();
1186 }
1187
1188 void ExpectNoVideo() {
1189 CallerExpectsNoVideo();
1190 CalleeExpectsNoVideo();
1191 }
1192
1193 void CallerExpectsSomeAudioAndVideo() {
1194 CallerExpectsSomeAudio();
1195 CallerExpectsSomeVideo();
1196 }
1197
1198 void CalleeExpectsSomeAudioAndVideo() {
1199 CalleeExpectsSomeAudio();
1200 CalleeExpectsSomeVideo();
1201 }
1202
1203 // Caller's audio functions.
1204 void CallerExpectsSomeAudio(
1205 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1206 caller_audio_expectation_ = kExpectSomeFrames;
1207 caller_audio_frames_expected_ = expected_audio_frames;
1208 }
1209
1210 void CallerExpectsNoAudio() {
1211 caller_audio_expectation_ = kExpectNoFrames;
1212 caller_audio_frames_expected_ = 0;
1213 }
1214
1215 // Caller's video functions.
1216 void CallerExpectsSomeVideo(
1217 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1218 caller_video_expectation_ = kExpectSomeFrames;
1219 caller_video_frames_expected_ = expected_video_frames;
1220 }
1221
1222 void CallerExpectsNoVideo() {
1223 caller_video_expectation_ = kExpectNoFrames;
1224 caller_video_frames_expected_ = 0;
1225 }
1226
1227 // Callee's audio functions.
1228 void CalleeExpectsSomeAudio(
1229 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1230 callee_audio_expectation_ = kExpectSomeFrames;
1231 callee_audio_frames_expected_ = expected_audio_frames;
1232 }
1233
1234 void CalleeExpectsNoAudio() {
1235 callee_audio_expectation_ = kExpectNoFrames;
1236 callee_audio_frames_expected_ = 0;
1237 }
1238
1239 // Callee's video functions.
1240 void CalleeExpectsSomeVideo(
1241 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1242 callee_video_expectation_ = kExpectSomeFrames;
1243 callee_video_frames_expected_ = expected_video_frames;
1244 }
1245
1246 void CalleeExpectsNoVideo() {
1247 callee_video_expectation_ = kExpectNoFrames;
1248 callee_video_frames_expected_ = 0;
1249 }
1250
1251 ExpectFrames caller_audio_expectation_ = kNoExpectation;
1252 ExpectFrames caller_video_expectation_ = kNoExpectation;
1253 ExpectFrames callee_audio_expectation_ = kNoExpectation;
1254 ExpectFrames callee_video_expectation_ = kNoExpectation;
1255 int caller_audio_frames_expected_ = 0;
1256 int caller_video_frames_expected_ = 0;
1257 int callee_audio_frames_expected_ = 0;
1258 int callee_video_frames_expected_ = 0;
1259};
1260
Qingsi Wang25ec8882019-11-15 12:33:05 -08001261class MockIceTransport : public webrtc::IceTransportInterface {
1262 public:
1263 MockIceTransport(const std::string& name, int component)
1264 : internal_(std::make_unique<cricket::FakeIceTransport>(
1265 name,
1266 component,
1267 nullptr /* network_thread */)) {}
1268 ~MockIceTransport() = default;
1269 cricket::IceTransportInternal* internal() { return internal_.get(); }
1270
1271 private:
1272 std::unique_ptr<cricket::FakeIceTransport> internal_;
1273};
1274
1275class MockIceTransportFactory : public IceTransportFactory {
1276 public:
1277 ~MockIceTransportFactory() override = default;
1278 rtc::scoped_refptr<IceTransportInterface> CreateIceTransport(
1279 const std::string& transport_name,
1280 int component,
1281 IceTransportInit init) {
1282 RecordIceTransportCreated();
1283 return new rtc::RefCountedObject<MockIceTransport>(transport_name,
1284 component);
1285 }
Danil Chapovalov3a353122020-05-15 11:16:53 +02001286 MOCK_METHOD(void, RecordIceTransportCreated, ());
Qingsi Wang25ec8882019-11-15 12:33:05 -08001287};
1288
deadbeef1dcb1642017-03-29 21:08:16 -07001289// Tests two PeerConnections connecting to each other end-to-end, using a
1290// virtual network, fake A/V capture and fake encoder/decoders. The
1291// PeerConnections share the threads/socket servers, but use separate versions
1292// of everything else (including "PeerConnectionFactory"s).
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001293class PeerConnectionIntegrationBaseTest : public ::testing::Test {
deadbeef1dcb1642017-03-29 21:08:16 -07001294 public:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001295 explicit PeerConnectionIntegrationBaseTest(SdpSemantics sdp_semantics)
1296 : sdp_semantics_(sdp_semantics),
1297 ss_(new rtc::VirtualSocketServer()),
Steve Antonede9ca52017-10-16 13:04:27 -07001298 fss_(new rtc::FirewallSocketServer(ss_.get())),
1299 network_thread_(new rtc::Thread(fss_.get())),
Niels Möller2a707032020-06-16 16:39:13 +02001300 worker_thread_(rtc::Thread::Create()) {
Sebastian Jansson8a793a02018-03-13 15:21:48 +01001301 network_thread_->SetName("PCNetworkThread", this);
1302 worker_thread_->SetName("PCWorkerThread", this);
deadbeef1dcb1642017-03-29 21:08:16 -07001303 RTC_CHECK(network_thread_->Start());
1304 RTC_CHECK(worker_thread_->Start());
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001305 webrtc::metrics::Reset();
deadbeef1dcb1642017-03-29 21:08:16 -07001306 }
1307
Seth Hampson2f0d7022018-02-20 11:54:42 -08001308 ~PeerConnectionIntegrationBaseTest() {
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00001309 // The PeerConnections should be deleted before the TurnCustomizers.
Seth Hampsonaed71642018-06-11 07:41:32 -07001310 // A TurnPort is created with a raw pointer to a TurnCustomizer. The
1311 // TurnPort has the same lifetime as the PeerConnection, so it's expected
1312 // that the TurnCustomizer outlives the life of the PeerConnection or else
1313 // when Send() is called it will hit a seg fault.
deadbeef1dcb1642017-03-29 21:08:16 -07001314 if (caller_) {
1315 caller_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001316 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001317 }
1318 if (callee_) {
1319 callee_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001320 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001321 }
Seth Hampsonaed71642018-06-11 07:41:32 -07001322
1323 // If turn servers were created for the test they need to be destroyed on
1324 // the network thread.
1325 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
1326 turn_servers_.clear();
1327 turn_customizers_.clear();
1328 });
deadbeef1dcb1642017-03-29 21:08:16 -07001329 }
1330
1331 bool SignalingStateStable() {
1332 return caller_->SignalingStateStable() && callee_->SignalingStateStable();
1333 }
1334
deadbeef71452802017-05-07 17:21:01 -07001335 bool DtlsConnected() {
Alex Loiko9289eda2018-11-23 16:18:59 +00001336 // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS
1337 // are connected. This is an important distinction. Once we have separate
1338 // ICE and DTLS state, this check needs to use the DTLS state.
1339 return (callee()->ice_connection_state() ==
1340 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1341 callee()->ice_connection_state() ==
1342 webrtc::PeerConnectionInterface::kIceConnectionCompleted) &&
1343 (caller()->ice_connection_state() ==
1344 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1345 caller()->ice_connection_state() ==
1346 webrtc::PeerConnectionInterface::kIceConnectionCompleted);
deadbeef71452802017-05-07 17:21:01 -07001347 }
1348
Qingsi Wang7685e862018-06-11 20:15:46 -07001349 // When |event_log_factory| is null, the default implementation of the event
1350 // log factory will be used.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001351 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWrapper(
1352 const std::string& debug_name,
Seth Hampson2f0d7022018-02-20 11:54:42 -08001353 const PeerConnectionFactory::Options* options,
1354 const RTCConfiguration* config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001355 webrtc::PeerConnectionDependencies dependencies,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001356 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory,
Johannes Kron3e983682020-03-29 22:17:00 +02001357 bool reset_encoder_factory,
1358 bool reset_decoder_factory) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001359 RTCConfiguration modified_config;
1360 if (config) {
1361 modified_config = *config;
1362 }
Steve Anton3acffc32018-04-12 17:21:03 -07001363 modified_config.sdp_semantics = sdp_semantics_;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001364 if (!dependencies.cert_generator) {
1365 dependencies.cert_generator =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001366 std::make_unique<FakeRTCCertificateGenerator>();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001367 }
1368 std::unique_ptr<PeerConnectionWrapper> client(
1369 new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001370
Niels Möllerf06f9232018-08-07 12:32:18 +02001371 if (!client->Init(options, &modified_config, std::move(dependencies),
1372 network_thread_.get(), worker_thread_.get(),
Niels Möller2a707032020-06-16 16:39:13 +02001373 std::move(event_log_factory), reset_encoder_factory,
Johannes Kron3e983682020-03-29 22:17:00 +02001374 reset_decoder_factory)) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001375 return nullptr;
1376 }
1377 return client;
1378 }
1379
Qingsi Wang7685e862018-06-11 20:15:46 -07001380 std::unique_ptr<PeerConnectionWrapper>
1381 CreatePeerConnectionWrapperWithFakeRtcEventLog(
1382 const std::string& debug_name,
Qingsi Wang7685e862018-06-11 20:15:46 -07001383 const PeerConnectionFactory::Options* options,
1384 const RTCConfiguration* config,
1385 webrtc::PeerConnectionDependencies dependencies) {
Danil Chapovalov4f281f12021-01-18 13:29:00 +01001386 return CreatePeerConnectionWrapper(
1387 debug_name, options, config, std::move(dependencies),
1388 std::make_unique<webrtc::FakeRtcEventLogFactory>(),
1389 /*reset_encoder_factory=*/false,
1390 /*reset_decoder_factory=*/false);
Qingsi Wang7685e862018-06-11 20:15:46 -07001391 }
1392
deadbeef1dcb1642017-03-29 21:08:16 -07001393 bool CreatePeerConnectionWrappers() {
1394 return CreatePeerConnectionWrappersWithConfig(
1395 PeerConnectionInterface::RTCConfiguration(),
1396 PeerConnectionInterface::RTCConfiguration());
1397 }
1398
Steve Anton3acffc32018-04-12 17:21:03 -07001399 bool CreatePeerConnectionWrappersWithSdpSemantics(
1400 SdpSemantics caller_semantics,
1401 SdpSemantics callee_semantics) {
1402 // Can't specify the sdp_semantics in the passed-in configuration since it
1403 // will be overwritten by CreatePeerConnectionWrapper with whatever is
1404 // stored in sdp_semantics_. So get around this by modifying the instance
1405 // variable before calling CreatePeerConnectionWrapper for the caller and
1406 // callee PeerConnections.
1407 SdpSemantics original_semantics = sdp_semantics_;
1408 sdp_semantics_ = caller_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001409 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001410 "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001411 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001412 /*reset_encoder_factory=*/false,
1413 /*reset_decoder_factory=*/false);
Steve Anton3acffc32018-04-12 17:21:03 -07001414 sdp_semantics_ = callee_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001415 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001416 "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001417 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001418 /*reset_encoder_factory=*/false,
1419 /*reset_decoder_factory=*/false);
Steve Anton3acffc32018-04-12 17:21:03 -07001420 sdp_semantics_ = original_semantics;
1421 return caller_ && callee_;
1422 }
1423
deadbeef1dcb1642017-03-29 21:08:16 -07001424 bool CreatePeerConnectionWrappersWithConfig(
1425 const PeerConnectionInterface::RTCConfiguration& caller_config,
1426 const PeerConnectionInterface::RTCConfiguration& callee_config) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001427 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001428 "Caller", nullptr, &caller_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001429 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001430 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001431 /*reset_decoder_factory=*/false);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001432 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001433 "Callee", nullptr, &callee_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001434 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001435 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001436 /*reset_decoder_factory=*/false);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001437 return caller_ && callee_;
1438 }
1439
1440 bool CreatePeerConnectionWrappersWithConfigAndDeps(
1441 const PeerConnectionInterface::RTCConfiguration& caller_config,
1442 webrtc::PeerConnectionDependencies caller_dependencies,
1443 const PeerConnectionInterface::RTCConfiguration& callee_config,
1444 webrtc::PeerConnectionDependencies callee_dependencies) {
Niels Möller2a707032020-06-16 16:39:13 +02001445 caller_ =
1446 CreatePeerConnectionWrapper("Caller", nullptr, &caller_config,
1447 std::move(caller_dependencies), nullptr,
1448 /*reset_encoder_factory=*/false,
1449 /*reset_decoder_factory=*/false);
1450 callee_ =
1451 CreatePeerConnectionWrapper("Callee", nullptr, &callee_config,
1452 std::move(callee_dependencies), nullptr,
1453 /*reset_encoder_factory=*/false,
1454 /*reset_decoder_factory=*/false);
deadbeef1dcb1642017-03-29 21:08:16 -07001455 return caller_ && callee_;
1456 }
1457
1458 bool CreatePeerConnectionWrappersWithOptions(
1459 const PeerConnectionFactory::Options& caller_options,
1460 const PeerConnectionFactory::Options& callee_options) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001461 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001462 "Caller", &caller_options, nullptr,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001463 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001464 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001465 /*reset_decoder_factory=*/false);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001466 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001467 "Callee", &callee_options, nullptr,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001468 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001469 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001470 /*reset_decoder_factory=*/false);
Qingsi Wang7685e862018-06-11 20:15:46 -07001471 return caller_ && callee_;
1472 }
1473
1474 bool CreatePeerConnectionWrappersWithFakeRtcEventLog() {
1475 PeerConnectionInterface::RTCConfiguration default_config;
1476 caller_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001477 "Caller", nullptr, &default_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001478 webrtc::PeerConnectionDependencies(nullptr));
1479 callee_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001480 "Callee", nullptr, &default_config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001481 webrtc::PeerConnectionDependencies(nullptr));
deadbeef1dcb1642017-03-29 21:08:16 -07001482 return caller_ && callee_;
1483 }
1484
Seth Hampson2f0d7022018-02-20 11:54:42 -08001485 std::unique_ptr<PeerConnectionWrapper>
1486 CreatePeerConnectionWrapperWithAlternateKey() {
deadbeef1dcb1642017-03-29 21:08:16 -07001487 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
1488 new FakeRTCCertificateGenerator());
1489 cert_generator->use_alternate_key();
1490
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001491 webrtc::PeerConnectionDependencies dependencies(nullptr);
1492 dependencies.cert_generator = std::move(cert_generator);
Niels Möller2a707032020-06-16 16:39:13 +02001493 return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr,
1494 std::move(dependencies), nullptr,
1495 /*reset_encoder_factory=*/false,
1496 /*reset_decoder_factory=*/false);
Johannes Kron3e983682020-03-29 22:17:00 +02001497 }
1498
1499 bool CreateOneDirectionalPeerConnectionWrappers(bool caller_to_callee) {
1500 caller_ = CreatePeerConnectionWrapper(
1501 "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001502 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001503 /*reset_encoder_factory=*/!caller_to_callee,
1504 /*reset_decoder_factory=*/caller_to_callee);
1505 callee_ = CreatePeerConnectionWrapper(
1506 "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001507 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001508 /*reset_encoder_factory=*/caller_to_callee,
1509 /*reset_decoder_factory=*/!caller_to_callee);
1510 return caller_ && callee_;
deadbeef1dcb1642017-03-29 21:08:16 -07001511 }
1512
Seth Hampsonaed71642018-06-11 07:41:32 -07001513 cricket::TestTurnServer* CreateTurnServer(
1514 rtc::SocketAddress internal_address,
1515 rtc::SocketAddress external_address,
1516 cricket::ProtocolType type = cricket::ProtocolType::PROTO_UDP,
1517 const std::string& common_name = "test turn server") {
1518 rtc::Thread* thread = network_thread();
1519 std::unique_ptr<cricket::TestTurnServer> turn_server =
1520 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnServer>>(
1521 RTC_FROM_HERE,
1522 [thread, internal_address, external_address, type, common_name] {
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001523 return std::make_unique<cricket::TestTurnServer>(
Seth Hampsonaed71642018-06-11 07:41:32 -07001524 thread, internal_address, external_address, type,
1525 /*ignore_bad_certs=*/true, common_name);
1526 });
1527 turn_servers_.push_back(std::move(turn_server));
1528 // Interactions with the turn server should be done on the network thread.
1529 return turn_servers_.back().get();
1530 }
1531
1532 cricket::TestTurnCustomizer* CreateTurnCustomizer() {
1533 std::unique_ptr<cricket::TestTurnCustomizer> turn_customizer =
1534 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnCustomizer>>(
1535 RTC_FROM_HERE,
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001536 [] { return std::make_unique<cricket::TestTurnCustomizer>(); });
Seth Hampsonaed71642018-06-11 07:41:32 -07001537 turn_customizers_.push_back(std::move(turn_customizer));
1538 // Interactions with the turn customizer should be done on the network
1539 // thread.
1540 return turn_customizers_.back().get();
1541 }
1542
1543 // Checks that the function counters for a TestTurnCustomizer are greater than
1544 // 0.
1545 void ExpectTurnCustomizerCountersIncremented(
1546 cricket::TestTurnCustomizer* turn_customizer) {
1547 unsigned int allow_channel_data_counter =
1548 network_thread()->Invoke<unsigned int>(
1549 RTC_FROM_HERE, [turn_customizer] {
1550 return turn_customizer->allow_channel_data_cnt_;
1551 });
1552 EXPECT_GT(allow_channel_data_counter, 0u);
1553 unsigned int modify_counter = network_thread()->Invoke<unsigned int>(
1554 RTC_FROM_HERE,
1555 [turn_customizer] { return turn_customizer->modify_cnt_; });
1556 EXPECT_GT(modify_counter, 0u);
1557 }
1558
deadbeef1dcb1642017-03-29 21:08:16 -07001559 // Once called, SDP blobs and ICE candidates will be automatically signaled
1560 // between PeerConnections.
1561 void ConnectFakeSignaling() {
1562 caller_->set_signaling_message_receiver(callee_.get());
1563 callee_->set_signaling_message_receiver(caller_.get());
1564 }
1565
Steve Antonede9ca52017-10-16 13:04:27 -07001566 // Once called, SDP blobs will be automatically signaled between
1567 // PeerConnections. Note that ICE candidates will not be signaled unless they
1568 // are in the exchanged SDP blobs.
1569 void ConnectFakeSignalingForSdpOnly() {
1570 ConnectFakeSignaling();
1571 SetSignalIceCandidates(false);
1572 }
1573
deadbeef1dcb1642017-03-29 21:08:16 -07001574 void SetSignalingDelayMs(int delay_ms) {
1575 caller_->set_signaling_delay_ms(delay_ms);
1576 callee_->set_signaling_delay_ms(delay_ms);
1577 }
1578
Steve Antonede9ca52017-10-16 13:04:27 -07001579 void SetSignalIceCandidates(bool signal) {
1580 caller_->set_signal_ice_candidates(signal);
1581 callee_->set_signal_ice_candidates(signal);
1582 }
1583
deadbeef1dcb1642017-03-29 21:08:16 -07001584 // Messages may get lost on the unreliable DataChannel, so we send multiple
1585 // times to avoid test flakiness.
1586 void SendRtpDataWithRetries(webrtc::DataChannelInterface* dc,
1587 const std::string& data,
1588 int retries) {
1589 for (int i = 0; i < retries; ++i) {
1590 dc->Send(DataBuffer(data));
1591 }
1592 }
1593
1594 rtc::Thread* network_thread() { return network_thread_.get(); }
1595
1596 rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); }
1597
1598 PeerConnectionWrapper* caller() { return caller_.get(); }
1599
1600 // Set the |caller_| to the |wrapper| passed in and return the
1601 // original |caller_|.
1602 PeerConnectionWrapper* SetCallerPcWrapperAndReturnCurrent(
1603 PeerConnectionWrapper* wrapper) {
1604 PeerConnectionWrapper* old = caller_.release();
1605 caller_.reset(wrapper);
1606 return old;
1607 }
1608
1609 PeerConnectionWrapper* callee() { return callee_.get(); }
1610
1611 // Set the |callee_| to the |wrapper| passed in and return the
1612 // original |callee_|.
1613 PeerConnectionWrapper* SetCalleePcWrapperAndReturnCurrent(
1614 PeerConnectionWrapper* wrapper) {
1615 PeerConnectionWrapper* old = callee_.release();
1616 callee_.reset(wrapper);
1617 return old;
1618 }
1619
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001620 void SetPortAllocatorFlags(uint32_t caller_flags, uint32_t callee_flags) {
Niels Möller4bab23f2021-01-18 09:24:33 +01001621 network_thread()->Invoke<void>(RTC_FROM_HERE, [this, caller_flags] {
1622 caller()->port_allocator()->set_flags(caller_flags);
1623 });
1624 network_thread()->Invoke<void>(RTC_FROM_HERE, [this, callee_flags] {
1625 callee()->port_allocator()->set_flags(callee_flags);
1626 });
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001627 }
1628
Steve Antonede9ca52017-10-16 13:04:27 -07001629 rtc::FirewallSocketServer* firewall() const { return fss_.get(); }
1630
Seth Hampson2f0d7022018-02-20 11:54:42 -08001631 // Expects the provided number of new frames to be received within
1632 // kMaxWaitForFramesMs. The new expected frames are specified in
1633 // |media_expectations|. Returns false if any of the expectations were
1634 // not met.
1635 bool ExpectNewFrames(const MediaExpectations& media_expectations) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02001636 // Make sure there are no bogus tracks confusing the issue.
1637 caller()->RemoveUnusedVideoRenderers();
1638 callee()->RemoveUnusedVideoRenderers();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001639 // First initialize the expected frame counts based upon the current
1640 // frame count.
1641 int total_caller_audio_frames_expected = caller()->audio_frames_received();
1642 if (media_expectations.caller_audio_expectation_ ==
1643 MediaExpectations::kExpectSomeFrames) {
1644 total_caller_audio_frames_expected +=
1645 media_expectations.caller_audio_frames_expected_;
1646 }
1647 int total_caller_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001648 caller()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001649 if (media_expectations.caller_video_expectation_ ==
1650 MediaExpectations::kExpectSomeFrames) {
1651 total_caller_video_frames_expected +=
1652 media_expectations.caller_video_frames_expected_;
1653 }
1654 int total_callee_audio_frames_expected = callee()->audio_frames_received();
1655 if (media_expectations.callee_audio_expectation_ ==
1656 MediaExpectations::kExpectSomeFrames) {
1657 total_callee_audio_frames_expected +=
1658 media_expectations.callee_audio_frames_expected_;
1659 }
1660 int total_callee_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001661 callee()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001662 if (media_expectations.callee_video_expectation_ ==
1663 MediaExpectations::kExpectSomeFrames) {
1664 total_callee_video_frames_expected +=
1665 media_expectations.callee_video_frames_expected_;
1666 }
deadbeef1dcb1642017-03-29 21:08:16 -07001667
Seth Hampson2f0d7022018-02-20 11:54:42 -08001668 // Wait for the expected frames.
deadbeef1dcb1642017-03-29 21:08:16 -07001669 EXPECT_TRUE_WAIT(caller()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001670 total_caller_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001671 caller()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001672 total_caller_video_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001673 callee()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001674 total_callee_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001675 callee()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001676 total_callee_video_frames_expected,
1677 kMaxWaitForFramesMs);
1678 bool expectations_correct =
1679 caller()->audio_frames_received() >=
1680 total_caller_audio_frames_expected &&
1681 caller()->min_video_frames_received_per_track() >=
1682 total_caller_video_frames_expected &&
1683 callee()->audio_frames_received() >=
1684 total_callee_audio_frames_expected &&
1685 callee()->min_video_frames_received_per_track() >=
1686 total_callee_video_frames_expected;
deadbeef1dcb1642017-03-29 21:08:16 -07001687
Seth Hampson2f0d7022018-02-20 11:54:42 -08001688 // After the combined wait, print out a more detailed message upon
1689 // failure.
deadbeef1dcb1642017-03-29 21:08:16 -07001690 EXPECT_GE(caller()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001691 total_caller_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001692 EXPECT_GE(caller()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001693 total_caller_video_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001694 EXPECT_GE(callee()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001695 total_callee_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001696 EXPECT_GE(callee()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001697 total_callee_video_frames_expected);
1698
1699 // We want to make sure nothing unexpected was received.
1700 if (media_expectations.caller_audio_expectation_ ==
1701 MediaExpectations::kExpectNoFrames) {
1702 EXPECT_EQ(caller()->audio_frames_received(),
1703 total_caller_audio_frames_expected);
1704 if (caller()->audio_frames_received() !=
1705 total_caller_audio_frames_expected) {
1706 expectations_correct = false;
1707 }
1708 }
1709 if (media_expectations.caller_video_expectation_ ==
1710 MediaExpectations::kExpectNoFrames) {
1711 EXPECT_EQ(caller()->min_video_frames_received_per_track(),
1712 total_caller_video_frames_expected);
1713 if (caller()->min_video_frames_received_per_track() !=
1714 total_caller_video_frames_expected) {
1715 expectations_correct = false;
1716 }
1717 }
1718 if (media_expectations.callee_audio_expectation_ ==
1719 MediaExpectations::kExpectNoFrames) {
1720 EXPECT_EQ(callee()->audio_frames_received(),
1721 total_callee_audio_frames_expected);
1722 if (callee()->audio_frames_received() !=
1723 total_callee_audio_frames_expected) {
1724 expectations_correct = false;
1725 }
1726 }
1727 if (media_expectations.callee_video_expectation_ ==
1728 MediaExpectations::kExpectNoFrames) {
1729 EXPECT_EQ(callee()->min_video_frames_received_per_track(),
1730 total_callee_video_frames_expected);
1731 if (callee()->min_video_frames_received_per_track() !=
1732 total_callee_video_frames_expected) {
1733 expectations_correct = false;
1734 }
1735 }
1736 return expectations_correct;
deadbeef1dcb1642017-03-29 21:08:16 -07001737 }
1738
Steve Antond91969e2019-05-30 12:27:03 -07001739 void ClosePeerConnections() {
1740 caller()->pc()->Close();
1741 callee()->pc()->Close();
1742 }
1743
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001744 void TestNegotiatedCipherSuite(
1745 const PeerConnectionFactory::Options& caller_options,
1746 const PeerConnectionFactory::Options& callee_options,
1747 int expected_cipher_suite) {
deadbeef1dcb1642017-03-29 21:08:16 -07001748 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options,
1749 callee_options));
deadbeef1dcb1642017-03-29 21:08:16 -07001750 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001751 caller()->AddAudioVideoTracks();
1752 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001753 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001754 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001755 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite),
deadbeefd8ad7882017-04-18 16:01:17 -07001756 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001757 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001758 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1759 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1760 expected_cipher_suite));
deadbeef1dcb1642017-03-29 21:08:16 -07001761 }
1762
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001763 void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
1764 bool remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001765 bool aes_ctr_enabled,
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001766 int expected_cipher_suite) {
1767 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001768 caller_options.crypto_options.srtp.enable_gcm_crypto_suites =
1769 local_gcm_enabled;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001770 caller_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher =
1771 aes_ctr_enabled;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001772 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001773 callee_options.crypto_options.srtp.enable_gcm_crypto_suites =
1774 remote_gcm_enabled;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001775 callee_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher =
1776 aes_ctr_enabled;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001777 TestNegotiatedCipherSuite(caller_options, callee_options,
1778 expected_cipher_suite);
1779 }
1780
Seth Hampson2f0d7022018-02-20 11:54:42 -08001781 protected:
Steve Anton3acffc32018-04-12 17:21:03 -07001782 SdpSemantics sdp_semantics_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001783
deadbeef1dcb1642017-03-29 21:08:16 -07001784 private:
1785 // |ss_| is used by |network_thread_| so it must be destroyed later.
deadbeef1dcb1642017-03-29 21:08:16 -07001786 std::unique_ptr<rtc::VirtualSocketServer> ss_;
Steve Antonede9ca52017-10-16 13:04:27 -07001787 std::unique_ptr<rtc::FirewallSocketServer> fss_;
deadbeef1dcb1642017-03-29 21:08:16 -07001788 // |network_thread_| and |worker_thread_| are used by both
1789 // |caller_| and |callee_| so they must be destroyed
1790 // later.
1791 std::unique_ptr<rtc::Thread> network_thread_;
1792 std::unique_ptr<rtc::Thread> worker_thread_;
Seth Hampsonaed71642018-06-11 07:41:32 -07001793 // The turn servers and turn customizers should be accessed & deleted on the
1794 // network thread to avoid a race with the socket read/write that occurs
1795 // on the network thread.
1796 std::vector<std::unique_ptr<cricket::TestTurnServer>> turn_servers_;
1797 std::vector<std::unique_ptr<cricket::TestTurnCustomizer>> turn_customizers_;
deadbeef1dcb1642017-03-29 21:08:16 -07001798 std::unique_ptr<PeerConnectionWrapper> caller_;
1799 std::unique_ptr<PeerConnectionWrapper> callee_;
1800};
1801
Seth Hampson2f0d7022018-02-20 11:54:42 -08001802class PeerConnectionIntegrationTest
1803 : public PeerConnectionIntegrationBaseTest,
1804 public ::testing::WithParamInterface<SdpSemantics> {
1805 protected:
1806 PeerConnectionIntegrationTest()
1807 : PeerConnectionIntegrationBaseTest(GetParam()) {}
1808};
1809
Yves Gerey100fe632020-01-17 19:15:53 +01001810// Fake clock must be set before threads are started to prevent race on
1811// Set/GetClockForTesting().
1812// To achieve that, multiple inheritance is used as a mixin pattern
1813// where order of construction is finely controlled.
1814// This also ensures peerconnection is closed before switching back to non-fake
1815// clock, avoiding other races and DCHECK failures such as in rtp_sender.cc.
1816class FakeClockForTest : public rtc::ScopedFakeClock {
1817 protected:
1818 FakeClockForTest() {
1819 // Some things use a time of "0" as a special value, so we need to start out
1820 // the fake clock at a nonzero time.
1821 // TODO(deadbeef): Fix this.
Danil Chapovalov0c626af2020-02-10 11:16:00 +01001822 AdvanceTime(webrtc::TimeDelta::Seconds(1));
Yves Gerey100fe632020-01-17 19:15:53 +01001823 }
1824
1825 // Explicit handle.
1826 ScopedFakeClock& FakeClock() { return *this; }
1827};
1828
1829// Ensure FakeClockForTest is constructed first (see class for rationale).
1830class PeerConnectionIntegrationTestWithFakeClock
1831 : public FakeClockForTest,
1832 public PeerConnectionIntegrationTest {};
1833
Seth Hampson2f0d7022018-02-20 11:54:42 -08001834class PeerConnectionIntegrationTestPlanB
1835 : public PeerConnectionIntegrationBaseTest {
1836 protected:
1837 PeerConnectionIntegrationTestPlanB()
1838 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
1839};
1840
1841class PeerConnectionIntegrationTestUnifiedPlan
1842 : public PeerConnectionIntegrationBaseTest {
1843 protected:
1844 PeerConnectionIntegrationTestUnifiedPlan()
1845 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
1846};
1847
deadbeef1dcb1642017-03-29 21:08:16 -07001848// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
1849// includes testing that the callback is invoked if an observer is connected
1850// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001851TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001852 RtpReceiverObserverOnFirstPacketReceived) {
1853 ASSERT_TRUE(CreatePeerConnectionWrappers());
1854 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001855 caller()->AddAudioVideoTracks();
1856 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001857 // Start offer/answer exchange and wait for it to complete.
1858 caller()->CreateAndSetAndSignalOffer();
1859 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1860 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001861 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1862 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001863 // Wait for all "first packet received" callbacks to be fired.
1864 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -08001865 absl::c_all_of(caller()->rtp_receiver_observers(),
1866 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1867 return o->first_packet_received();
1868 }),
deadbeef1dcb1642017-03-29 21:08:16 -07001869 kMaxWaitForFramesMs);
1870 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -08001871 absl::c_all_of(callee()->rtp_receiver_observers(),
1872 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1873 return o->first_packet_received();
1874 }),
deadbeef1dcb1642017-03-29 21:08:16 -07001875 kMaxWaitForFramesMs);
1876 // If new observers are set after the first packet was already received, the
1877 // callback should still be invoked.
1878 caller()->ResetRtpReceiverObservers();
1879 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001880 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1881 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001882 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -08001883 absl::c_all_of(caller()->rtp_receiver_observers(),
1884 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1885 return o->first_packet_received();
1886 }));
deadbeef1dcb1642017-03-29 21:08:16 -07001887 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -08001888 absl::c_all_of(callee()->rtp_receiver_observers(),
1889 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1890 return o->first_packet_received();
1891 }));
deadbeef1dcb1642017-03-29 21:08:16 -07001892}
1893
1894class DummyDtmfObserver : public DtmfSenderObserverInterface {
1895 public:
1896 DummyDtmfObserver() : completed_(false) {}
1897
1898 // Implements DtmfSenderObserverInterface.
1899 void OnToneChange(const std::string& tone) override {
1900 tones_.push_back(tone);
1901 if (tone.empty()) {
1902 completed_ = true;
1903 }
1904 }
1905
1906 const std::vector<std::string>& tones() const { return tones_; }
1907 bool completed() const { return completed_; }
1908
1909 private:
1910 bool completed_;
1911 std::vector<std::string> tones_;
1912};
1913
1914// Assumes |sender| already has an audio track added and the offer/answer
1915// exchange is done.
1916void TestDtmfFromSenderToReceiver(PeerConnectionWrapper* sender,
1917 PeerConnectionWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -08001918 // We should be able to get a DTMF sender from the local sender.
1919 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
1920 sender->pc()->GetSenders().at(0)->GetDtmfSender();
1921 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -07001922 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -07001923 dtmf_sender->RegisterObserver(&observer);
1924
1925 // Test the DtmfSender object just created.
1926 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
1927 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
1928
1929 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
1930 std::vector<std::string> tones = {"1", "a", ""};
1931 EXPECT_EQ(tones, observer.tones());
1932 dtmf_sender->UnregisterObserver();
1933 // TODO(deadbeef): Verify the tones were actually received end-to-end.
1934}
1935
1936// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
1937// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001938TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -07001939 ASSERT_TRUE(CreatePeerConnectionWrappers());
1940 ConnectFakeSignaling();
1941 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -08001942 caller()->AddAudioTrack();
1943 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001944 caller()->CreateAndSetAndSignalOffer();
1945 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -07001946 // DTLS must finish before the DTMF sender can be used reliably.
1947 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001948 TestDtmfFromSenderToReceiver(caller(), callee());
1949 TestDtmfFromSenderToReceiver(callee(), caller());
1950}
1951
1952// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
1953// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001954TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -07001955 ASSERT_TRUE(CreatePeerConnectionWrappers());
1956 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +01001957
deadbeef1dcb1642017-03-29 21:08:16 -07001958 // Do normal offer/answer and wait for some frames to be received in each
1959 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001960 caller()->AddAudioVideoTracks();
1961 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001962 caller()->CreateAndSetAndSignalOffer();
1963 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001964 MediaExpectations media_expectations;
1965 media_expectations.ExpectBidirectionalAudioAndVideo();
1966 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Ying Wangef3998f2019-12-09 13:06:53 +01001967 EXPECT_METRIC_LE(
1968 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1969 webrtc::kEnumCounterKeyProtocolDtls));
1970 EXPECT_METRIC_EQ(
1971 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1972 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -07001973}
1974
1975// Uses SDES instead of DTLS for key agreement.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001976TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
deadbeef1dcb1642017-03-29 21:08:16 -07001977 PeerConnectionInterface::RTCConfiguration sdes_config;
1978 sdes_config.enable_dtls_srtp.emplace(false);
1979 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
1980 ConnectFakeSignaling();
1981
1982 // Do normal offer/answer and wait for some frames to be received in each
1983 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001984 caller()->AddAudioVideoTracks();
1985 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001986 caller()->CreateAndSetAndSignalOffer();
1987 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001988 MediaExpectations media_expectations;
1989 media_expectations.ExpectBidirectionalAudioAndVideo();
1990 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Ying Wangef3998f2019-12-09 13:06:53 +01001991 EXPECT_METRIC_LE(
1992 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1993 webrtc::kEnumCounterKeyProtocolSdes));
1994 EXPECT_METRIC_EQ(
1995 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1996 webrtc::kEnumCounterKeyProtocolDtls));
deadbeef1dcb1642017-03-29 21:08:16 -07001997}
1998
Steve Anton9a44b2d2019-07-12 12:58:30 -07001999// Basic end-to-end test specifying the |enable_encrypted_rtp_header_extensions|
2000// option to offer encrypted versions of all header extensions alongside the
2001// unencrypted versions.
2002TEST_P(PeerConnectionIntegrationTest,
2003 EndToEndCallWithEncryptedRtpHeaderExtensions) {
2004 CryptoOptions crypto_options;
2005 crypto_options.srtp.enable_encrypted_rtp_header_extensions = true;
2006 PeerConnectionInterface::RTCConfiguration config;
2007 config.crypto_options = crypto_options;
2008 // Note: This allows offering >14 RTP header extensions.
2009 config.offer_extmap_allow_mixed = true;
2010 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2011 ConnectFakeSignaling();
2012
2013 // Do normal offer/answer and wait for some frames to be received in each
2014 // direction.
2015 caller()->AddAudioVideoTracks();
2016 callee()->AddAudioVideoTracks();
2017 caller()->CreateAndSetAndSignalOffer();
2018 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2019 MediaExpectations media_expectations;
2020 media_expectations.ExpectBidirectionalAudioAndVideo();
2021 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2022}
2023
deadbeef1dcb1642017-03-29 21:08:16 -07002024// This test sets up a call between two parties with a source resolution of
2025// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002026TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002027 Send1280By720ResolutionAndReceive16To9AspectRatio) {
2028 ASSERT_TRUE(CreatePeerConnectionWrappers());
2029 ConnectFakeSignaling();
2030
Niels Möller5c7efe72018-05-11 10:34:46 +02002031 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
2032 webrtc::FakePeriodicVideoSource::Config config;
2033 config.width = 1280;
2034 config.height = 720;
Johannes Kron965e7942018-09-13 15:36:20 +02002035 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +02002036 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
2037 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -07002038
2039 // Do normal offer/answer and wait for at least one frame to be received in
2040 // each direction.
2041 caller()->CreateAndSetAndSignalOffer();
2042 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2043 callee()->min_video_frames_received_per_track() > 0,
2044 kMaxWaitForFramesMs);
2045
2046 // Check rendered aspect ratio.
2047 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
2048 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
2049 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
2050 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
2051}
2052
2053// This test sets up an one-way call, with media only from caller to
2054// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002055TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -07002056 ASSERT_TRUE(CreatePeerConnectionWrappers());
2057 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002058 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002059 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002060 MediaExpectations media_expectations;
2061 media_expectations.CalleeExpectsSomeAudioAndVideo();
2062 media_expectations.CallerExpectsNoAudio();
2063 media_expectations.CallerExpectsNoVideo();
2064 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002065}
2066
Johannes Kron3e983682020-03-29 22:17:00 +02002067// Tests that send only works without the caller having a decoder factory and
2068// the callee having an encoder factory.
2069TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSendOnlyVideo) {
2070 ASSERT_TRUE(
2071 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
2072 ConnectFakeSignaling();
2073 // Add one-directional video, from caller to callee.
2074 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2075 caller()->CreateLocalVideoTrack();
2076 caller()->AddTrack(caller_track);
2077 PeerConnectionInterface::RTCOfferAnswerOptions options;
2078 options.offer_to_receive_video = 0;
2079 caller()->SetOfferAnswerOptions(options);
2080 caller()->CreateAndSetAndSignalOffer();
2081 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2082 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2083
2084 // Expect video to be received in one direction.
2085 MediaExpectations media_expectations;
2086 media_expectations.CallerExpectsNoVideo();
2087 media_expectations.CalleeExpectsSomeVideo();
2088
2089 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2090}
2091
2092// Tests that receive only works without the caller having an encoder factory
2093// and the callee having a decoder factory.
2094TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithReceiveOnlyVideo) {
2095 ASSERT_TRUE(
2096 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/false));
2097 ConnectFakeSignaling();
2098 // Add one-directional video, from callee to caller.
2099 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2100 callee()->CreateLocalVideoTrack();
2101 callee()->AddTrack(callee_track);
2102 PeerConnectionInterface::RTCOfferAnswerOptions options;
2103 options.offer_to_receive_video = 1;
2104 caller()->SetOfferAnswerOptions(options);
2105 caller()->CreateAndSetAndSignalOffer();
2106 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2107 ASSERT_EQ(caller()->pc()->GetReceivers().size(), 1u);
2108
2109 // Expect video to be received in one direction.
2110 MediaExpectations media_expectations;
2111 media_expectations.CallerExpectsSomeVideo();
2112 media_expectations.CalleeExpectsNoVideo();
2113
2114 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2115}
2116
2117TEST_P(PeerConnectionIntegrationTest,
2118 EndToEndCallAddReceiveVideoToSendOnlyCall) {
2119 ASSERT_TRUE(CreatePeerConnectionWrappers());
2120 ConnectFakeSignaling();
2121 // Add one-directional video, from caller to callee.
2122 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2123 caller()->CreateLocalVideoTrack();
2124 caller()->AddTrack(caller_track);
2125 caller()->CreateAndSetAndSignalOffer();
2126 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2127
2128 // Add receive video.
2129 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2130 callee()->CreateLocalVideoTrack();
2131 callee()->AddTrack(callee_track);
2132 caller()->CreateAndSetAndSignalOffer();
2133 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2134
2135 // Ensure that video frames are received end-to-end.
2136 MediaExpectations media_expectations;
2137 media_expectations.ExpectBidirectionalVideo();
2138 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2139}
2140
2141TEST_P(PeerConnectionIntegrationTest,
2142 EndToEndCallAddSendVideoToReceiveOnlyCall) {
2143 ASSERT_TRUE(CreatePeerConnectionWrappers());
2144 ConnectFakeSignaling();
2145 // Add one-directional video, from callee to caller.
2146 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2147 callee()->CreateLocalVideoTrack();
2148 callee()->AddTrack(callee_track);
2149 caller()->CreateAndSetAndSignalOffer();
2150 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2151
2152 // Add send video.
2153 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2154 caller()->CreateLocalVideoTrack();
2155 caller()->AddTrack(caller_track);
2156 caller()->CreateAndSetAndSignalOffer();
2157 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2158
2159 // Expect video to be received in one direction.
2160 MediaExpectations media_expectations;
2161 media_expectations.ExpectBidirectionalVideo();
2162 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2163}
2164
2165TEST_P(PeerConnectionIntegrationTest,
2166 EndToEndCallRemoveReceiveVideoFromSendReceiveCall) {
2167 ASSERT_TRUE(CreatePeerConnectionWrappers());
2168 ConnectFakeSignaling();
2169 // Add send video, from caller to callee.
2170 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2171 caller()->CreateLocalVideoTrack();
2172 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
2173 caller()->AddTrack(caller_track);
2174 // Add receive video, from callee to caller.
2175 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2176 callee()->CreateLocalVideoTrack();
2177
2178 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
2179 callee()->AddTrack(callee_track);
2180 caller()->CreateAndSetAndSignalOffer();
2181 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2182
2183 // Remove receive video (i.e., callee sender track).
2184 callee()->pc()->RemoveTrack(callee_sender);
2185
2186 caller()->CreateAndSetAndSignalOffer();
2187 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2188
2189 // Expect one-directional video.
2190 MediaExpectations media_expectations;
2191 media_expectations.CallerExpectsNoVideo();
2192 media_expectations.CalleeExpectsSomeVideo();
2193
2194 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2195}
2196
2197TEST_P(PeerConnectionIntegrationTest,
2198 EndToEndCallRemoveSendVideoFromSendReceiveCall) {
2199 ASSERT_TRUE(CreatePeerConnectionWrappers());
2200 ConnectFakeSignaling();
2201 // Add send video, from caller to callee.
2202 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2203 caller()->CreateLocalVideoTrack();
2204 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
2205 caller()->AddTrack(caller_track);
2206 // Add receive video, from callee to caller.
2207 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2208 callee()->CreateLocalVideoTrack();
2209
2210 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
2211 callee()->AddTrack(callee_track);
2212 caller()->CreateAndSetAndSignalOffer();
2213 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2214
2215 // Remove send video (i.e., caller sender track).
2216 caller()->pc()->RemoveTrack(caller_sender);
2217
2218 caller()->CreateAndSetAndSignalOffer();
2219 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2220
2221 // Expect one-directional video.
2222 MediaExpectations media_expectations;
2223 media_expectations.CalleeExpectsNoVideo();
2224 media_expectations.CallerExpectsSomeVideo();
2225
2226 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2227}
2228
deadbeef1dcb1642017-03-29 21:08:16 -07002229// This test sets up a audio call initially, with the callee rejecting video
2230// initially. Then later the callee decides to upgrade to audio/video, and
2231// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002232TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -07002233 ASSERT_TRUE(CreatePeerConnectionWrappers());
2234 ConnectFakeSignaling();
2235 // Initially, offer an audio/video stream from the caller, but refuse to
2236 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -08002237 caller()->AddAudioVideoTracks();
2238 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002239 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2240 PeerConnectionInterface::RTCOfferAnswerOptions options;
2241 options.offer_to_receive_video = 0;
2242 callee()->SetOfferAnswerOptions(options);
2243 } else {
2244 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002245 callee()
2246 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2247 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002248 });
2249 }
deadbeef1dcb1642017-03-29 21:08:16 -07002250 // Do offer/answer and make sure audio is still received end-to-end.
2251 caller()->CreateAndSetAndSignalOffer();
2252 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002253 {
2254 MediaExpectations media_expectations;
2255 media_expectations.ExpectBidirectionalAudio();
2256 media_expectations.ExpectNoVideo();
2257 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2258 }
deadbeef1dcb1642017-03-29 21:08:16 -07002259 // Sanity check that the callee's description has a rejected video section.
2260 ASSERT_NE(nullptr, callee()->pc()->local_description());
2261 const ContentInfo* callee_video_content =
2262 GetFirstVideoContent(callee()->pc()->local_description()->description());
2263 ASSERT_NE(nullptr, callee_video_content);
2264 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002265
deadbeef1dcb1642017-03-29 21:08:16 -07002266 // Now negotiate with video and ensure negotiation succeeds, with video
2267 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -08002268 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002269 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2270 PeerConnectionInterface::RTCOfferAnswerOptions options;
2271 options.offer_to_receive_video = 1;
2272 callee()->SetOfferAnswerOptions(options);
2273 } else {
2274 callee()->SetRemoteOfferHandler(nullptr);
2275 caller()->SetRemoteOfferHandler([this] {
2276 // The caller creates a new transceiver to receive video on when receiving
2277 // the offer, but by default it is send only.
2278 auto transceivers = caller()->pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +02002279 ASSERT_EQ(2U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002280 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
Harald Alvestrand6060df52020-08-11 09:54:02 +02002281 transceivers[1]->receiver()->media_type());
2282 transceivers[1]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
2283 transceivers[1]->SetDirectionWithError(
2284 RtpTransceiverDirection::kSendRecv);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002285 });
2286 }
deadbeef1dcb1642017-03-29 21:08:16 -07002287 callee()->CreateAndSetAndSignalOffer();
2288 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002289 {
2290 // Expect additional audio frames to be received after the upgrade.
2291 MediaExpectations media_expectations;
2292 media_expectations.ExpectBidirectionalAudioAndVideo();
2293 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2294 }
deadbeef1dcb1642017-03-29 21:08:16 -07002295}
2296
deadbeef4389b4d2017-09-07 09:07:36 -07002297// Simpler than the above test; just add an audio track to an established
2298// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002299TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -07002300 ASSERT_TRUE(CreatePeerConnectionWrappers());
2301 ConnectFakeSignaling();
2302 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -08002303 caller()->AddVideoTrack();
2304 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07002305 caller()->CreateAndSetAndSignalOffer();
2306 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2307 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08002308 caller()->AddAudioTrack();
2309 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07002310 caller()->CreateAndSetAndSignalOffer();
2311 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2312 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002313 MediaExpectations media_expectations;
2314 media_expectations.ExpectBidirectionalAudioAndVideo();
2315 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -07002316}
2317
deadbeef1dcb1642017-03-29 21:08:16 -07002318// This test sets up a call that's transferred to a new caller with a different
2319// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002320TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -07002321 ASSERT_TRUE(CreatePeerConnectionWrappers());
2322 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002323 caller()->AddAudioVideoTracks();
2324 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002325 caller()->CreateAndSetAndSignalOffer();
2326 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2327
2328 // Keep the original peer around which will still send packets to the
2329 // receiving client. These SRTP packets will be dropped.
2330 std::unique_ptr<PeerConnectionWrapper> original_peer(
2331 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002332 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07002333 // TODO(deadbeef): Why do we call Close here? That goes against the comment
2334 // directly above.
2335 original_peer->pc()->Close();
2336
2337 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002338 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002339 caller()->CreateAndSetAndSignalOffer();
2340 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2341 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002342 MediaExpectations media_expectations;
2343 media_expectations.ExpectBidirectionalAudioAndVideo();
2344 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002345}
2346
2347// This test sets up a call that's transferred to a new callee with a different
2348// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002349TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -07002350 ASSERT_TRUE(CreatePeerConnectionWrappers());
2351 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002352 caller()->AddAudioVideoTracks();
2353 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002354 caller()->CreateAndSetAndSignalOffer();
2355 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2356
2357 // Keep the original peer around which will still send packets to the
2358 // receiving client. These SRTP packets will be dropped.
2359 std::unique_ptr<PeerConnectionWrapper> original_peer(
2360 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002361 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07002362 // TODO(deadbeef): Why do we call Close here? That goes against the comment
2363 // directly above.
2364 original_peer->pc()->Close();
2365
2366 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002367 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002368 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2369 caller()->CreateAndSetAndSignalOffer();
2370 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2371 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002372 MediaExpectations media_expectations;
2373 media_expectations.ExpectBidirectionalAudioAndVideo();
2374 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002375}
2376
2377// This test sets up a non-bundled call and negotiates bundling at the same
2378// time as starting an ICE restart. When bundling is in effect in the restart,
2379// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002380TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -07002381 ASSERT_TRUE(CreatePeerConnectionWrappers());
2382 ConnectFakeSignaling();
2383
Steve Anton15324772018-01-16 10:26:49 -08002384 caller()->AddAudioVideoTracks();
2385 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002386 // Remove the bundle group from the SDP received by the callee.
2387 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2388 desc->RemoveGroupByName("BUNDLE");
2389 });
2390 caller()->CreateAndSetAndSignalOffer();
2391 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002392 {
2393 MediaExpectations media_expectations;
2394 media_expectations.ExpectBidirectionalAudioAndVideo();
2395 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2396 }
deadbeef1dcb1642017-03-29 21:08:16 -07002397 // Now stop removing the BUNDLE group, and trigger an ICE restart.
2398 callee()->SetReceivedSdpMunger(nullptr);
2399 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2400 caller()->CreateAndSetAndSignalOffer();
2401 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2402
2403 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002404 {
2405 MediaExpectations media_expectations;
2406 media_expectations.ExpectBidirectionalAudioAndVideo();
2407 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2408 }
deadbeef1dcb1642017-03-29 21:08:16 -07002409}
2410
2411// Test CVO (Coordination of Video Orientation). If a video source is rotated
2412// and both peers support the CVO RTP header extension, the actual video frames
2413// don't need to be encoded in different resolutions, since the rotation is
2414// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002415TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002416 ASSERT_TRUE(CreatePeerConnectionWrappers());
2417 ConnectFakeSignaling();
2418 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002419 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002420 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002421 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002422 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2423
2424 // Wait for video frames to be received by both sides.
2425 caller()->CreateAndSetAndSignalOffer();
2426 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2427 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2428 callee()->min_video_frames_received_per_track() > 0,
2429 kMaxWaitForFramesMs);
2430
2431 // Ensure that the aspect ratio is unmodified.
2432 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2433 // not just assumed.
2434 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
2435 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
2436 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
2437 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
2438 // Ensure that the CVO bits were surfaced to the renderer.
2439 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
2440 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
2441}
2442
2443// Test that when the CVO extension isn't supported, video is rotated the
2444// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002445TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002446 ASSERT_TRUE(CreatePeerConnectionWrappers());
2447 ConnectFakeSignaling();
2448 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002449 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002450 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002451 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002452 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2453
2454 // Remove the CVO extension from the offered SDP.
2455 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2456 cricket::VideoContentDescription* video =
2457 GetFirstVideoContentDescription(desc);
2458 video->ClearRtpHeaderExtensions();
2459 });
2460 // Wait for video frames to be received by both sides.
2461 caller()->CreateAndSetAndSignalOffer();
2462 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2463 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2464 callee()->min_video_frames_received_per_track() > 0,
2465 kMaxWaitForFramesMs);
2466
2467 // Expect that the aspect ratio is inversed to account for the 90/270 degree
2468 // rotation.
2469 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2470 // not just assumed.
2471 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
2472 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
2473 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
2474 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
2475 // Expect that each endpoint is unaware of the rotation of the other endpoint.
2476 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
2477 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
2478}
2479
deadbeef1dcb1642017-03-29 21:08:16 -07002480// Test that if the answerer rejects the audio m= section, no audio is sent or
2481// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002482TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002483 ASSERT_TRUE(CreatePeerConnectionWrappers());
2484 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002485 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002486 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2487 // Only add video track for callee, and set offer_to_receive_audio to 0, so
2488 // it will reject the audio m= section completely.
2489 PeerConnectionInterface::RTCOfferAnswerOptions options;
2490 options.offer_to_receive_audio = 0;
2491 callee()->SetOfferAnswerOptions(options);
2492 } else {
2493 // Stopping the audio RtpTransceiver will cause the media section to be
2494 // rejected in the answer.
2495 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002496 callee()
2497 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
2498 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002499 });
2500 }
Steve Anton15324772018-01-16 10:26:49 -08002501 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002502 // Do offer/answer and wait for successful end-to-end video frames.
2503 caller()->CreateAndSetAndSignalOffer();
2504 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002505 MediaExpectations media_expectations;
2506 media_expectations.ExpectBidirectionalVideo();
2507 media_expectations.ExpectNoAudio();
2508 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2509
deadbeef1dcb1642017-03-29 21:08:16 -07002510 // Sanity check that the callee's description has a rejected audio section.
2511 ASSERT_NE(nullptr, callee()->pc()->local_description());
2512 const ContentInfo* callee_audio_content =
2513 GetFirstAudioContent(callee()->pc()->local_description()->description());
2514 ASSERT_NE(nullptr, callee_audio_content);
2515 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002516 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002517 // The caller's transceiver should have stopped after receiving the answer,
2518 // and thus no longer listed in transceivers.
2519 EXPECT_EQ(nullptr,
2520 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002521 }
deadbeef1dcb1642017-03-29 21:08:16 -07002522}
2523
2524// Test that if the answerer rejects the video m= section, no video is sent or
2525// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002526TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002527 ASSERT_TRUE(CreatePeerConnectionWrappers());
2528 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002529 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002530 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2531 // Only add audio track for callee, and set offer_to_receive_video to 0, so
2532 // it will reject the video m= section completely.
2533 PeerConnectionInterface::RTCOfferAnswerOptions options;
2534 options.offer_to_receive_video = 0;
2535 callee()->SetOfferAnswerOptions(options);
2536 } else {
2537 // Stopping the video RtpTransceiver will cause the media section to be
2538 // rejected in the answer.
2539 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002540 callee()
2541 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2542 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002543 });
2544 }
Steve Anton15324772018-01-16 10:26:49 -08002545 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002546 // Do offer/answer and wait for successful end-to-end audio frames.
2547 caller()->CreateAndSetAndSignalOffer();
2548 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002549 MediaExpectations media_expectations;
2550 media_expectations.ExpectBidirectionalAudio();
2551 media_expectations.ExpectNoVideo();
2552 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2553
deadbeef1dcb1642017-03-29 21:08:16 -07002554 // Sanity check that the callee's description has a rejected video section.
2555 ASSERT_NE(nullptr, callee()->pc()->local_description());
2556 const ContentInfo* callee_video_content =
2557 GetFirstVideoContent(callee()->pc()->local_description()->description());
2558 ASSERT_NE(nullptr, callee_video_content);
2559 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002560 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002561 // The caller's transceiver should have stopped after receiving the answer,
2562 // and thus is no longer present.
2563 EXPECT_EQ(nullptr,
2564 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002565 }
deadbeef1dcb1642017-03-29 21:08:16 -07002566}
2567
2568// Test that if the answerer rejects both audio and video m= sections, nothing
2569// bad happens.
2570// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
2571// test anything but the fact that negotiation succeeds, which doesn't mean
2572// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002573TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -07002574 ASSERT_TRUE(CreatePeerConnectionWrappers());
2575 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002576 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002577 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2578 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
2579 // will reject both audio and video m= sections.
2580 PeerConnectionInterface::RTCOfferAnswerOptions options;
2581 options.offer_to_receive_audio = 0;
2582 options.offer_to_receive_video = 0;
2583 callee()->SetOfferAnswerOptions(options);
2584 } else {
2585 callee()->SetRemoteOfferHandler([this] {
2586 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +01002587 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002588 transceiver->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002589 }
2590 });
2591 }
deadbeef1dcb1642017-03-29 21:08:16 -07002592 // Do offer/answer and wait for stable signaling state.
2593 caller()->CreateAndSetAndSignalOffer();
2594 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002595
deadbeef1dcb1642017-03-29 21:08:16 -07002596 // Sanity check that the callee's description has rejected m= sections.
2597 ASSERT_NE(nullptr, callee()->pc()->local_description());
2598 const ContentInfo* callee_audio_content =
2599 GetFirstAudioContent(callee()->pc()->local_description()->description());
2600 ASSERT_NE(nullptr, callee_audio_content);
2601 EXPECT_TRUE(callee_audio_content->rejected);
2602 const ContentInfo* callee_video_content =
2603 GetFirstVideoContent(callee()->pc()->local_description()->description());
2604 ASSERT_NE(nullptr, callee_video_content);
2605 EXPECT_TRUE(callee_video_content->rejected);
2606}
2607
2608// This test sets up an audio and video call between two parties. After the
2609// call runs for a while, the caller sends an updated offer with video being
2610// rejected. Once the re-negotiation is done, the video flow should stop and
2611// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002612TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07002613 ASSERT_TRUE(CreatePeerConnectionWrappers());
2614 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002615 caller()->AddAudioVideoTracks();
2616 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002617 caller()->CreateAndSetAndSignalOffer();
2618 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002619 {
2620 MediaExpectations media_expectations;
2621 media_expectations.ExpectBidirectionalAudioAndVideo();
2622 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2623 }
deadbeef1dcb1642017-03-29 21:08:16 -07002624 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002625 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2626 caller()->SetGeneratedSdpMunger(
2627 [](cricket::SessionDescription* description) {
2628 for (cricket::ContentInfo& content : description->contents()) {
2629 if (cricket::IsVideoContent(&content)) {
2630 content.rejected = true;
2631 }
2632 }
2633 });
2634 } else {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002635 caller()
2636 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2637 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002638 }
deadbeef1dcb1642017-03-29 21:08:16 -07002639 caller()->CreateAndSetAndSignalOffer();
2640 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2641
2642 // Sanity check that the caller's description has a rejected video section.
2643 ASSERT_NE(nullptr, caller()->pc()->local_description());
2644 const ContentInfo* caller_video_content =
2645 GetFirstVideoContent(caller()->pc()->local_description()->description());
2646 ASSERT_NE(nullptr, caller_video_content);
2647 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -07002648 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002649 {
2650 MediaExpectations media_expectations;
2651 media_expectations.ExpectBidirectionalAudio();
2652 media_expectations.ExpectNoVideo();
2653 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2654 }
deadbeef1dcb1642017-03-29 21:08:16 -07002655}
2656
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -07002657// Do one offer/answer with audio, another that disables it (rejecting the m=
2658// section), and another that re-enables it. Regression test for:
2659// bugs.webrtc.org/6023
2660TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
2661 ASSERT_TRUE(CreatePeerConnectionWrappers());
2662 ConnectFakeSignaling();
2663
2664 // Add audio track, do normal offer/answer.
2665 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2666 caller()->CreateLocalAudioTrack();
2667 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2668 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2669 caller()->CreateAndSetAndSignalOffer();
2670 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2671
2672 // Remove audio track, and set offer_to_receive_audio to false to cause the
2673 // m= section to be completely disabled, not just "recvonly".
2674 caller()->pc()->RemoveTrack(sender);
2675 PeerConnectionInterface::RTCOfferAnswerOptions options;
2676 options.offer_to_receive_audio = 0;
2677 caller()->SetOfferAnswerOptions(options);
2678 caller()->CreateAndSetAndSignalOffer();
2679 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2680
2681 // Add the audio track again, expecting negotiation to succeed and frames to
2682 // flow.
2683 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2684 options.offer_to_receive_audio = 1;
2685 caller()->SetOfferAnswerOptions(options);
2686 caller()->CreateAndSetAndSignalOffer();
2687 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2688
2689 MediaExpectations media_expectations;
2690 media_expectations.CalleeExpectsSomeAudio();
2691 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2692}
2693
deadbeef1dcb1642017-03-29 21:08:16 -07002694// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
2695// is needed to support legacy endpoints.
2696// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
2697// add a test for an end-to-end test without MID signaling either (basically,
2698// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002699TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -07002700 ASSERT_TRUE(CreatePeerConnectionWrappers());
2701 ConnectFakeSignaling();
2702 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08002703 caller()->AddAudioVideoTracks();
2704 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07002705 // Remove SSRCs and MSIDs from the received offer SDP.
2706 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07002707 caller()->CreateAndSetAndSignalOffer();
2708 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002709 MediaExpectations media_expectations;
2710 media_expectations.ExpectBidirectionalAudioAndVideo();
2711 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002712}
2713
Seth Hampson5897a6e2018-04-03 11:16:33 -07002714// Basic end-to-end test, without SSRC signaling. This means that the track
2715// was created properly and frames are delivered when the MSIDs are communicated
2716// with a=msid lines and no a=ssrc lines.
2717TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2718 EndToEndCallWithoutSsrcSignaling) {
2719 const char kStreamId[] = "streamId";
2720 ASSERT_TRUE(CreatePeerConnectionWrappers());
2721 ConnectFakeSignaling();
2722 // Add just audio tracks.
2723 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
2724 callee()->AddAudioTrack();
2725
2726 // Remove SSRCs from the received offer SDP.
2727 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
2728 caller()->CreateAndSetAndSignalOffer();
2729 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2730 MediaExpectations media_expectations;
2731 media_expectations.ExpectBidirectionalAudio();
2732 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2733}
2734
Johannes Kron3e983682020-03-29 22:17:00 +02002735TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2736 EndToEndCallAddReceiveVideoToSendOnlyCall) {
2737 ASSERT_TRUE(CreatePeerConnectionWrappers());
2738 ConnectFakeSignaling();
2739 // Add one-directional video, from caller to callee.
2740 rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
2741 caller()->CreateLocalVideoTrack();
2742
2743 RtpTransceiverInit video_transceiver_init;
2744 video_transceiver_init.stream_ids = {"video1"};
2745 video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly;
2746 auto video_sender =
2747 caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue();
2748 caller()->CreateAndSetAndSignalOffer();
2749 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2750
2751 // Add receive direction.
Harald Alvestrand6060df52020-08-11 09:54:02 +02002752 video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);
Johannes Kron3e983682020-03-29 22:17:00 +02002753
2754 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2755 callee()->CreateLocalVideoTrack();
2756
2757 callee()->AddTrack(callee_track);
2758 caller()->CreateAndSetAndSignalOffer();
2759 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2760 // Ensure that video frames are received end-to-end.
2761 MediaExpectations media_expectations;
2762 media_expectations.ExpectBidirectionalVideo();
2763 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2764}
2765
Steve Antondf527fd2018-04-27 15:52:03 -07002766// Tests that video flows between multiple video tracks when SSRCs are not
2767// signaled. This exercises the MID RTP header extension which is needed to
2768// demux the incoming video tracks.
2769TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2770 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
2771 ASSERT_TRUE(CreatePeerConnectionWrappers());
2772 ConnectFakeSignaling();
2773 caller()->AddVideoTrack();
2774 caller()->AddVideoTrack();
2775 callee()->AddVideoTrack();
2776 callee()->AddVideoTrack();
2777
2778 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2779 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2780 caller()->CreateAndSetAndSignalOffer();
2781 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2782 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2783 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2784
2785 // Expect video to be received in both directions on both tracks.
2786 MediaExpectations media_expectations;
2787 media_expectations.ExpectBidirectionalVideo();
2788 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2789}
2790
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -07002791// Used for the test below.
2792void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
2793 RemoveSsrcsAndKeepMsids(desc);
2794 desc->RemoveGroupByName("BUNDLE");
2795 for (ContentInfo& content : desc->contents()) {
2796 cricket::MediaContentDescription* media = content.media_description();
2797 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
2798 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
2799 [](const RtpExtension& extension) {
2800 return extension.uri ==
2801 RtpExtension::kMidUri;
2802 }),
2803 extensions.end());
2804 media->set_rtp_header_extensions(extensions);
2805 }
2806}
2807
2808// Tests that video flows between multiple video tracks when BUNDLE is not used,
2809// SSRCs are not signaled and the MID RTP header extension is not used. This
2810// relies on demuxing by payload type, which normally doesn't work if you have
2811// multiple media sections using the same payload type, but which should work as
2812// long as the media sections aren't bundled.
2813// Regression test for: http://crbug.com/webrtc/12023
2814TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2815 EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid) {
2816 ASSERT_TRUE(CreatePeerConnectionWrappers());
2817 ConnectFakeSignaling();
2818 caller()->AddVideoTrack();
2819 caller()->AddVideoTrack();
2820 callee()->AddVideoTrack();
2821 callee()->AddVideoTrack();
2822 caller()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
2823 callee()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
2824 caller()->CreateAndSetAndSignalOffer();
2825 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2826 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2827 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2828 // Make sure we are not bundled.
2829 ASSERT_NE(caller()->pc()->GetSenders()[0]->dtls_transport(),
2830 caller()->pc()->GetSenders()[1]->dtls_transport());
2831
2832 // Expect video to be received in both directions on both tracks.
2833 MediaExpectations media_expectations;
2834 media_expectations.ExpectBidirectionalVideo();
2835 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2836}
2837
2838// Used for the test below.
2839void ModifyPayloadTypesAndRemoveMidExtension(
2840 cricket::SessionDescription* desc) {
2841 int pt = 96;
2842 for (ContentInfo& content : desc->contents()) {
2843 cricket::MediaContentDescription* media = content.media_description();
2844 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
2845 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
2846 [](const RtpExtension& extension) {
2847 return extension.uri ==
2848 RtpExtension::kMidUri;
2849 }),
2850 extensions.end());
2851 media->set_rtp_header_extensions(extensions);
2852 cricket::VideoContentDescription* video = media->as_video();
2853 ASSERT_TRUE(video != nullptr);
2854 std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
2855 video->set_codecs(codecs);
2856 }
2857}
2858
2859// Tests that two video tracks can be demultiplexed by payload type alone, by
2860// using different payload types for the same codec in different m= sections.
2861// This practice is discouraged but historically has been supported.
2862// Regression test for: http://crbug.com/webrtc/12029
2863TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2864 EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType) {
2865 ASSERT_TRUE(CreatePeerConnectionWrappers());
2866 ConnectFakeSignaling();
2867 caller()->AddVideoTrack();
2868 caller()->AddVideoTrack();
2869 callee()->AddVideoTrack();
2870 callee()->AddVideoTrack();
2871 caller()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
2872 callee()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
2873 // We can't remove SSRCs from the generated SDP because then no send streams
2874 // would be created.
2875 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2876 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2877 caller()->CreateAndSetAndSignalOffer();
2878 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2879 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2880 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2881 // Make sure we are bundled.
2882 ASSERT_EQ(caller()->pc()->GetSenders()[0]->dtls_transport(),
2883 caller()->pc()->GetSenders()[1]->dtls_transport());
2884
2885 // Expect video to be received in both directions on both tracks.
2886 MediaExpectations media_expectations;
2887 media_expectations.ExpectBidirectionalVideo();
2888 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2889}
2890
Henrik Boström5b147782018-12-04 11:25:05 +01002891TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
2892 ASSERT_TRUE(CreatePeerConnectionWrappers());
2893 ConnectFakeSignaling();
2894 caller()->AddAudioTrack();
2895 caller()->AddVideoTrack();
2896 caller()->CreateAndSetAndSignalOffer();
2897 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2898 auto callee_receivers = callee()->pc()->GetReceivers();
2899 ASSERT_EQ(2u, callee_receivers.size());
2900 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
2901 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
2902}
2903
2904TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
2905 ASSERT_TRUE(CreatePeerConnectionWrappers());
2906 ConnectFakeSignaling();
2907 caller()->AddAudioTrack();
2908 caller()->AddVideoTrack();
2909 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2910 caller()->CreateAndSetAndSignalOffer();
2911 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2912 auto callee_receivers = callee()->pc()->GetReceivers();
2913 ASSERT_EQ(2u, callee_receivers.size());
2914 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
2915 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
2916 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
2917 callee_receivers[1]->stream_ids()[0]);
2918 EXPECT_EQ(callee_receivers[0]->streams()[0],
2919 callee_receivers[1]->streams()[0]);
2920}
2921
deadbeef1dcb1642017-03-29 21:08:16 -07002922// Test that if two video tracks are sent (from caller to callee, in this test),
2923// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002924TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07002925 ASSERT_TRUE(CreatePeerConnectionWrappers());
2926 ConnectFakeSignaling();
2927 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08002928 caller()->AddAudioVideoTracks();
2929 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002930 caller()->CreateAndSetAndSignalOffer();
2931 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08002932 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002933
2934 MediaExpectations media_expectations;
2935 media_expectations.CalleeExpectsSomeAudioAndVideo();
2936 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002937}
2938
2939static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
2940 bool first = true;
2941 for (cricket::ContentInfo& content : desc->contents()) {
2942 if (first) {
2943 first = false;
2944 continue;
2945 }
2946 content.bundle_only = true;
2947 }
2948 first = true;
2949 for (cricket::TransportInfo& transport : desc->transport_infos()) {
2950 if (first) {
2951 first = false;
2952 continue;
2953 }
2954 transport.description.ice_ufrag.clear();
2955 transport.description.ice_pwd.clear();
2956 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
2957 transport.description.identity_fingerprint.reset(nullptr);
2958 }
2959}
2960
2961// Test that if applying a true "max bundle" offer, which uses ports of 0,
2962// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
2963// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
2964// successfully and media flows.
2965// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
2966// TODO(deadbeef): Won't need this test once we start generating actual
2967// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002968TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002969 EndToEndCallWithSpecCompliantMaxBundleOffer) {
2970 ASSERT_TRUE(CreatePeerConnectionWrappers());
2971 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002972 caller()->AddAudioVideoTracks();
2973 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002974 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
2975 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
2976 // but the first m= section.
2977 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
2978 caller()->CreateAndSetAndSignalOffer();
2979 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002980 MediaExpectations media_expectations;
2981 media_expectations.ExpectBidirectionalAudioAndVideo();
2982 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002983}
2984
2985// Test that we can receive the audio output level from a remote audio track.
2986// TODO(deadbeef): Use a fake audio source and verify that the output level is
2987// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002988TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002989 ASSERT_TRUE(CreatePeerConnectionWrappers());
2990 ConnectFakeSignaling();
2991 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002992 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002993 caller()->CreateAndSetAndSignalOffer();
2994 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2995
2996 // Get the audio output level stats. Note that the level is not available
2997 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07002998 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002999 kMaxWaitForFramesMs);
3000}
3001
3002// Test that an audio input level is reported.
3003// TODO(deadbeef): Use a fake audio source and verify that the input level is
3004// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003005TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07003006 ASSERT_TRUE(CreatePeerConnectionWrappers());
3007 ConnectFakeSignaling();
3008 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08003009 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07003010 caller()->CreateAndSetAndSignalOffer();
3011 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3012
3013 // Get the audio input level stats. The level should be available very
3014 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07003015 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07003016 kMaxWaitForStatsMs);
3017}
3018
3019// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003020TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07003021 ASSERT_TRUE(CreatePeerConnectionWrappers());
3022 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003023 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003024 // Do offer/answer, wait for the callee to receive some frames.
3025 caller()->CreateAndSetAndSignalOffer();
3026 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003027
3028 MediaExpectations media_expectations;
3029 media_expectations.CalleeExpectsSomeAudioAndVideo();
3030 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003031
3032 // Get a handle to the remote tracks created, so they can be used as GetStats
3033 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01003034 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08003035 // We received frames, so we definitely should have nonzero "received bytes"
3036 // stats at this point.
3037 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
3038 0);
3039 }
deadbeef1dcb1642017-03-29 21:08:16 -07003040}
3041
3042// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003043TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07003044 ASSERT_TRUE(CreatePeerConnectionWrappers());
3045 ConnectFakeSignaling();
3046 auto audio_track = caller()->CreateLocalAudioTrack();
3047 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08003048 caller()->AddTrack(audio_track);
3049 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07003050 // Do offer/answer, wait for the callee to receive some frames.
3051 caller()->CreateAndSetAndSignalOffer();
3052 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003053 MediaExpectations media_expectations;
3054 media_expectations.CalleeExpectsSomeAudioAndVideo();
3055 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003056
3057 // The callee received frames, so we definitely should have nonzero "sent
3058 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07003059 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
3060 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
3061}
3062
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003063// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003064TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003065 ASSERT_TRUE(CreatePeerConnectionWrappers());
3066 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003067 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003068
Steve Anton15324772018-01-16 10:26:49 -08003069 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003070
3071 // Do offer/answer, wait for the callee to receive some frames.
3072 caller()->CreateAndSetAndSignalOffer();
3073 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3074
3075 // Get the remote audio track created on the receiver, so they can be used as
3076 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08003077 auto receivers = callee()->pc()->GetReceivers();
3078 ASSERT_EQ(1u, receivers.size());
3079 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003080
3081 // Get the audio output level stats. Note that the level is not available
3082 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07003083 EXPECT_TRUE_WAIT(
3084 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
3085 0,
3086 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003087}
3088
Steve Antona41959e2018-11-28 11:15:33 -08003089// Test that the track ID is associated with all local and remote SSRC stats
3090// using the old GetStats() and more than 1 audio and more than 1 video track.
3091// This is a regression test for crbug.com/906988
3092TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3093 OldGetStatsAssociatesTrackIdForManyMediaSections) {
3094 ASSERT_TRUE(CreatePeerConnectionWrappers());
3095 ConnectFakeSignaling();
3096 auto audio_sender_1 = caller()->AddAudioTrack();
3097 auto video_sender_1 = caller()->AddVideoTrack();
3098 auto audio_sender_2 = caller()->AddAudioTrack();
3099 auto video_sender_2 = caller()->AddVideoTrack();
3100 caller()->CreateAndSetAndSignalOffer();
3101 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3102
3103 MediaExpectations media_expectations;
3104 media_expectations.CalleeExpectsSomeAudioAndVideo();
3105 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
3106
3107 std::vector<std::string> track_ids = {
3108 audio_sender_1->track()->id(), video_sender_1->track()->id(),
3109 audio_sender_2->track()->id(), video_sender_2->track()->id()};
3110
3111 auto caller_stats = caller()->OldGetStats();
3112 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
3113 auto callee_stats = callee()->OldGetStats();
3114 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
3115}
3116
Steve Antonffa6ce42018-11-30 09:26:08 -08003117// Test that the new GetStats() returns stats for all outgoing/incoming streams
3118// with the correct track IDs if there are more than one audio and more than one
3119// video senders/receivers.
3120TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
3121 ASSERT_TRUE(CreatePeerConnectionWrappers());
3122 ConnectFakeSignaling();
3123 auto audio_sender_1 = caller()->AddAudioTrack();
3124 auto video_sender_1 = caller()->AddVideoTrack();
3125 auto audio_sender_2 = caller()->AddAudioTrack();
3126 auto video_sender_2 = caller()->AddVideoTrack();
3127 caller()->CreateAndSetAndSignalOffer();
3128 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3129
3130 MediaExpectations media_expectations;
3131 media_expectations.CalleeExpectsSomeAudioAndVideo();
3132 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
3133
3134 std::vector<std::string> track_ids = {
3135 audio_sender_1->track()->id(), video_sender_1->track()->id(),
3136 audio_sender_2->track()->id(), video_sender_2->track()->id()};
3137
3138 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
3139 caller()->NewGetStats();
3140 ASSERT_TRUE(caller_report);
3141 auto outbound_stream_stats =
3142 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
Henrik Boströma0ff50c2020-05-05 15:54:46 +02003143 ASSERT_EQ(outbound_stream_stats.size(), 4u);
Steve Antonffa6ce42018-11-30 09:26:08 -08003144 std::vector<std::string> outbound_track_ids;
3145 for (const auto& stat : outbound_stream_stats) {
3146 ASSERT_TRUE(stat->bytes_sent.is_defined());
3147 EXPECT_LT(0u, *stat->bytes_sent);
Rasmus Brandt2efae772019-06-27 14:29:34 +02003148 if (*stat->kind == "video") {
3149 ASSERT_TRUE(stat->key_frames_encoded.is_defined());
3150 EXPECT_GT(*stat->key_frames_encoded, 0u);
3151 ASSERT_TRUE(stat->frames_encoded.is_defined());
3152 EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
3153 }
Steve Antonffa6ce42018-11-30 09:26:08 -08003154 ASSERT_TRUE(stat->track_id.is_defined());
3155 const auto* track_stat =
3156 caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
3157 ASSERT_TRUE(track_stat);
3158 outbound_track_ids.push_back(*track_stat->track_identifier);
3159 }
3160 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
3161
3162 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
3163 callee()->NewGetStats();
3164 ASSERT_TRUE(callee_report);
3165 auto inbound_stream_stats =
3166 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
3167 ASSERT_EQ(4u, inbound_stream_stats.size());
3168 std::vector<std::string> inbound_track_ids;
3169 for (const auto& stat : inbound_stream_stats) {
3170 ASSERT_TRUE(stat->bytes_received.is_defined());
3171 EXPECT_LT(0u, *stat->bytes_received);
Rasmus Brandt2efae772019-06-27 14:29:34 +02003172 if (*stat->kind == "video") {
3173 ASSERT_TRUE(stat->key_frames_decoded.is_defined());
3174 EXPECT_GT(*stat->key_frames_decoded, 0u);
3175 ASSERT_TRUE(stat->frames_decoded.is_defined());
3176 EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
3177 }
Steve Antonffa6ce42018-11-30 09:26:08 -08003178 ASSERT_TRUE(stat->track_id.is_defined());
3179 const auto* track_stat =
3180 callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
3181 ASSERT_TRUE(track_stat);
3182 inbound_track_ids.push_back(*track_stat->track_identifier);
3183 }
3184 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
3185}
3186
3187// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07003188// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
3189// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003190TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07003191 GetStatsForUnsignaledStreamWithNewStatsApi) {
3192 ASSERT_TRUE(CreatePeerConnectionWrappers());
3193 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003194 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07003195 // Remove SSRCs and MSIDs from the received offer SDP.
3196 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3197 caller()->CreateAndSetAndSignalOffer();
3198 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003199 MediaExpectations media_expectations;
3200 media_expectations.CalleeExpectsSomeAudio(1);
3201 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07003202
3203 // We received a frame, so we should have nonzero "bytes received" stats for
3204 // the unsignaled stream, if stats are working for it.
3205 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
3206 callee()->NewGetStats();
3207 ASSERT_NE(nullptr, report);
3208 auto inbound_stream_stats =
3209 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
3210 ASSERT_EQ(1U, inbound_stream_stats.size());
3211 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
3212 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07003213 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
3214}
3215
Taylor Brandstettera4653442018-06-19 09:44:26 -07003216// Same as above but for the legacy stats implementation.
3217TEST_P(PeerConnectionIntegrationTest,
3218 GetStatsForUnsignaledStreamWithOldStatsApi) {
3219 ASSERT_TRUE(CreatePeerConnectionWrappers());
3220 ConnectFakeSignaling();
3221 caller()->AddAudioTrack();
3222 // Remove SSRCs and MSIDs from the received offer SDP.
3223 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3224 caller()->CreateAndSetAndSignalOffer();
3225 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3226
3227 // Note that, since the old stats implementation associates SSRCs with tracks
3228 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
3229 // associated track ID. So we can't use the track "selector" argument.
3230 //
3231 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
3232 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003233 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07003234 kDefaultTimeout);
3235}
3236
zhihuangf8164932017-05-19 13:09:47 -07003237// Test that we can successfully get the media related stats (audio level
3238// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003239TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07003240 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
3241 ASSERT_TRUE(CreatePeerConnectionWrappers());
3242 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003243 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07003244 // Remove SSRCs and MSIDs from the received offer SDP.
3245 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3246 caller()->CreateAndSetAndSignalOffer();
3247 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003248 MediaExpectations media_expectations;
3249 media_expectations.CalleeExpectsSomeAudio(1);
3250 media_expectations.CalleeExpectsSomeVideo(1);
3251 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07003252
3253 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
3254 callee()->NewGetStats();
3255 ASSERT_NE(nullptr, report);
3256
3257 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3258 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
3259 ASSERT_GE(audio_index, 0);
3260 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07003261}
3262
deadbeef4e2deab2017-09-20 13:56:21 -07003263// Helper for test below.
3264void ModifySsrcs(cricket::SessionDescription* desc) {
3265 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07003266 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08003267 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07003268 for (uint32_t& ssrc : stream.ssrcs) {
3269 ssrc = rtc::CreateRandomId();
3270 }
3271 }
3272 }
3273}
3274
3275// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
3276// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
3277// This should result in two "RTCInboundRTPStreamStats", but only one
3278// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
3279// being reset to 0 once the SSRC change occurs.
3280//
3281// Regression test for this bug:
3282// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
3283//
3284// The bug causes the track stats to only represent one of the two streams:
3285// whichever one has the higher SSRC. So with this bug, there was a 50% chance
3286// that the track stat counters would reset to 0 when the new stream is
3287// received, and a 50% chance that they'll stop updating (while
3288// "concealed_samples" continues increasing, due to silence being generated for
3289// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003290TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08003291 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07003292 ASSERT_TRUE(CreatePeerConnectionWrappers());
3293 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003294 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07003295 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
3296 // that doesn't signal SSRCs (from the callee's perspective).
3297 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3298 caller()->CreateAndSetAndSignalOffer();
3299 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3300 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003301 {
3302 MediaExpectations media_expectations;
3303 media_expectations.CalleeExpectsSomeAudio(50);
3304 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3305 }
deadbeef4e2deab2017-09-20 13:56:21 -07003306 // Some audio frames were received, so we should have nonzero "samples
3307 // received" for the track.
3308 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
3309 callee()->NewGetStats();
3310 ASSERT_NE(nullptr, report);
3311 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3312 ASSERT_EQ(1U, track_stats.size());
3313 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
3314 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
3315 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
3316
3317 // Create a new offer and munge it to cause the caller to use a new SSRC.
3318 caller()->SetGeneratedSdpMunger(ModifySsrcs);
3319 caller()->CreateAndSetAndSignalOffer();
3320 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3321 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
3322 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003323 {
3324 MediaExpectations media_expectations;
3325 media_expectations.CalleeExpectsSomeAudio(25);
3326 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3327 }
deadbeef4e2deab2017-09-20 13:56:21 -07003328
3329 report = callee()->NewGetStats();
3330 ASSERT_NE(nullptr, report);
3331 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3332 ASSERT_EQ(1U, track_stats.size());
3333 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
3334 // The "total samples received" stat should only be greater than it was
3335 // before.
3336 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
3337 // Right now, the new SSRC will cause the counters to reset to 0.
3338 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
3339
3340 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08003341 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07003342 // good sign that we're seeing stats from the old stream that's no longer
3343 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08003344 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07003345 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
3346 EXPECT_LT(*track_stats[0]->concealed_samples,
3347 *track_stats[0]->total_samples_received *
3348 kAcceptableConcealedSamplesPercentage);
3349
3350 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
3351 // sanity check that the SSRC really changed.
3352 // TODO(deadbeef): This isn't working right now, because we're not returning
3353 // *any* stats for the inactive stream. Uncomment when the bug is completely
3354 // fixed.
3355 // auto inbound_stream_stats =
3356 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
3357 // ASSERT_EQ(2U, inbound_stream_stats.size());
3358}
3359
deadbeef1dcb1642017-03-29 21:08:16 -07003360// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003361TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07003362 PeerConnectionFactory::Options dtls_10_options;
3363 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3364 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
3365 dtls_10_options));
3366 ConnectFakeSignaling();
3367 // Do normal offer/answer and wait for some frames to be received in each
3368 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003369 caller()->AddAudioVideoTracks();
3370 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003371 caller()->CreateAndSetAndSignalOffer();
3372 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003373 MediaExpectations media_expectations;
3374 media_expectations.ExpectBidirectionalAudioAndVideo();
3375 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003376}
3377
3378// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003379TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07003380 PeerConnectionFactory::Options dtls_10_options;
3381 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3382 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
3383 dtls_10_options));
3384 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003385 caller()->AddAudioVideoTracks();
3386 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003387 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003388 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07003389 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07003390 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07003391 kDefaultTimeout);
3392 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07003393 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003394 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01003395 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
3396 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
3397 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07003398}
3399
3400// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003401TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07003402 PeerConnectionFactory::Options dtls_12_options;
3403 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3404 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
3405 dtls_12_options));
3406 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003407 caller()->AddAudioVideoTracks();
3408 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003409 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003410 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07003411 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07003412 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07003413 kDefaultTimeout);
3414 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07003415 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003416 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01003417 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
3418 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
3419 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07003420}
3421
3422// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
3423// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003424TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07003425 PeerConnectionFactory::Options caller_options;
3426 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3427 PeerConnectionFactory::Options callee_options;
3428 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3429 ASSERT_TRUE(
3430 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
3431 ConnectFakeSignaling();
3432 // Do normal offer/answer and wait for some frames to be received in each
3433 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003434 caller()->AddAudioVideoTracks();
3435 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003436 caller()->CreateAndSetAndSignalOffer();
3437 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003438 MediaExpectations media_expectations;
3439 media_expectations.ExpectBidirectionalAudioAndVideo();
3440 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003441}
3442
3443// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
3444// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003445TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07003446 PeerConnectionFactory::Options caller_options;
3447 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3448 PeerConnectionFactory::Options callee_options;
3449 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3450 ASSERT_TRUE(
3451 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
3452 ConnectFakeSignaling();
3453 // Do normal offer/answer and wait for some frames to be received in each
3454 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003455 caller()->AddAudioVideoTracks();
3456 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003457 caller()->CreateAndSetAndSignalOffer();
3458 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003459 MediaExpectations media_expectations;
3460 media_expectations.ExpectBidirectionalAudioAndVideo();
3461 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003462}
3463
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003464// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
3465// works as expected; the cipher should only be used if enabled by both sides.
3466TEST_P(PeerConnectionIntegrationTest,
3467 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
3468 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003469 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003470 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003471 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
3472 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003473 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
3474 TestNegotiatedCipherSuite(caller_options, callee_options,
3475 expected_cipher_suite);
3476}
3477
3478TEST_P(PeerConnectionIntegrationTest,
3479 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
3480 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003481 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
3482 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003483 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003484 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003485 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
3486 TestNegotiatedCipherSuite(caller_options, callee_options,
3487 expected_cipher_suite);
3488}
3489
3490TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
3491 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003492 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003493 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003494 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003495 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
3496 TestNegotiatedCipherSuite(caller_options, callee_options,
3497 expected_cipher_suite);
3498}
3499
deadbeef1dcb1642017-03-29 21:08:16 -07003500// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003501TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07003502 bool local_gcm_enabled = false;
3503 bool remote_gcm_enabled = false;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003504 bool aes_ctr_enabled = true;
deadbeef1dcb1642017-03-29 21:08:16 -07003505 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
3506 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003507 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07003508}
3509
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003510// Test that a GCM cipher is used if both ends support it and non-GCM is
3511// disabled.
3512TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07003513 bool local_gcm_enabled = true;
3514 bool remote_gcm_enabled = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003515 bool aes_ctr_enabled = false;
deadbeef1dcb1642017-03-29 21:08:16 -07003516 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
3517 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003518 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07003519}
3520
deadbeef7914b8c2017-04-21 03:23:33 -07003521// Verify that media can be transmitted end-to-end when GCM crypto suites are
3522// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
3523// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
3524// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003525TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07003526 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003527 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003528 gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false;
deadbeef7914b8c2017-04-21 03:23:33 -07003529 ASSERT_TRUE(
3530 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
3531 ConnectFakeSignaling();
3532 // Do normal offer/answer and wait for some frames to be received in each
3533 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003534 caller()->AddAudioVideoTracks();
3535 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003536 caller()->CreateAndSetAndSignalOffer();
3537 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003538 MediaExpectations media_expectations;
3539 media_expectations.ExpectBidirectionalAudioAndVideo();
3540 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003541}
3542
deadbeef1dcb1642017-03-29 21:08:16 -07003543// This test sets up a call between two parties with audio, video and an RTP
3544// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003545TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003546 PeerConnectionInterface::RTCConfiguration rtc_config;
3547 rtc_config.enable_rtp_data_channel = true;
3548 rtc_config.enable_dtls_srtp = false;
3549 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003550 ConnectFakeSignaling();
3551 // Expect that data channel created on caller side will show up for callee as
3552 // well.
3553 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003554 caller()->AddAudioVideoTracks();
3555 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003556 caller()->CreateAndSetAndSignalOffer();
3557 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3558 // Ensure the existence of the RTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003559 MediaExpectations media_expectations;
3560 media_expectations.ExpectBidirectionalAudioAndVideo();
3561 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003562 ASSERT_NE(nullptr, caller()->data_channel());
3563 ASSERT_NE(nullptr, callee()->data_channel());
3564 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3565 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3566
3567 // Ensure data can be sent in both directions.
3568 std::string data = "hello world";
3569 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3570 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3571 kDefaultTimeout);
3572 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3573 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3574 kDefaultTimeout);
3575}
3576
Eldar Rellod9ebe012020-03-18 20:41:45 +02003577TEST_P(PeerConnectionIntegrationTest, RtpDataChannelWorksAfterRollback) {
3578 PeerConnectionInterface::RTCConfiguration rtc_config;
3579 rtc_config.enable_rtp_data_channel = true;
3580 rtc_config.enable_dtls_srtp = false;
3581 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
3582 ConnectFakeSignaling();
3583 auto data_channel = caller()->pc()->CreateDataChannel("label_1", nullptr);
3584 ASSERT_TRUE(data_channel.get() != nullptr);
3585 caller()->CreateAndSetAndSignalOffer();
3586 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3587
3588 caller()->CreateDataChannel("label_2", nullptr);
3589 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
3590 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
3591 caller()->pc()->SetLocalDescription(observer,
3592 caller()->CreateOfferAndWait().release());
3593 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3594 caller()->Rollback();
3595
3596 std::string data = "hello world";
3597 SendRtpDataWithRetries(data_channel, data, 5);
3598 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3599 kDefaultTimeout);
3600}
3601
deadbeef1dcb1642017-03-29 21:08:16 -07003602// Ensure that an RTP data channel is signaled as closed for the caller when
3603// the callee rejects it in a subsequent offer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003604TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003605 RtpDataChannelSignaledClosedInCalleeOffer) {
3606 // Same procedure as above test.
Niels Möllerf06f9232018-08-07 12:32:18 +02003607 PeerConnectionInterface::RTCConfiguration rtc_config;
3608 rtc_config.enable_rtp_data_channel = true;
3609 rtc_config.enable_dtls_srtp = false;
3610 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003611 ConnectFakeSignaling();
3612 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003613 caller()->AddAudioVideoTracks();
3614 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003615 caller()->CreateAndSetAndSignalOffer();
3616 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3617 ASSERT_NE(nullptr, caller()->data_channel());
3618 ASSERT_NE(nullptr, callee()->data_channel());
3619 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3620 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3621
3622 // Close the data channel on the callee, and do an updated offer/answer.
3623 callee()->data_channel()->Close();
3624 callee()->CreateAndSetAndSignalOffer();
3625 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3626 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3627 EXPECT_FALSE(callee()->data_observer()->IsOpen());
3628}
3629
3630// Tests that data is buffered in an RTP data channel until an observer is
3631// registered for it.
3632//
3633// NOTE: RTP data channels can receive data before the underlying
3634// transport has detected that a channel is writable and thus data can be
3635// received before the data channel state changes to open. That is hard to test
3636// but the same buffering is expected to be used in that case.
Yves Gerey100fe632020-01-17 19:15:53 +01003637//
3638// Use fake clock and simulated network delay so that we predictably can wait
3639// until an SCTP message has been delivered without "sleep()"ing.
3640TEST_P(PeerConnectionIntegrationTestWithFakeClock,
deadbeef1dcb1642017-03-29 21:08:16 -07003641 DataBufferedUntilRtpDataChannelObserverRegistered) {
deadbeef1dcb1642017-03-29 21:08:16 -07003642 virtual_socket_server()->set_delay_mean(5); // 5 ms per hop.
3643 virtual_socket_server()->UpdateDelayDistribution();
3644
Niels Möllerf06f9232018-08-07 12:32:18 +02003645 PeerConnectionInterface::RTCConfiguration rtc_config;
3646 rtc_config.enable_rtp_data_channel = true;
3647 rtc_config.enable_dtls_srtp = false;
3648 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003649 ConnectFakeSignaling();
3650 caller()->CreateDataChannel();
3651 caller()->CreateAndSetAndSignalOffer();
3652 ASSERT_TRUE(caller()->data_channel() != nullptr);
3653 ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr,
Yves Gerey100fe632020-01-17 19:15:53 +01003654 kDefaultTimeout, FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003655 ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(),
Yves Gerey100fe632020-01-17 19:15:53 +01003656 kDefaultTimeout, FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003657 ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen,
3658 callee()->data_channel()->state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01003659 FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003660
3661 // Unregister the observer which is normally automatically registered.
3662 callee()->data_channel()->UnregisterObserver();
3663 // Send data and advance fake clock until it should have been received.
3664 std::string data = "hello world";
3665 caller()->data_channel()->Send(DataBuffer(data));
Yves Gerey100fe632020-01-17 19:15:53 +01003666 SIMULATED_WAIT(false, 50, FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003667
3668 // Attach data channel and expect data to be received immediately. Note that
3669 // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any
3670 // further, but data can be received even if the callback is asynchronous.
3671 MockDataChannelObserver new_observer(callee()->data_channel());
3672 EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01003673 FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003674}
3675
3676// This test sets up a call between two parties with audio, video and but only
3677// the caller client supports RTP data channels.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003678TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003679 PeerConnectionInterface::RTCConfiguration rtc_config_1;
3680 rtc_config_1.enable_rtp_data_channel = true;
deadbeef1dcb1642017-03-29 21:08:16 -07003681 // Must disable DTLS to make negotiation succeed.
Niels Möllerf06f9232018-08-07 12:32:18 +02003682 rtc_config_1.enable_dtls_srtp = false;
3683 PeerConnectionInterface::RTCConfiguration rtc_config_2;
3684 rtc_config_2.enable_dtls_srtp = false;
3685 rtc_config_2.enable_dtls_srtp = false;
3686 ASSERT_TRUE(
3687 CreatePeerConnectionWrappersWithConfig(rtc_config_1, rtc_config_2));
deadbeef1dcb1642017-03-29 21:08:16 -07003688 ConnectFakeSignaling();
3689 caller()->CreateDataChannel();
Harald Alvestrandf3736ed2019-04-08 13:09:30 +02003690 ASSERT_TRUE(caller()->data_channel() != nullptr);
Steve Anton15324772018-01-16 10:26:49 -08003691 caller()->AddAudioVideoTracks();
3692 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003693 caller()->CreateAndSetAndSignalOffer();
3694 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3695 // The caller should still have a data channel, but it should be closed, and
3696 // one should ever have been created for the callee.
3697 EXPECT_TRUE(caller()->data_channel() != nullptr);
3698 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3699 EXPECT_EQ(nullptr, callee()->data_channel());
3700}
3701
3702// This test sets up a call between two parties with audio, and video. When
3703// audio and video is setup and flowing, an RTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003704TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003705 PeerConnectionInterface::RTCConfiguration rtc_config;
3706 rtc_config.enable_rtp_data_channel = true;
3707 rtc_config.enable_dtls_srtp = false;
3708 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003709 ConnectFakeSignaling();
3710 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003711 caller()->AddAudioVideoTracks();
3712 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003713 caller()->CreateAndSetAndSignalOffer();
3714 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3715 // Create data channel and do new offer and answer.
3716 caller()->CreateDataChannel();
3717 caller()->CreateAndSetAndSignalOffer();
3718 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3719 ASSERT_NE(nullptr, caller()->data_channel());
3720 ASSERT_NE(nullptr, callee()->data_channel());
3721 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3722 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3723 // Ensure data can be sent in both directions.
3724 std::string data = "hello world";
3725 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3726 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3727 kDefaultTimeout);
3728 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3729 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3730 kDefaultTimeout);
3731}
3732
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01003733#ifdef WEBRTC_HAVE_SCTP
deadbeef1dcb1642017-03-29 21:08:16 -07003734
3735// This test sets up a call between two parties with audio, video and an SCTP
3736// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003737TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003738 ASSERT_TRUE(CreatePeerConnectionWrappers());
3739 ConnectFakeSignaling();
3740 // Expect that data channel created on caller side will show up for callee as
3741 // well.
3742 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003743 caller()->AddAudioVideoTracks();
3744 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003745 caller()->CreateAndSetAndSignalOffer();
3746 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3747 // Ensure the existence of the SCTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003748 MediaExpectations media_expectations;
3749 media_expectations.ExpectBidirectionalAudioAndVideo();
3750 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003751 // Caller data channel should already exist (it created one). Callee data
3752 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3753 ASSERT_NE(nullptr, caller()->data_channel());
3754 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3755 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3756 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3757
3758 // Ensure data can be sent in both directions.
3759 std::string data = "hello world";
3760 caller()->data_channel()->Send(DataBuffer(data));
3761 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3762 kDefaultTimeout);
3763 callee()->data_channel()->Send(DataBuffer(data));
3764 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3765 kDefaultTimeout);
3766}
3767
3768// Ensure that when the callee closes an SCTP data channel, the closing
3769// procedure results in the data channel being closed for the caller as well.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003770TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003771 // Same procedure as above test.
3772 ASSERT_TRUE(CreatePeerConnectionWrappers());
3773 ConnectFakeSignaling();
3774 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003775 caller()->AddAudioVideoTracks();
3776 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003777 caller()->CreateAndSetAndSignalOffer();
3778 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3779 ASSERT_NE(nullptr, caller()->data_channel());
3780 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3781 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3782 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3783
3784 // Close the data channel on the callee side, and wait for it to reach the
3785 // "closed" state on both sides.
3786 callee()->data_channel()->Close();
3787 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3788 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3789}
3790
Seth Hampson2f0d7022018-02-20 11:54:42 -08003791TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
Steve Antonda6c0952017-10-23 11:41:54 -07003792 ASSERT_TRUE(CreatePeerConnectionWrappers());
3793 ConnectFakeSignaling();
3794 webrtc::DataChannelInit init;
3795 init.id = 53;
3796 init.maxRetransmits = 52;
3797 caller()->CreateDataChannel("data-channel", &init);
Steve Anton15324772018-01-16 10:26:49 -08003798 caller()->AddAudioVideoTracks();
3799 callee()->AddAudioVideoTracks();
Steve Antonda6c0952017-10-23 11:41:54 -07003800 caller()->CreateAndSetAndSignalOffer();
3801 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton074dece2017-10-24 13:04:12 -07003802 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3803 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Harald Alvestrand5c4d2ee2019-04-01 12:58:15 +02003804 // Since "negotiated" is false, the "id" parameter should be ignored.
3805 EXPECT_NE(init.id, callee()->data_channel()->id());
Steve Antonda6c0952017-10-23 11:41:54 -07003806 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3807 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3808 EXPECT_FALSE(callee()->data_channel()->negotiated());
3809}
3810
deadbeef1dcb1642017-03-29 21:08:16 -07003811// Test usrsctp's ability to process unordered data stream, where data actually
3812// arrives out of order using simulated delays. Previously there have been some
3813// bugs in this area.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003814TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003815 // Introduce random network delays.
3816 // Otherwise it's not a true "unordered" test.
3817 virtual_socket_server()->set_delay_mean(20);
3818 virtual_socket_server()->set_delay_stddev(5);
3819 virtual_socket_server()->UpdateDelayDistribution();
3820 // Normal procedure, but with unordered data channel config.
3821 ASSERT_TRUE(CreatePeerConnectionWrappers());
3822 ConnectFakeSignaling();
3823 webrtc::DataChannelInit init;
3824 init.ordered = false;
3825 caller()->CreateDataChannel(&init);
3826 caller()->CreateAndSetAndSignalOffer();
3827 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3828 ASSERT_NE(nullptr, caller()->data_channel());
3829 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3830 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3831 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3832
3833 static constexpr int kNumMessages = 100;
3834 // Deliberately chosen to be larger than the MTU so messages get fragmented.
3835 static constexpr size_t kMaxMessageSize = 4096;
3836 // Create and send random messages.
3837 std::vector<std::string> sent_messages;
3838 for (int i = 0; i < kNumMessages; ++i) {
3839 size_t length =
3840 (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand)
3841 std::string message;
3842 ASSERT_TRUE(rtc::CreateRandomString(length, &message));
3843 caller()->data_channel()->Send(DataBuffer(message));
3844 callee()->data_channel()->Send(DataBuffer(message));
3845 sent_messages.push_back(message);
3846 }
3847
3848 // Wait for all messages to be received.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003849 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003850 caller()->data_observer()->received_message_count(),
3851 kDefaultTimeout);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003852 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003853 callee()->data_observer()->received_message_count(),
3854 kDefaultTimeout);
3855
3856 // Sort and compare to make sure none of the messages were corrupted.
3857 std::vector<std::string> caller_received_messages =
3858 caller()->data_observer()->messages();
3859 std::vector<std::string> callee_received_messages =
3860 callee()->data_observer()->messages();
Steve Anton64b626b2019-01-28 17:25:26 -08003861 absl::c_sort(sent_messages);
3862 absl::c_sort(caller_received_messages);
3863 absl::c_sort(callee_received_messages);
deadbeef1dcb1642017-03-29 21:08:16 -07003864 EXPECT_EQ(sent_messages, caller_received_messages);
3865 EXPECT_EQ(sent_messages, callee_received_messages);
3866}
3867
3868// This test sets up a call between two parties with audio, and video. When
3869// audio and video are setup and flowing, an SCTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003870TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07003871 ASSERT_TRUE(CreatePeerConnectionWrappers());
3872 ConnectFakeSignaling();
3873 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003874 caller()->AddAudioVideoTracks();
3875 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003876 caller()->CreateAndSetAndSignalOffer();
3877 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3878 // Create data channel and do new offer and answer.
3879 caller()->CreateDataChannel();
3880 caller()->CreateAndSetAndSignalOffer();
3881 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3882 // Caller data channel should already exist (it created one). Callee data
3883 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3884 ASSERT_NE(nullptr, caller()->data_channel());
3885 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3886 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3887 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3888 // Ensure data can be sent in both directions.
3889 std::string data = "hello world";
3890 caller()->data_channel()->Send(DataBuffer(data));
3891 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3892 kDefaultTimeout);
3893 callee()->data_channel()->Send(DataBuffer(data));
3894 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3895 kDefaultTimeout);
3896}
3897
deadbeef7914b8c2017-04-21 03:23:33 -07003898// Set up a connection initially just using SCTP data channels, later upgrading
3899// to audio/video, ensuring frames are received end-to-end. Effectively the
3900// inverse of the test above.
3901// This was broken in M57; see https://crbug.com/711243
Seth Hampson2f0d7022018-02-20 11:54:42 -08003902TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
deadbeef7914b8c2017-04-21 03:23:33 -07003903 ASSERT_TRUE(CreatePeerConnectionWrappers());
3904 ConnectFakeSignaling();
3905 // Do initial offer/answer with just data channel.
3906 caller()->CreateDataChannel();
3907 caller()->CreateAndSetAndSignalOffer();
3908 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3909 // Wait until data can be sent over the data channel.
3910 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3911 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3912 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3913
3914 // Do subsequent offer/answer with two-way audio and video. Audio and video
3915 // should end up bundled on the DTLS/ICE transport already used for data.
Steve Anton15324772018-01-16 10:26:49 -08003916 caller()->AddAudioVideoTracks();
3917 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003918 caller()->CreateAndSetAndSignalOffer();
3919 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003920 MediaExpectations media_expectations;
3921 media_expectations.ExpectBidirectionalAudioAndVideo();
3922 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003923}
3924
deadbeef8b7e9ad2017-05-25 09:38:55 -07003925static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
Harald Alvestrand5fc28b12019-05-13 13:36:16 +02003926 cricket::SctpDataContentDescription* dcd_offer =
3927 GetFirstSctpDataContentDescription(desc);
Harald Alvestrand17ea0682019-12-13 11:51:04 +01003928 // See https://crbug.com/webrtc/11211 - this function is a no-op
Steve Antonb1c1de12017-12-21 15:14:30 -08003929 ASSERT_TRUE(dcd_offer);
deadbeef8b7e9ad2017-05-25 09:38:55 -07003930 dcd_offer->set_use_sctpmap(false);
3931 dcd_offer->set_protocol("UDP/DTLS/SCTP");
3932}
3933
3934// Test that the data channel works when a spec-compliant SCTP m= section is
3935// offered (using "a=sctp-port" instead of "a=sctpmap", and using
3936// "UDP/DTLS/SCTP" as the protocol).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003937TEST_P(PeerConnectionIntegrationTest,
deadbeef8b7e9ad2017-05-25 09:38:55 -07003938 DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
3939 ASSERT_TRUE(CreatePeerConnectionWrappers());
3940 ConnectFakeSignaling();
3941 caller()->CreateDataChannel();
3942 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
3943 caller()->CreateAndSetAndSignalOffer();
3944 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3945 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3946 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3947 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3948
3949 // Ensure data can be sent in both directions.
3950 std::string data = "hello world";
3951 caller()->data_channel()->Send(DataBuffer(data));
3952 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3953 kDefaultTimeout);
3954 callee()->data_channel()->Send(DataBuffer(data));
3955 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3956 kDefaultTimeout);
3957}
3958
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01003959#endif // WEBRTC_HAVE_SCTP
deadbeef1dcb1642017-03-29 21:08:16 -07003960
3961// Test that the ICE connection and gathering states eventually reach
3962// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08003963TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07003964 ASSERT_TRUE(CreatePeerConnectionWrappers());
3965 ConnectFakeSignaling();
3966 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08003967 caller()->AddAudioVideoTracks();
3968 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003969 caller()->CreateAndSetAndSignalOffer();
3970 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3971 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3972 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
3973 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3974 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
3975 // After the best candidate pair is selected and all candidates are signaled,
3976 // the ICE connection state should reach "complete".
3977 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
3978 // answerer/"callee" by default) only reaches "connected". When this is
3979 // fixed, this test should be updated.
3980 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3981 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00003982 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3983 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07003984}
3985
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003986constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
3987 cricket::PORTALLOCATOR_DISABLE_RELAY |
3988 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003989
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003990// Use a mock resolver to resolve the hostname back to the original IP on both
3991// sides and check that the ICE connection connects.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003992TEST_P(PeerConnectionIntegrationTest,
3993 IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003994 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003995 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003996 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003997 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003998 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
3999 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004000
4001 // This also verifies that the injected AsyncResolverFactory is used by
4002 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004003 EXPECT_CALL(*caller_resolver_factory, Create())
4004 .WillOnce(Return(&caller_async_resolver));
4005 webrtc::PeerConnectionDependencies caller_deps(nullptr);
4006 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
4007
4008 EXPECT_CALL(*callee_resolver_factory, Create())
4009 .WillOnce(Return(&callee_async_resolver));
4010 webrtc::PeerConnectionDependencies callee_deps(nullptr);
4011 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
4012
4013 PeerConnectionInterface::RTCConfiguration config;
4014 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
4015 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
4016
4017 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4018 config, std::move(caller_deps), config, std::move(callee_deps)));
4019
4020 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
4021 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
4022
4023 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07004024 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004025 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07004026 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004027 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004028
4029 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004030
4031 ConnectFakeSignaling();
4032 caller()->AddAudioVideoTracks();
4033 callee()->AddAudioVideoTracks();
4034 caller()->CreateAndSetAndSignalOffer();
4035 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4036 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4037 caller()->ice_connection_state(), kDefaultTimeout);
4038 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4039 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08004040
Ying Wangef3998f2019-12-09 13:06:53 +01004041 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
4042 "WebRTC.PeerConnection.CandidatePairType_UDP",
4043 webrtc::kIceCandidatePairHostNameHostName));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004044}
4045
Steve Antonede9ca52017-10-16 13:04:27 -07004046// Test that firewalling the ICE connection causes the clients to identify the
4047// disconnected state and then removing the firewall causes them to reconnect.
4048class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08004049 : public PeerConnectionIntegrationBaseTest,
4050 public ::testing::WithParamInterface<
4051 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07004052 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08004053 PeerConnectionIntegrationIceStatesTest()
4054 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
4055 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07004056 }
4057
4058 void StartStunServer(const SocketAddress& server_address) {
4059 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01004060 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07004061 }
4062
4063 bool TestIPv6() {
4064 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
4065 }
4066
4067 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004068 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
4069 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07004070 }
4071
4072 std::vector<SocketAddress> CallerAddresses() {
4073 std::vector<SocketAddress> addresses;
4074 addresses.push_back(SocketAddress("1.1.1.1", 0));
4075 if (TestIPv6()) {
4076 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
4077 }
4078 return addresses;
4079 }
4080
4081 std::vector<SocketAddress> CalleeAddresses() {
4082 std::vector<SocketAddress> addresses;
4083 addresses.push_back(SocketAddress("2.2.2.2", 0));
4084 if (TestIPv6()) {
4085 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
4086 }
4087 return addresses;
4088 }
4089
4090 void SetUpNetworkInterfaces() {
4091 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07004092 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
4093 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07004094
4095 // Add network addresses for test.
4096 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07004097 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07004098 }
4099 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07004100 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07004101 }
4102 }
4103
4104 private:
4105 uint32_t port_allocator_flags_;
4106 std::unique_ptr<cricket::TestStunServer> stun_server_;
4107};
4108
Yves Gerey100fe632020-01-17 19:15:53 +01004109// Ensure FakeClockForTest is constructed first (see class for rationale).
4110class PeerConnectionIntegrationIceStatesTestWithFakeClock
4111 : public FakeClockForTest,
4112 public PeerConnectionIntegrationIceStatesTest {};
4113
Steve Antonede9ca52017-10-16 13:04:27 -07004114// Tests that the PeerConnection goes through all the ICE gathering/connection
4115// states over the duration of the call. This includes Disconnected and Failed
4116// states, induced by putting a firewall between the peers and waiting for them
4117// to time out.
Yves Gerey100fe632020-01-17 19:15:53 +01004118TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock, VerifyIceStates) {
Steve Antonede9ca52017-10-16 13:04:27 -07004119 const SocketAddress kStunServerAddress =
4120 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
4121 StartStunServer(kStunServerAddress);
4122
4123 PeerConnectionInterface::RTCConfiguration config;
4124 PeerConnectionInterface::IceServer ice_stun_server;
4125 ice_stun_server.urls.push_back(
4126 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
4127 kStunServerAddress.PortAsString());
4128 config.servers.push_back(ice_stun_server);
4129
4130 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
4131 ConnectFakeSignaling();
4132 SetPortAllocatorFlags();
4133 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08004134 caller()->AddAudioVideoTracks();
4135 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004136
4137 // Initial state before anything happens.
4138 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
4139 caller()->ice_gathering_state());
4140 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
4141 caller()->ice_connection_state());
Jonas Olsson7a6739e2019-01-15 16:31:55 +01004142 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
4143 caller()->standardized_ice_connection_state());
Steve Antonede9ca52017-10-16 13:04:27 -07004144
4145 // Start the call by creating the offer, setting it as the local description,
4146 // then sending it to the peer who will respond with an answer. This happens
4147 // asynchronously so that we can watch the states as it runs in the
4148 // background.
4149 caller()->CreateAndSetAndSignalOffer();
4150
Steve Antona9b67ce2020-01-16 14:00:44 -08004151 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4152 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004153 FakeClock());
Steve Antona9b67ce2020-01-16 14:00:44 -08004154 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4155 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004156 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004157
4158 // Verify that the observer was notified of the intermediate transitions.
4159 EXPECT_THAT(caller()->ice_connection_state_history(),
4160 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
4161 PeerConnectionInterface::kIceConnectionConnected,
4162 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olssonacd8ae72019-02-25 15:26:24 +01004163 EXPECT_THAT(caller()->standardized_ice_connection_state_history(),
4164 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
4165 PeerConnectionInterface::kIceConnectionConnected,
4166 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olsson635474e2018-10-18 15:58:17 +02004167 EXPECT_THAT(
4168 caller()->peer_connection_state_history(),
4169 ElementsAre(PeerConnectionInterface::PeerConnectionState::kConnecting,
Jonas Olsson635474e2018-10-18 15:58:17 +02004170 PeerConnectionInterface::PeerConnectionState::kConnected));
Steve Antonede9ca52017-10-16 13:04:27 -07004171 EXPECT_THAT(caller()->ice_gathering_state_history(),
4172 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
4173 PeerConnectionInterface::kIceGatheringComplete));
4174
4175 // Block connections to/from the caller and wait for ICE to become
4176 // disconnected.
4177 for (const auto& caller_address : CallerAddresses()) {
4178 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4179 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01004180 RTC_LOG(LS_INFO) << "Firewall rules applied";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004181 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
4182 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004183 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004184 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
4185 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004186 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004187
4188 // Let ICE re-establish by removing the firewall rules.
4189 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01004190 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004191 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4192 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004193 FakeClock());
Jonas Olssonacd8ae72019-02-25 15:26:24 +01004194 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004195 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004196 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004197
4198 // According to RFC7675, if there is no response within 30 seconds then the
4199 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08004200 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07004201 constexpr int kConsentTimeout = 30000;
4202 for (const auto& caller_address : CallerAddresses()) {
4203 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4204 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01004205 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004206 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4207 caller()->ice_connection_state(), kConsentTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004208 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004209 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4210 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004211 kConsentTimeout, FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004212}
4213
4214// Tests that if the connection doesn't get set up properly we eventually reach
4215// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01004216TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
4217 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004218 // Block connections to/from the caller and wait for ICE to become
4219 // disconnected.
4220 for (const auto& caller_address : CallerAddresses()) {
4221 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4222 }
4223
4224 ASSERT_TRUE(CreatePeerConnectionWrappers());
4225 ConnectFakeSignaling();
4226 SetPortAllocatorFlags();
4227 SetUpNetworkInterfaces();
4228 caller()->AddAudioVideoTracks();
4229 caller()->CreateAndSetAndSignalOffer();
4230
4231 // According to RFC7675, if there is no response within 30 seconds then the
4232 // peer should consider the other side to have rejected the connection. This
4233 // is signaled by the state transitioning to "failed".
4234 constexpr int kConsentTimeout = 30000;
4235 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4236 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004237 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004238}
4239
4240// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
4241// and that the statistics in the metric observers are updated correctly.
4242TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) {
4243 ASSERT_TRUE(CreatePeerConnectionWrappers());
4244 ConnectFakeSignaling();
4245 SetPortAllocatorFlags();
4246 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08004247 caller()->AddAudioVideoTracks();
4248 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004249 caller()->CreateAndSetAndSignalOffer();
4250
4251 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08004252 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4253 caller()->ice_connection_state(), kDefaultTimeout);
4254 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4255 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07004256
Qingsi Wang7fc821d2018-07-12 12:54:53 -07004257 // TODO(bugs.webrtc.org/9456): Fix it.
4258 const int num_best_ipv4 = webrtc::metrics::NumEvents(
4259 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
4260 const int num_best_ipv6 = webrtc::metrics::NumEvents(
4261 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004262 if (TestIPv6()) {
4263 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
4264 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01004265 EXPECT_METRIC_EQ(0, num_best_ipv4);
4266 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004267 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01004268 EXPECT_METRIC_EQ(1, num_best_ipv4);
4269 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004270 }
4271
Ying Wangef3998f2019-12-09 13:06:53 +01004272 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
4273 "WebRTC.PeerConnection.CandidatePairType_UDP",
4274 webrtc::kIceCandidatePairHostHost));
4275 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
4276 "WebRTC.PeerConnection.CandidatePairType_UDP",
4277 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07004278}
4279
4280constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
4281 cricket::PORTALLOCATOR_DISABLE_STUN |
4282 cricket::PORTALLOCATOR_DISABLE_RELAY;
4283constexpr uint32_t kFlagsIPv6NoStun =
4284 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
4285 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
4286constexpr uint32_t kFlagsIPv4Stun =
4287 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
4288
Mirko Bonadeic84f6612019-01-31 12:20:57 +01004289INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004290 PeerConnectionIntegrationTest,
4291 PeerConnectionIntegrationIceStatesTest,
4292 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4293 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
4294 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
4295 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07004296
Yves Gerey100fe632020-01-17 19:15:53 +01004297INSTANTIATE_TEST_SUITE_P(
4298 PeerConnectionIntegrationTest,
4299 PeerConnectionIntegrationIceStatesTestWithFakeClock,
4300 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4301 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
4302 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
4303 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
4304
deadbeef1dcb1642017-03-29 21:08:16 -07004305// This test sets up a call between two parties with audio and video.
4306// During the call, the caller restarts ICE and the test verifies that
4307// new ICE candidates are generated and audio and video still can flow, and the
4308// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004309TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07004310 ASSERT_TRUE(CreatePeerConnectionWrappers());
4311 ConnectFakeSignaling();
4312 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08004313 caller()->AddAudioVideoTracks();
4314 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004315 caller()->CreateAndSetAndSignalOffer();
4316 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4317 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4318 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00004319 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4320 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07004321
4322 // To verify that the ICE restart actually occurs, get
4323 // ufrag/password/candidates before and after restart.
4324 // Create an SDP string of the first audio candidate for both clients.
4325 const webrtc::IceCandidateCollection* audio_candidates_caller =
4326 caller()->pc()->local_description()->candidates(0);
4327 const webrtc::IceCandidateCollection* audio_candidates_callee =
4328 callee()->pc()->local_description()->candidates(0);
4329 ASSERT_GT(audio_candidates_caller->count(), 0u);
4330 ASSERT_GT(audio_candidates_callee->count(), 0u);
4331 std::string caller_candidate_pre_restart;
4332 ASSERT_TRUE(
4333 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
4334 std::string callee_candidate_pre_restart;
4335 ASSERT_TRUE(
4336 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
4337 const cricket::SessionDescription* desc =
4338 caller()->pc()->local_description()->description();
4339 std::string caller_ufrag_pre_restart =
4340 desc->transport_infos()[0].description.ice_ufrag;
4341 desc = callee()->pc()->local_description()->description();
4342 std::string callee_ufrag_pre_restart =
4343 desc->transport_infos()[0].description.ice_ufrag;
4344
Alex Drake00c7ecf2019-08-06 10:54:47 -07004345 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07004346 // Have the caller initiate an ICE restart.
4347 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
4348 caller()->CreateAndSetAndSignalOffer();
4349 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4350 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4351 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00004352 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07004353 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4354
4355 // Grab the ufrags/candidates again.
4356 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
4357 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
4358 ASSERT_GT(audio_candidates_caller->count(), 0u);
4359 ASSERT_GT(audio_candidates_callee->count(), 0u);
4360 std::string caller_candidate_post_restart;
4361 ASSERT_TRUE(
4362 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
4363 std::string callee_candidate_post_restart;
4364 ASSERT_TRUE(
4365 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
4366 desc = caller()->pc()->local_description()->description();
4367 std::string caller_ufrag_post_restart =
4368 desc->transport_infos()[0].description.ice_ufrag;
4369 desc = callee()->pc()->local_description()->description();
4370 std::string callee_ufrag_post_restart =
4371 desc->transport_infos()[0].description.ice_ufrag;
4372 // Sanity check that an ICE restart was actually negotiated in SDP.
4373 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
4374 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
4375 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
4376 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07004377 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07004378
4379 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004380 MediaExpectations media_expectations;
4381 media_expectations.ExpectBidirectionalAudioAndVideo();
4382 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004383}
4384
4385// Verify that audio/video can be received end-to-end when ICE renomination is
4386// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004387TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07004388 PeerConnectionInterface::RTCConfiguration config;
4389 config.enable_ice_renomination = true;
4390 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
4391 ConnectFakeSignaling();
4392 // Do normal offer/answer and wait for some frames to be received in each
4393 // direction.
Steve Anton15324772018-01-16 10:26:49 -08004394 caller()->AddAudioVideoTracks();
4395 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004396 caller()->CreateAndSetAndSignalOffer();
4397 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4398 // Sanity check that ICE renomination was actually negotiated.
4399 const cricket::SessionDescription* desc =
4400 caller()->pc()->local_description()->description();
4401 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08004402 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07004403 }
4404 desc = callee()->pc()->local_description()->description();
4405 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08004406 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07004407 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08004408 MediaExpectations media_expectations;
4409 media_expectations.ExpectBidirectionalAudioAndVideo();
4410 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004411}
4412
Steve Anton6f25b092017-10-23 09:39:20 -07004413// With a max bundle policy and RTCP muxing, adding a new media description to
4414// the connection should not affect ICE at all because the new media will use
4415// the existing connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004416TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08004417 AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07004418 PeerConnectionInterface::RTCConfiguration config;
4419 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
4420 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
4421 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
4422 config, PeerConnectionInterface::RTCConfiguration()));
4423 ConnectFakeSignaling();
4424
Steve Anton15324772018-01-16 10:26:49 -08004425 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07004426 caller()->CreateAndSetAndSignalOffer();
4427 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07004428 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4429 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07004430
4431 caller()->clear_ice_connection_state_history();
4432
Steve Anton15324772018-01-16 10:26:49 -08004433 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07004434 caller()->CreateAndSetAndSignalOffer();
4435 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4436
4437 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
4438}
4439
deadbeef1dcb1642017-03-29 21:08:16 -07004440// This test sets up a call between two parties with audio and video. It then
4441// renegotiates setting the video m-line to "port 0", then later renegotiates
4442// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004443TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07004444 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
4445 ASSERT_TRUE(CreatePeerConnectionWrappers());
4446 ConnectFakeSignaling();
4447
4448 // Do initial negotiation, only sending media from the caller. Will result in
4449 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08004450 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004451 caller()->CreateAndSetAndSignalOffer();
4452 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4453
4454 // Negotiate again, disabling the video "m=" section (the callee will set the
4455 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08004456 if (sdp_semantics_ == SdpSemantics::kPlanB) {
4457 PeerConnectionInterface::RTCOfferAnswerOptions options;
4458 options.offer_to_receive_video = 0;
4459 callee()->SetOfferAnswerOptions(options);
4460 } else {
4461 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02004462 callee()
4463 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
4464 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08004465 });
4466 }
deadbeef1dcb1642017-03-29 21:08:16 -07004467 caller()->CreateAndSetAndSignalOffer();
4468 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4469 // Sanity check that video "m=" section was actually rejected.
4470 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
4471 callee()->pc()->local_description()->description());
4472 ASSERT_NE(nullptr, answer_video_content);
4473 ASSERT_TRUE(answer_video_content->rejected);
4474
4475 // Enable video and do negotiation again, making sure video is received
4476 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004477 if (sdp_semantics_ == SdpSemantics::kPlanB) {
4478 PeerConnectionInterface::RTCOfferAnswerOptions options;
4479 options.offer_to_receive_video = 1;
4480 callee()->SetOfferAnswerOptions(options);
4481 } else {
4482 // The caller's transceiver is stopped, so we need to add another track.
4483 auto caller_transceiver =
4484 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02004485 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08004486 caller()->AddVideoTrack();
4487 }
4488 callee()->AddVideoTrack();
4489 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07004490 caller()->CreateAndSetAndSignalOffer();
4491 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004492
deadbeef1dcb1642017-03-29 21:08:16 -07004493 // Verify the caller receives frames from the newly added stream, and the
4494 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004495 MediaExpectations media_expectations;
4496 media_expectations.CalleeExpectsSomeAudio();
4497 media_expectations.ExpectBidirectionalVideo();
4498 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004499}
4500
deadbeef1dcb1642017-03-29 21:08:16 -07004501// This tests that if we negotiate after calling CreateSender but before we
4502// have a track, then set a track later, frames from the newly-set track are
4503// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004504TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07004505 MediaFlowsAfterEarlyWarmupWithCreateSender) {
4506 ASSERT_TRUE(CreatePeerConnectionWrappers());
4507 ConnectFakeSignaling();
4508 auto caller_audio_sender =
4509 caller()->pc()->CreateSender("audio", "caller_stream");
4510 auto caller_video_sender =
4511 caller()->pc()->CreateSender("video", "caller_stream");
4512 auto callee_audio_sender =
4513 callee()->pc()->CreateSender("audio", "callee_stream");
4514 auto callee_video_sender =
4515 callee()->pc()->CreateSender("video", "callee_stream");
4516 caller()->CreateAndSetAndSignalOffer();
4517 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4518 // Wait for ICE to complete, without any tracks being set.
4519 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4520 caller()->ice_connection_state(), kMaxWaitForFramesMs);
4521 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4522 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4523 // Now set the tracks, and expect frames to immediately start flowing.
4524 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
4525 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
4526 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
4527 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08004528 MediaExpectations media_expectations;
4529 media_expectations.ExpectBidirectionalAudioAndVideo();
4530 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4531}
4532
4533// This tests that if we negotiate after calling AddTransceiver but before we
4534// have a track, then set a track later, frames from the newly-set tracks are
4535// received end-to-end.
4536TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
4537 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
4538 ASSERT_TRUE(CreatePeerConnectionWrappers());
4539 ConnectFakeSignaling();
4540 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
4541 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
4542 auto caller_audio_sender = audio_result.MoveValue()->sender();
4543 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
4544 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
4545 auto caller_video_sender = video_result.MoveValue()->sender();
4546 callee()->SetRemoteOfferHandler([this] {
4547 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02004548 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004549 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02004550 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004551 RtpTransceiverDirection::kSendRecv);
4552 });
4553 caller()->CreateAndSetAndSignalOffer();
4554 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4555 // Wait for ICE to complete, without any tracks being set.
4556 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4557 caller()->ice_connection_state(), kMaxWaitForFramesMs);
4558 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4559 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4560 // Now set the tracks, and expect frames to immediately start flowing.
4561 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
4562 auto callee_video_sender = callee()->pc()->GetSenders()[1];
4563 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
4564 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
4565 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
4566 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
4567 MediaExpectations media_expectations;
4568 media_expectations.ExpectBidirectionalAudioAndVideo();
4569 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004570}
4571
4572// This test verifies that a remote video track can be added via AddStream,
4573// and sent end-to-end. For this particular test, it's simply echoed back
4574// from the caller to the callee, rather than being forwarded to a third
4575// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004576TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07004577 ASSERT_TRUE(CreatePeerConnectionWrappers());
4578 ConnectFakeSignaling();
4579 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08004580 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07004581 caller()->CreateAndSetAndSignalOffer();
4582 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02004583 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07004584
4585 // Echo the stream back, and do a new offer/anwer (initiated by callee this
4586 // time).
4587 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
4588 callee()->CreateAndSetAndSignalOffer();
4589 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4590
Seth Hampson2f0d7022018-02-20 11:54:42 -08004591 MediaExpectations media_expectations;
4592 media_expectations.ExpectBidirectionalVideo();
4593 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004594}
4595
4596// Test that we achieve the expected end-to-end connection time, using a
4597// fake clock and simulated latency on the media and signaling paths.
4598// We use a TURN<->TURN connection because this is usually the quickest to
4599// set up initially, especially when we're confident the connection will work
4600// and can start sending media before we get a STUN response.
4601//
4602// With various optimizations enabled, here are the network delays we expect to
4603// be on the critical path:
4604// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
4605// signaling answer (with DTLS fingerprint).
4606// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
4607// using TURN<->TURN pair, and DTLS exchange is 4 packets,
4608// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01004609TEST_P(PeerConnectionIntegrationTestWithFakeClock,
4610 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07004611 static constexpr int media_hop_delay_ms = 50;
4612 static constexpr int signaling_trip_delay_ms = 500;
4613 // For explanation of these values, see comment above.
4614 static constexpr int required_media_hops = 9;
4615 static constexpr int required_signaling_trips = 2;
4616 // For internal delays (such as posting an event asychronously).
4617 static constexpr int allowed_internal_delay_ms = 20;
4618 static constexpr int total_connection_time_ms =
4619 media_hop_delay_ms * required_media_hops +
4620 signaling_trip_delay_ms * required_signaling_trips +
4621 allowed_internal_delay_ms;
4622
4623 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4624 3478};
4625 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4626 0};
4627 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4628 3478};
4629 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4630 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004631 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
4632 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004633
Seth Hampsonaed71642018-06-11 07:41:32 -07004634 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
4635 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07004636 // Bypass permission check on received packets so media can be sent before
4637 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07004638 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
4639 turn_server_1->set_enable_permission_checks(false);
4640 });
4641 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
4642 turn_server_2->set_enable_permission_checks(false);
4643 });
deadbeef1dcb1642017-03-29 21:08:16 -07004644
4645 PeerConnectionInterface::RTCConfiguration client_1_config;
4646 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4647 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4648 ice_server_1.username = "test";
4649 ice_server_1.password = "test";
4650 client_1_config.servers.push_back(ice_server_1);
4651 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4652 client_1_config.presume_writable_when_fully_relayed = true;
4653
4654 PeerConnectionInterface::RTCConfiguration client_2_config;
4655 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4656 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4657 ice_server_2.username = "test";
4658 ice_server_2.password = "test";
4659 client_2_config.servers.push_back(ice_server_2);
4660 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4661 client_2_config.presume_writable_when_fully_relayed = true;
4662
4663 ASSERT_TRUE(
4664 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4665 // Set up the simulated delays.
4666 SetSignalingDelayMs(signaling_trip_delay_ms);
4667 ConnectFakeSignaling();
4668 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
4669 virtual_socket_server()->UpdateDelayDistribution();
4670
4671 // Set "offer to receive audio/video" without adding any tracks, so we just
4672 // set up ICE/DTLS with no media.
4673 PeerConnectionInterface::RTCOfferAnswerOptions options;
4674 options.offer_to_receive_audio = 1;
4675 options.offer_to_receive_video = 1;
4676 caller()->SetOfferAnswerOptions(options);
4677 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07004678 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01004679 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07004680 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
4681 // If this is not done a DCHECK can be hit in ports.cc, because a large
4682 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07004683 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07004684}
4685
Jonas Orelandbdcee282017-10-10 14:01:40 +02004686// Verify that a TurnCustomizer passed in through RTCConfiguration
4687// is actually used by the underlying TURN candidate pair.
4688// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004689TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02004690 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4691 3478};
4692 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4693 0};
4694 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4695 3478};
4696 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4697 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004698 CreateTurnServer(turn_server_1_internal_address,
4699 turn_server_1_external_address);
4700 CreateTurnServer(turn_server_2_internal_address,
4701 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004702
4703 PeerConnectionInterface::RTCConfiguration client_1_config;
4704 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4705 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4706 ice_server_1.username = "test";
4707 ice_server_1.password = "test";
4708 client_1_config.servers.push_back(ice_server_1);
4709 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004710 auto* customizer1 = CreateTurnCustomizer();
4711 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004712
4713 PeerConnectionInterface::RTCConfiguration client_2_config;
4714 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4715 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4716 ice_server_2.username = "test";
4717 ice_server_2.password = "test";
4718 client_2_config.servers.push_back(ice_server_2);
4719 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004720 auto* customizer2 = CreateTurnCustomizer();
4721 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004722
4723 ASSERT_TRUE(
4724 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4725 ConnectFakeSignaling();
4726
4727 // Set "offer to receive audio/video" without adding any tracks, so we just
4728 // set up ICE/DTLS with no media.
4729 PeerConnectionInterface::RTCOfferAnswerOptions options;
4730 options.offer_to_receive_audio = 1;
4731 options.offer_to_receive_video = 1;
4732 caller()->SetOfferAnswerOptions(options);
4733 caller()->CreateAndSetAndSignalOffer();
4734 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4735
Seth Hampsonaed71642018-06-11 07:41:32 -07004736 ExpectTurnCustomizerCountersIncremented(customizer1);
4737 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004738}
4739
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004740// Verifies that you can use TCP instead of UDP to connect to a TURN server and
4741// send media between the caller and the callee.
4742TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
4743 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4744 3478};
4745 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4746
4747 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07004748 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4749 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004750
4751 webrtc::PeerConnectionInterface::IceServer ice_server;
4752 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
4753 ice_server.username = "test";
4754 ice_server.password = "test";
4755
4756 PeerConnectionInterface::RTCConfiguration client_1_config;
4757 client_1_config.servers.push_back(ice_server);
4758 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4759
4760 PeerConnectionInterface::RTCConfiguration client_2_config;
4761 client_2_config.servers.push_back(ice_server);
4762 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4763
4764 ASSERT_TRUE(
4765 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4766
4767 // Do normal offer/answer and wait for ICE to complete.
4768 ConnectFakeSignaling();
4769 caller()->AddAudioVideoTracks();
4770 callee()->AddAudioVideoTracks();
4771 caller()->CreateAndSetAndSignalOffer();
4772 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4773 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4774 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4775
4776 MediaExpectations media_expectations;
4777 media_expectations.ExpectBidirectionalAudioAndVideo();
4778 EXPECT_TRUE(ExpectNewFrames(media_expectations));
4779}
4780
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004781// Verify that a SSLCertificateVerifier passed in through
4782// PeerConnectionDependencies is actually used by the underlying SSL
4783// implementation to determine whether a certificate presented by the TURN
4784// server is accepted by the client. Note that openssladapter_unittest.cc
4785// contains more detailed, lower-level tests.
4786TEST_P(PeerConnectionIntegrationTest,
4787 SSLCertificateVerifierUsedForTurnConnections) {
4788 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4789 3478};
4790 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4791
4792 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4793 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004794 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4795 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004796
4797 webrtc::PeerConnectionInterface::IceServer ice_server;
4798 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4799 ice_server.username = "test";
4800 ice_server.password = "test";
4801
4802 PeerConnectionInterface::RTCConfiguration client_1_config;
4803 client_1_config.servers.push_back(ice_server);
4804 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4805
4806 PeerConnectionInterface::RTCConfiguration client_2_config;
4807 client_2_config.servers.push_back(ice_server);
4808 // Setting the type to kRelay forces the connection to go through a TURN
4809 // server.
4810 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4811
4812 // Get a copy to the pointer so we can verify calls later.
4813 rtc::TestCertificateVerifier* client_1_cert_verifier =
4814 new rtc::TestCertificateVerifier();
4815 client_1_cert_verifier->verify_certificate_ = true;
4816 rtc::TestCertificateVerifier* client_2_cert_verifier =
4817 new rtc::TestCertificateVerifier();
4818 client_2_cert_verifier->verify_certificate_ = true;
4819
4820 // Create the dependencies with the test certificate verifier.
4821 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4822 client_1_deps.tls_cert_verifier =
4823 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4824 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4825 client_2_deps.tls_cert_verifier =
4826 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4827
4828 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4829 client_1_config, std::move(client_1_deps), client_2_config,
4830 std::move(client_2_deps)));
4831 ConnectFakeSignaling();
4832
4833 // Set "offer to receive audio/video" without adding any tracks, so we just
4834 // set up ICE/DTLS with no media.
4835 PeerConnectionInterface::RTCOfferAnswerOptions options;
4836 options.offer_to_receive_audio = 1;
4837 options.offer_to_receive_video = 1;
4838 caller()->SetOfferAnswerOptions(options);
4839 caller()->CreateAndSetAndSignalOffer();
4840 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4841
4842 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4843 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004844}
4845
4846TEST_P(PeerConnectionIntegrationTest,
4847 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
4848 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4849 3478};
4850 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4851
4852 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4853 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004854 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4855 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004856
4857 webrtc::PeerConnectionInterface::IceServer ice_server;
4858 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4859 ice_server.username = "test";
4860 ice_server.password = "test";
4861
4862 PeerConnectionInterface::RTCConfiguration client_1_config;
4863 client_1_config.servers.push_back(ice_server);
4864 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4865
4866 PeerConnectionInterface::RTCConfiguration client_2_config;
4867 client_2_config.servers.push_back(ice_server);
4868 // Setting the type to kRelay forces the connection to go through a TURN
4869 // server.
4870 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4871
4872 // Get a copy to the pointer so we can verify calls later.
4873 rtc::TestCertificateVerifier* client_1_cert_verifier =
4874 new rtc::TestCertificateVerifier();
4875 client_1_cert_verifier->verify_certificate_ = false;
4876 rtc::TestCertificateVerifier* client_2_cert_verifier =
4877 new rtc::TestCertificateVerifier();
4878 client_2_cert_verifier->verify_certificate_ = false;
4879
4880 // Create the dependencies with the test certificate verifier.
4881 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4882 client_1_deps.tls_cert_verifier =
4883 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4884 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4885 client_2_deps.tls_cert_verifier =
4886 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4887
4888 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4889 client_1_config, std::move(client_1_deps), client_2_config,
4890 std::move(client_2_deps)));
4891 ConnectFakeSignaling();
4892
4893 // Set "offer to receive audio/video" without adding any tracks, so we just
4894 // set up ICE/DTLS with no media.
4895 PeerConnectionInterface::RTCOfferAnswerOptions options;
4896 options.offer_to_receive_audio = 1;
4897 options.offer_to_receive_video = 1;
4898 caller()->SetOfferAnswerOptions(options);
4899 caller()->CreateAndSetAndSignalOffer();
4900 bool wait_res = true;
4901 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
4902 // properly, should be able to just wait for a state of "failed" instead of
4903 // waiting a fixed 10 seconds.
4904 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
4905 ASSERT_FALSE(wait_res);
4906
4907 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4908 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004909}
4910
Qingsi Wang25ec8882019-11-15 12:33:05 -08004911// Test that the injected ICE transport factory is used to create ICE transports
4912// for WebRTC connections.
4913TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
4914 PeerConnectionInterface::RTCConfiguration default_config;
4915 PeerConnectionDependencies dependencies(nullptr);
4916 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
4917 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
4918 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02004919 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
4920 std::move(dependencies), nullptr,
4921 /*reset_encoder_factory=*/false,
4922 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08004923 ASSERT_TRUE(wrapper);
4924 wrapper->CreateDataChannel();
4925 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
4926 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
4927 wrapper->pc()->SetLocalDescription(observer,
4928 wrapper->CreateOfferAndWait().release());
4929}
4930
deadbeefc964d0b2017-04-03 10:03:35 -07004931// Test that audio and video flow end-to-end when codec names don't use the
4932// expected casing, given that they're supposed to be case insensitive. To test
4933// this, all but one codec is removed from each media description, and its
4934// casing is changed.
4935//
4936// In the past, this has regressed and caused crashes/black video, due to the
4937// fact that code at some layers was doing case-insensitive comparisons and
4938// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004939TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07004940 ASSERT_TRUE(CreatePeerConnectionWrappers());
4941 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004942 caller()->AddAudioVideoTracks();
4943 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07004944
4945 // Remove all but one audio/video codec (opus and VP8), and change the
4946 // casing of the caller's generated offer.
4947 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
4948 cricket::AudioContentDescription* audio =
4949 GetFirstAudioContentDescription(description);
4950 ASSERT_NE(nullptr, audio);
4951 auto audio_codecs = audio->codecs();
4952 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
4953 [](const cricket::AudioCodec& codec) {
4954 return codec.name != "opus";
4955 }),
4956 audio_codecs.end());
4957 ASSERT_EQ(1u, audio_codecs.size());
4958 audio_codecs[0].name = "OpUs";
4959 audio->set_codecs(audio_codecs);
4960
4961 cricket::VideoContentDescription* video =
4962 GetFirstVideoContentDescription(description);
4963 ASSERT_NE(nullptr, video);
4964 auto video_codecs = video->codecs();
4965 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
4966 [](const cricket::VideoCodec& codec) {
4967 return codec.name != "VP8";
4968 }),
4969 video_codecs.end());
4970 ASSERT_EQ(1u, video_codecs.size());
4971 video_codecs[0].name = "vP8";
4972 video->set_codecs(video_codecs);
4973 });
4974
4975 caller()->CreateAndSetAndSignalOffer();
4976 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4977
4978 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004979 MediaExpectations media_expectations;
4980 media_expectations.ExpectBidirectionalAudioAndVideo();
4981 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07004982}
4983
Jonas Oreland49ac5952018-09-26 16:04:32 +02004984TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07004985 ASSERT_TRUE(CreatePeerConnectionWrappers());
4986 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004987 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07004988 caller()->CreateAndSetAndSignalOffer();
4989 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07004990 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004991 MediaExpectations media_expectations;
4992 media_expectations.CalleeExpectsSomeAudio(1);
4993 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02004994 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07004995 auto receiver = callee()->pc()->GetReceivers()[0];
4996 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02004997 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07004998 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4999 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02005000 sources[0].source_id());
5001 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
5002}
5003
5004TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
5005 ASSERT_TRUE(CreatePeerConnectionWrappers());
5006 ConnectFakeSignaling();
5007 caller()->AddVideoTrack();
5008 caller()->CreateAndSetAndSignalOffer();
5009 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5010 // Wait for one video frame to be received by the callee.
5011 MediaExpectations media_expectations;
5012 media_expectations.CalleeExpectsSomeVideo(1);
5013 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5014 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
5015 auto receiver = callee()->pc()->GetReceivers()[0];
5016 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
5017 auto sources = receiver->GetSources();
5018 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02005019 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02005020 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
5021 sources[0].source_id());
5022 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07005023}
5024
deadbeef2f425aa2017-04-14 10:41:32 -07005025// Test that if a track is removed and added again with a different stream ID,
5026// the new stream ID is successfully communicated in SDP and media continues to
5027// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005028// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
5029// it will not reuse a transceiver that has already been sending. After creating
5030// a new transceiver it tries to create an offer with two senders of the same
5031// track ids and it fails.
5032TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07005033 ASSERT_TRUE(CreatePeerConnectionWrappers());
5034 ConnectFakeSignaling();
5035
deadbeef2f425aa2017-04-14 10:41:32 -07005036 // Add track using stream 1, do offer/answer.
5037 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
5038 caller()->CreateLocalAudioTrack();
5039 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07005040 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07005041 caller()->CreateAndSetAndSignalOffer();
5042 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005043 {
5044 MediaExpectations media_expectations;
5045 media_expectations.CalleeExpectsSomeAudio(1);
5046 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5047 }
deadbeef2f425aa2017-04-14 10:41:32 -07005048 // Remove the sender, and create a new one with the new stream.
5049 caller()->pc()->RemoveTrack(sender);
Steve Antond78323f2018-07-11 11:13:44 -07005050 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07005051 caller()->CreateAndSetAndSignalOffer();
5052 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5053 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005054 {
5055 MediaExpectations media_expectations;
5056 media_expectations.CalleeExpectsSomeAudio();
5057 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5058 }
deadbeef2f425aa2017-04-14 10:41:32 -07005059}
5060
Seth Hampson2f0d7022018-02-20 11:54:42 -08005061TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02005062 ASSERT_TRUE(CreatePeerConnectionWrappers());
5063 ConnectFakeSignaling();
5064
Mirko Bonadei317a1f02019-09-17 17:06:18 +02005065 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02005066 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
5067 ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true));
Elad Alon99c3fe52017-10-13 16:29:40 +02005068 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01005069 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
5070 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02005071
Steve Anton15324772018-01-16 10:26:49 -08005072 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02005073 caller()->CreateAndSetAndSignalOffer();
5074 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5075}
5076
Steve Antonede9ca52017-10-16 13:04:27 -07005077// Test that if candidates are only signaled by applying full session
5078// descriptions (instead of using AddIceCandidate), the peers can connect to
5079// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005080TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07005081 ASSERT_TRUE(CreatePeerConnectionWrappers());
5082 // Each side will signal the session descriptions but not candidates.
5083 ConnectFakeSignalingForSdpOnly();
5084
5085 // Add audio video track and exchange the initial offer/answer with media
5086 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08005087 caller()->AddAudioVideoTracks();
5088 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07005089 caller()->CreateAndSetAndSignalOffer();
5090
5091 // Wait for all candidates to be gathered on both the caller and callee.
5092 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
5093 caller()->ice_gathering_state(), kDefaultTimeout);
5094 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
5095 callee()->ice_gathering_state(), kDefaultTimeout);
5096
5097 // The candidates will now be included in the session description, so
5098 // signaling them will start the ICE connection.
5099 caller()->CreateAndSetAndSignalOffer();
5100 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5101
5102 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005103 MediaExpectations media_expectations;
5104 media_expectations.ExpectBidirectionalAudioAndVideo();
5105 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07005106}
5107
henrika5f6bf242017-11-01 11:06:56 +01005108// Test that SetAudioPlayout can be used to disable audio playout from the
5109// start, then later enable it. This may be useful, for example, if the caller
5110// needs to play a local ringtone until some event occurs, after which it
5111// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005112TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01005113 ASSERT_TRUE(CreatePeerConnectionWrappers());
5114 ConnectFakeSignaling();
5115
5116 // Set up audio-only call where audio playout is disabled on caller's side.
5117 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08005118 caller()->AddAudioTrack();
5119 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01005120 caller()->CreateAndSetAndSignalOffer();
5121 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5122
5123 // Pump messages for a second.
5124 WAIT(false, 1000);
5125 // Since audio playout is disabled, the caller shouldn't have received
5126 // anything (at the playout level, at least).
5127 EXPECT_EQ(0, caller()->audio_frames_received());
5128 // As a sanity check, make sure the callee (for which playout isn't disabled)
5129 // did still see frames on its audio level.
5130 ASSERT_GT(callee()->audio_frames_received(), 0);
5131
5132 // Enable playout again, and ensure audio starts flowing.
5133 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005134 MediaExpectations media_expectations;
5135 media_expectations.ExpectBidirectionalAudio();
5136 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01005137}
5138
5139double GetAudioEnergyStat(PeerConnectionWrapper* pc) {
5140 auto report = pc->NewGetStats();
5141 auto track_stats_list =
5142 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
5143 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
5144 for (const auto* track_stats : track_stats_list) {
5145 if (track_stats->remote_source.is_defined() &&
5146 *track_stats->remote_source) {
5147 remote_track_stats = track_stats;
5148 break;
5149 }
5150 }
5151
5152 if (!remote_track_stats->total_audio_energy.is_defined()) {
5153 return 0.0;
5154 }
5155 return *remote_track_stats->total_audio_energy;
5156}
5157
5158// Test that if audio playout is disabled via the SetAudioPlayout() method, then
5159// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005160TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01005161 DisableAudioPlayoutStillGeneratesAudioStats) {
5162 ASSERT_TRUE(CreatePeerConnectionWrappers());
5163 ConnectFakeSignaling();
5164
5165 // Set up audio-only call where playout is disabled but audio-processing is
5166 // still active.
Steve Anton15324772018-01-16 10:26:49 -08005167 caller()->AddAudioTrack();
5168 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01005169 caller()->pc()->SetAudioPlayout(false);
5170
5171 caller()->CreateAndSetAndSignalOffer();
5172 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5173
5174 // Wait for the callee to receive audio stats.
5175 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
5176}
5177
henrika4f167df2017-11-01 14:45:55 +01005178// Test that SetAudioRecording can be used to disable audio recording from the
5179// start, then later enable it. This may be useful, for example, if the caller
5180// wants to ensure that no audio resources are active before a certain state
5181// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005182TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01005183 ASSERT_TRUE(CreatePeerConnectionWrappers());
5184 ConnectFakeSignaling();
5185
5186 // Set up audio-only call where audio recording is disabled on caller's side.
5187 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08005188 caller()->AddAudioTrack();
5189 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01005190 caller()->CreateAndSetAndSignalOffer();
5191 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5192
5193 // Pump messages for a second.
5194 WAIT(false, 1000);
5195 // Since caller has disabled audio recording, the callee shouldn't have
5196 // received anything.
5197 EXPECT_EQ(0, callee()->audio_frames_received());
5198 // As a sanity check, make sure the caller did still see frames on its
5199 // audio level since audio recording is enabled on the calle side.
5200 ASSERT_GT(caller()->audio_frames_received(), 0);
5201
5202 // Enable audio recording again, and ensure audio starts flowing.
5203 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005204 MediaExpectations media_expectations;
5205 media_expectations.ExpectBidirectionalAudio();
5206 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01005207}
5208
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005209// Test that after closing PeerConnections, they stop sending any packets (ICE,
5210// DTLS, RTP...).
Seth Hampson2f0d7022018-02-20 11:54:42 -08005211TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005212 // Set up audio/video/data, wait for some frames to be received.
5213 ASSERT_TRUE(CreatePeerConnectionWrappers());
5214 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08005215 caller()->AddAudioVideoTracks();
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005216#ifdef WEBRTC_HAVE_SCTP
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005217 caller()->CreateDataChannel();
5218#endif
5219 caller()->CreateAndSetAndSignalOffer();
5220 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005221 MediaExpectations media_expectations;
5222 media_expectations.CalleeExpectsSomeAudioAndVideo();
5223 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005224 // Close PeerConnections.
Steve Antond91969e2019-05-30 12:27:03 -07005225 ClosePeerConnections();
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005226 // Pump messages for a second, and ensure no new packets end up sent.
5227 uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
5228 WAIT(false, 1000);
5229 uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
5230 EXPECT_EQ(sent_packets_a, sent_packets_b);
5231}
5232
Steve Anton7eca0932018-03-30 15:18:41 -07005233// Test that transport stats are generated by the RTCStatsCollector for a
5234// connection that only involves data channels. This is a regression test for
5235// crbug.com/826972.
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005236#ifdef WEBRTC_HAVE_SCTP
Steve Anton7eca0932018-03-30 15:18:41 -07005237TEST_P(PeerConnectionIntegrationTest,
5238 TransportStatsReportedForDataChannelOnlyConnection) {
5239 ASSERT_TRUE(CreatePeerConnectionWrappers());
5240 ConnectFakeSignaling();
5241 caller()->CreateDataChannel();
5242
5243 caller()->CreateAndSetAndSignalOffer();
5244 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5245 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
5246
5247 auto caller_report = caller()->NewGetStats();
5248 EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
5249 auto callee_report = callee()->NewGetStats();
5250 EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
5251}
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005252#endif // WEBRTC_HAVE_SCTP
Steve Anton7eca0932018-03-30 15:18:41 -07005253
Qingsi Wang7685e862018-06-11 20:15:46 -07005254TEST_P(PeerConnectionIntegrationTest,
5255 IceEventsGeneratedAndLoggedInRtcEventLog) {
5256 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
5257 ConnectFakeSignaling();
5258 PeerConnectionInterface::RTCOfferAnswerOptions options;
5259 options.offer_to_receive_audio = 1;
5260 caller()->SetOfferAnswerOptions(options);
5261 caller()->CreateAndSetAndSignalOffer();
5262 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
5263 ASSERT_NE(nullptr, caller()->event_log_factory());
5264 ASSERT_NE(nullptr, callee()->event_log_factory());
5265 webrtc::FakeRtcEventLog* caller_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01005266 caller()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07005267 webrtc::FakeRtcEventLog* callee_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01005268 callee()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07005269 ASSERT_NE(nullptr, caller_event_log);
5270 ASSERT_NE(nullptr, callee_event_log);
5271 int caller_ice_config_count = caller_event_log->GetEventCount(
5272 webrtc::RtcEvent::Type::IceCandidatePairConfig);
5273 int caller_ice_event_count = caller_event_log->GetEventCount(
5274 webrtc::RtcEvent::Type::IceCandidatePairEvent);
5275 int callee_ice_config_count = callee_event_log->GetEventCount(
5276 webrtc::RtcEvent::Type::IceCandidatePairConfig);
5277 int callee_ice_event_count = callee_event_log->GetEventCount(
5278 webrtc::RtcEvent::Type::IceCandidatePairEvent);
5279 EXPECT_LT(0, caller_ice_config_count);
5280 EXPECT_LT(0, caller_ice_event_count);
5281 EXPECT_LT(0, callee_ice_config_count);
5282 EXPECT_LT(0, callee_ice_event_count);
5283}
5284
Qingsi Wangc129c352019-04-18 10:41:58 -07005285TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07005286 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
5287 3478};
5288 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
5289
5290 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
5291
5292 webrtc::PeerConnectionInterface::IceServer ice_server;
5293 ice_server.urls.push_back("turn:88.88.88.0:3478");
5294 ice_server.username = "test";
5295 ice_server.password = "test";
5296
5297 PeerConnectionInterface::RTCConfiguration caller_config;
5298 caller_config.servers.push_back(ice_server);
5299 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5300 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005301 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07005302
5303 PeerConnectionInterface::RTCConfiguration callee_config;
5304 callee_config.servers.push_back(ice_server);
5305 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5306 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005307 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07005308
5309 ASSERT_TRUE(
5310 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5311
5312 // Do normal offer/answer and wait for ICE to complete.
5313 ConnectFakeSignaling();
5314 caller()->AddAudioVideoTracks();
5315 callee()->AddAudioVideoTracks();
5316 caller()->CreateAndSetAndSignalOffer();
5317 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5318 // Since we are doing continual gathering, the ICE transport does not reach
5319 // kIceGatheringComplete (see
5320 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
5321 // kIceConnectionComplete.
5322 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
5323 caller()->ice_connection_state(), kDefaultTimeout);
5324 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
5325 callee()->ice_connection_state(), kDefaultTimeout);
5326 // Note that we cannot use the metric
5327 // |WebRTC.PeerConnection.CandidatePairType_UDP| in this test since this
5328 // metric is only populated when we reach kIceConnectionComplete in the
5329 // current implementation.
5330 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
5331 caller()->last_candidate_gathered().type());
5332 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
5333 callee()->last_candidate_gathered().type());
5334
5335 // Loosen the caller's candidate filter.
5336 caller_config = caller()->pc()->GetConfiguration();
5337 caller_config.type = webrtc::PeerConnectionInterface::kAll;
5338 caller()->pc()->SetConfiguration(caller_config);
5339 // We should have gathered a new host candidate.
5340 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
5341 caller()->last_candidate_gathered().type(), kDefaultTimeout);
5342
5343 // Loosen the callee's candidate filter.
5344 callee_config = callee()->pc()->GetConfiguration();
5345 callee_config.type = webrtc::PeerConnectionInterface::kAll;
5346 callee()->pc()->SetConfiguration(callee_config);
5347 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
5348 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02005349
5350 // Create an offer and verify that it does not contain an ICE restart (i.e new
5351 // ice credentials).
5352 std::string caller_ufrag_pre_offer = caller()
5353 ->pc()
5354 ->local_description()
5355 ->description()
5356 ->transport_infos()[0]
5357 .description.ice_ufrag;
5358 caller()->CreateAndSetAndSignalOffer();
5359 std::string caller_ufrag_post_offer = caller()
5360 ->pc()
5361 ->local_description()
5362 ->description()
5363 ->transport_infos()[0]
5364 .description.ice_ufrag;
5365 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07005366}
5367
Eldar Relloda13ea22019-06-01 12:23:43 +03005368TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03005369 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
5370 3478};
5371 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
5372
5373 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
5374
5375 webrtc::PeerConnectionInterface::IceServer ice_server;
5376 ice_server.urls.push_back("turn:88.88.88.0:3478");
5377 ice_server.username = "test";
5378 ice_server.password = "123";
5379
5380 PeerConnectionInterface::RTCConfiguration caller_config;
5381 caller_config.servers.push_back(ice_server);
5382 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5383 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5384
5385 PeerConnectionInterface::RTCConfiguration callee_config;
5386 callee_config.servers.push_back(ice_server);
5387 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5388 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5389
5390 ASSERT_TRUE(
5391 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5392
5393 // Do normal offer/answer and wait for ICE to complete.
5394 ConnectFakeSignaling();
5395 caller()->AddAudioVideoTracks();
5396 callee()->AddAudioVideoTracks();
5397 caller()->CreateAndSetAndSignalOffer();
5398 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5399 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
5400 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
5401 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02005402 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03005403}
5404
Eldar Rellofa8019c2020-05-14 11:59:33 +03005405TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
5406 webrtc::PeerConnectionInterface::IceServer ice_server;
5407 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
5408 ice_server.username = "test";
5409 ice_server.password = "test";
5410
5411 PeerConnectionInterface::RTCConfiguration caller_config;
5412 caller_config.servers.push_back(ice_server);
5413 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5414 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5415
5416 PeerConnectionInterface::RTCConfiguration callee_config;
5417 callee_config.servers.push_back(ice_server);
5418 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5419 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5420
5421 ASSERT_TRUE(
5422 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5423
5424 // Do normal offer/answer and wait for ICE to complete.
5425 ConnectFakeSignaling();
5426 caller()->AddAudioVideoTracks();
5427 callee()->AddAudioVideoTracks();
5428 caller()->CreateAndSetAndSignalOffer();
5429 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5430 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
5431 EXPECT_EQ(caller()->error_event().address, "");
5432}
5433
Eldar Rello5ab79e62019-10-09 18:29:44 +03005434TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5435 AudioKeepsFlowingAfterImplicitRollback) {
5436 PeerConnectionInterface::RTCConfiguration config;
5437 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5438 config.enable_implicit_rollback = true;
5439 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5440 ConnectFakeSignaling();
5441 caller()->AddAudioTrack();
5442 callee()->AddAudioTrack();
5443 caller()->CreateAndSetAndSignalOffer();
5444 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5445 MediaExpectations media_expectations;
5446 media_expectations.ExpectBidirectionalAudio();
5447 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5448 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
5449 caller()->AddVideoTrack();
5450 callee()->AddVideoTrack();
5451 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
5452 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5453 callee()->pc()->SetLocalDescription(observer,
5454 callee()->CreateOfferAndWait().release());
5455 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
5456 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
5457 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5458 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5459}
5460
5461TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5462 ImplicitRollbackVisitsStableState) {
5463 RTCConfiguration config;
5464 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5465 config.enable_implicit_rollback = true;
5466
5467 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5468
5469 rtc::scoped_refptr<MockSetSessionDescriptionObserver> sld_observer(
5470 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5471 callee()->pc()->SetLocalDescription(sld_observer,
5472 callee()->CreateOfferAndWait().release());
5473 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
5474 EXPECT_EQ(sld_observer->error(), "");
5475
5476 rtc::scoped_refptr<MockSetSessionDescriptionObserver> srd_observer(
5477 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5478 callee()->pc()->SetRemoteDescription(
5479 srd_observer, caller()->CreateOfferAndWait().release());
5480 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
5481 EXPECT_EQ(srd_observer->error(), "");
5482
5483 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
5484 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
5485 PeerConnectionInterface::kStable,
5486 PeerConnectionInterface::kHaveRemoteOffer));
5487}
5488
Eldar Rellobd9c33a2020-10-01 17:52:45 +03005489TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5490 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
5491 ASSERT_TRUE(CreatePeerConnectionWrappers());
5492 ConnectFakeSignaling();
5493 caller()->AddVideoTrack();
5494 callee()->AddVideoTrack();
5495 auto munger = [](cricket::SessionDescription* desc) {
5496 cricket::VideoContentDescription* video =
5497 GetFirstVideoContentDescription(desc);
5498 auto codecs = video->codecs();
5499 for (auto&& codec : codecs) {
5500 if (codec.name == "H264") {
5501 std::string value;
5502 // The parameter is not supposed to be present in SDP by default.
5503 EXPECT_FALSE(
5504 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
5505 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
5506 std::string(""));
5507 }
5508 }
5509 video->set_codecs(codecs);
5510 };
5511 // Munge local offer for SLD.
5512 caller()->SetGeneratedSdpMunger(munger);
5513 // Munge remote answer for SRD.
5514 caller()->SetReceivedSdpMunger(munger);
5515 caller()->CreateAndSetAndSignalOffer();
5516 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5517 // Observe that after munging the parameter is present in generated SDP.
5518 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
5519 cricket::VideoContentDescription* video =
5520 GetFirstVideoContentDescription(desc);
5521 for (auto&& codec : video->codecs()) {
5522 if (codec.name == "H264") {
5523 std::string value;
5524 EXPECT_TRUE(
5525 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
5526 }
5527 }
5528 });
5529 caller()->CreateOfferAndWait();
5530}
5531
Harald Alvestrand1a9be302020-12-11 14:53:59 +00005532TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00005533 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00005534 PeerConnectionInterface::RTCConfiguration config;
5535 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5536 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5537 ConnectFakeSignaling();
5538 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
5539
5540 caller()->CreateAndSetAndSignalOffer();
5541 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5542 int current_size = caller()->pc()->GetTransceivers().size();
5543 // Add more tracks until we get close to having issues.
5544 // Issues have been seen at:
5545 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005546 // - 16 tracks on android_arm_dbg (flaky)
5547 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00005548 // Double the number of tracks
5549 for (int i = 0; i < current_size; i++) {
5550 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
5551 }
5552 current_size = caller()->pc()->GetTransceivers().size();
5553 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
5554 auto start_time_ms = rtc::TimeMillis();
5555 caller()->CreateAndSetAndSignalOffer();
5556 // We want to stop when the time exceeds one second.
5557 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5558 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
5559 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
5560 ASSERT_GT(1000, elapsed_time_ms)
5561 << "Audio transceivers: Negotiation took too long after "
5562 << current_size << " tracks added";
5563 }
5564}
5565
5566TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5567 RenegotiateManyVideoTransceivers) {
5568 PeerConnectionInterface::RTCConfiguration config;
5569 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5570 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5571 ConnectFakeSignaling();
5572 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
5573
5574 caller()->CreateAndSetAndSignalOffer();
5575 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5576 int current_size = caller()->pc()->GetTransceivers().size();
5577 // Add more tracks until we get close to having issues.
5578 // Issues have been seen at:
5579 // - 96 on a Linux workstation
5580 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
5581 // - 32 on android_arm64_rel and linux_dbg bots
5582 while (current_size < 16) {
5583 // Double the number of tracks
5584 for (int i = 0; i < current_size; i++) {
5585 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
5586 }
5587 current_size = caller()->pc()->GetTransceivers().size();
5588 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
5589 auto start_time_ms = rtc::TimeMillis();
5590 caller()->CreateAndSetAndSignalOffer();
5591 // We want to stop when the time exceeds one second.
5592 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5593 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
5594 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
5595 ASSERT_GT(1000, elapsed_time_ms)
5596 << "Video transceivers: Negotiation took too long after "
5597 << current_size << " tracks added";
5598 }
5599}
5600
Harald Alvestrand94324f22021-01-13 12:31:53 +00005601TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5602 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
5603 PeerConnectionInterface::RTCConfiguration config;
5604 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5605 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5606 ConnectFakeSignaling();
5607 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005608 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00005609 caller()->CreateAndSetAndSignalOffer();
5610 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5611 // Wait until we can see the audio flowing.
5612 MediaExpectations media_expectations;
5613 media_expectations.CalleeExpectsSomeAudio();
5614 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5615
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005616 // Get the baseline numbers for audio_packets and audio_delay
5617 // in both directions.
5618 caller()->StartWatchingDelayStats();
5619 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00005620
5621 int current_size = caller()->pc()->GetTransceivers().size();
5622 // Add more tracks until we get close to having issues.
5623 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005624 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00005625 // Double the number of tracks
5626 for (int i = 0; i < current_size; i++) {
5627 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
5628 }
5629 current_size = caller()->pc()->GetTransceivers().size();
5630 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
5631 auto start_time_ms = rtc::TimeMillis();
5632 caller()->CreateAndSetAndSignalOffer();
5633 // We want to stop when the time exceeds one second.
5634 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5635 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
5636 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
5637 // This is a guard against the test using excessive amounts of time.
5638 ASSERT_GT(5000, elapsed_time_ms)
5639 << "Video transceivers: Negotiation took too long after "
5640 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005641 caller()->UpdateDelayStats("caller reception", current_size);
5642 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00005643 }
5644}
5645
Mirko Bonadeic84f6612019-01-31 12:20:57 +01005646INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
5647 PeerConnectionIntegrationTest,
5648 Values(SdpSemantics::kPlanB,
5649 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-17 17:41:02 -08005650
Yves Gerey100fe632020-01-17 19:15:53 +01005651INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
5652 PeerConnectionIntegrationTestWithFakeClock,
5653 Values(SdpSemantics::kPlanB,
5654 SdpSemantics::kUnifiedPlan));
5655
Steve Anton74255ff2018-01-24 18:32:57 -08005656// Tests that verify interoperability between Plan B and Unified Plan
5657// PeerConnections.
5658class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08005659 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08005660 public ::testing::WithParamInterface<
5661 std::tuple<SdpSemantics, SdpSemantics>> {
5662 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08005663 // Setting the SdpSemantics for the base test to kDefault does not matter
5664 // because we specify not to use the test semantics when creating
5665 // PeerConnectionWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08005666 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07005667 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08005668 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08005669 callee_semantics_(std::get<1>(GetParam())) {}
5670
5671 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07005672 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
5673 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08005674 }
5675
5676 const SdpSemantics caller_semantics_;
5677 const SdpSemantics callee_semantics_;
5678};
5679
5680TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
5681 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5682 ConnectFakeSignaling();
5683
5684 caller()->CreateAndSetAndSignalOffer();
5685 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5686}
5687
5688TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
5689 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5690 ConnectFakeSignaling();
5691 auto audio_sender = caller()->AddAudioTrack();
5692
5693 caller()->CreateAndSetAndSignalOffer();
5694 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5695
5696 // Verify that one audio receiver has been created on the remote and that it
5697 // has the same track ID as the sending track.
5698 auto receivers = callee()->pc()->GetReceivers();
5699 ASSERT_EQ(1u, receivers.size());
5700 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
5701 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
5702
Seth Hampson2f0d7022018-02-20 11:54:42 -08005703 MediaExpectations media_expectations;
5704 media_expectations.CalleeExpectsSomeAudio();
5705 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005706}
5707
5708TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
5709 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5710 ConnectFakeSignaling();
5711 auto video_sender = caller()->AddVideoTrack();
5712 auto audio_sender = caller()->AddAudioTrack();
5713
5714 caller()->CreateAndSetAndSignalOffer();
5715 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5716
5717 // Verify that one audio and one video receiver have been created on the
5718 // remote and that they have the same track IDs as the sending tracks.
5719 auto audio_receivers =
5720 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
5721 ASSERT_EQ(1u, audio_receivers.size());
5722 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
5723 auto video_receivers =
5724 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
5725 ASSERT_EQ(1u, video_receivers.size());
5726 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
5727
Seth Hampson2f0d7022018-02-20 11:54:42 -08005728 MediaExpectations media_expectations;
5729 media_expectations.CalleeExpectsSomeAudioAndVideo();
5730 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005731}
5732
5733TEST_P(PeerConnectionIntegrationInteropTest,
5734 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
5735 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5736 ConnectFakeSignaling();
5737 caller()->AddAudioVideoTracks();
5738 callee()->AddAudioVideoTracks();
5739
5740 caller()->CreateAndSetAndSignalOffer();
5741 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5742
Seth Hampson2f0d7022018-02-20 11:54:42 -08005743 MediaExpectations media_expectations;
5744 media_expectations.ExpectBidirectionalAudioAndVideo();
5745 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005746}
5747
5748TEST_P(PeerConnectionIntegrationInteropTest,
5749 ReverseRolesOneAudioLocalToOneVideoRemote) {
5750 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5751 ConnectFakeSignaling();
5752 caller()->AddAudioTrack();
5753 callee()->AddVideoTrack();
5754
5755 caller()->CreateAndSetAndSignalOffer();
5756 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5757
5758 // Verify that only the audio track has been negotiated.
5759 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
5760 // Might also check that the callee's NegotiationNeeded flag is set.
5761
5762 // Reverse roles.
5763 callee()->CreateAndSetAndSignalOffer();
5764 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5765
Seth Hampson2f0d7022018-02-20 11:54:42 -08005766 MediaExpectations media_expectations;
5767 media_expectations.CallerExpectsSomeVideo();
5768 media_expectations.CalleeExpectsSomeAudio();
5769 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005770}
5771
Mirko Bonadeic84f6612019-01-31 12:20:57 +01005772INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07005773 PeerConnectionIntegrationTest,
5774 PeerConnectionIntegrationInteropTest,
5775 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
5776 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
5777
5778// Test that if the Unified Plan side offers two video tracks then the Plan B
5779// side will only see the first one and ignore the second.
5780TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07005781 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
5782 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08005783 ConnectFakeSignaling();
5784 auto first_sender = caller()->AddVideoTrack();
5785 caller()->AddVideoTrack();
5786
5787 caller()->CreateAndSetAndSignalOffer();
5788 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5789
5790 // Verify that there is only one receiver and it corresponds to the first
5791 // added track.
5792 auto receivers = callee()->pc()->GetReceivers();
5793 ASSERT_EQ(1u, receivers.size());
5794 EXPECT_TRUE(receivers[0]->track()->enabled());
5795 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
5796
Seth Hampson2f0d7022018-02-20 11:54:42 -08005797 MediaExpectations media_expectations;
5798 media_expectations.CalleeExpectsSomeVideo();
5799 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005800}
5801
Steve Anton2bed3972019-01-04 17:04:30 -08005802// Test that if the initial offer tagged BUNDLE section is rejected due to its
5803// associated RtpTransceiver being stopped and another transceiver is added,
5804// then renegotiation causes the callee to receive the new video track without
5805// error.
5806// This is a regression test for bugs.webrtc.org/9954
5807TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5808 ReOfferWithStoppedBundleTaggedTransceiver) {
5809 RTCConfiguration config;
5810 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
5811 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5812 ConnectFakeSignaling();
5813 auto audio_transceiver_or_error =
5814 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5815 ASSERT_TRUE(audio_transceiver_or_error.ok());
5816 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5817
5818 caller()->CreateAndSetAndSignalOffer();
5819 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5820 {
5821 MediaExpectations media_expectations;
5822 media_expectations.CalleeExpectsSomeAudio();
5823 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5824 }
5825
Harald Alvestrand6060df52020-08-11 09:54:02 +02005826 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08005827 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
5828
5829 caller()->CreateAndSetAndSignalOffer();
5830 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5831 {
5832 MediaExpectations media_expectations;
5833 media_expectations.CalleeExpectsSomeVideo();
5834 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5835 }
5836}
5837
Harald Alvestrandbedb6052020-08-20 14:50:10 +02005838TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5839 StopTransceiverRemovesDtlsTransports) {
5840 RTCConfiguration config;
5841 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5842 ConnectFakeSignaling();
5843 auto audio_transceiver_or_error =
5844 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5845 ASSERT_TRUE(audio_transceiver_or_error.ok());
5846 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5847
5848 caller()->CreateAndSetAndSignalOffer();
5849 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5850
5851 audio_transceiver->StopStandard();
5852 caller()->CreateAndSetAndSignalOffer();
5853 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5854 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
5855 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
5856 caller()->pc()->ice_gathering_state());
5857 EXPECT_THAT(caller()->ice_gathering_state_history(),
5858 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
5859 PeerConnectionInterface::kIceGatheringComplete,
5860 PeerConnectionInterface::kIceGatheringNew));
5861}
5862
Harald Alvestrand1ee33252020-09-24 13:31:15 +00005863TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00005864 StopTransceiverStopsAndRemovesTransceivers) {
5865 RTCConfiguration config;
5866 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5867 ConnectFakeSignaling();
5868 auto audio_transceiver_or_error =
5869 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5870 ASSERT_TRUE(audio_transceiver_or_error.ok());
5871 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
5872
5873 caller()->CreateAndSetAndSignalOffer();
5874 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5875 caller_transceiver->StopStandard();
5876
5877 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
5878 caller()->CreateAndSetAndSignalOffer();
5879 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5880 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
5881 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
5882 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
5883 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
5884 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
5885 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
5886 EXPECT_TRUE(caller_transceiver->stopped());
5887 EXPECT_TRUE(callee_transceiver->stopped());
5888}
5889
5890TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00005891 StopTransceiverEndsIncomingAudioTrack) {
5892 RTCConfiguration config;
5893 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5894 ConnectFakeSignaling();
5895 auto audio_transceiver_or_error =
5896 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5897 ASSERT_TRUE(audio_transceiver_or_error.ok());
5898 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5899
5900 caller()->CreateAndSetAndSignalOffer();
5901 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5902 auto caller_track = audio_transceiver->receiver()->track();
5903 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
5904 audio_transceiver->StopStandard();
5905 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
5906 caller_track->state());
5907 caller()->CreateAndSetAndSignalOffer();
5908 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5909 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
5910 callee_track->state());
5911}
5912
5913TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5914 StopTransceiverEndsIncomingVideoTrack) {
5915 RTCConfiguration config;
5916 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5917 ConnectFakeSignaling();
5918 auto audio_transceiver_or_error =
5919 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
5920 ASSERT_TRUE(audio_transceiver_or_error.ok());
5921 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5922
5923 caller()->CreateAndSetAndSignalOffer();
5924 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5925 auto caller_track = audio_transceiver->receiver()->track();
5926 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
5927 audio_transceiver->StopStandard();
5928 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
5929 caller_track->state());
5930 caller()->CreateAndSetAndSignalOffer();
5931 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5932 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
5933 callee_track->state());
5934}
5935
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005936#ifdef WEBRTC_HAVE_SCTP
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02005937
5938TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5939 EndToEndCallWithBundledSctpDataChannel) {
5940 ASSERT_TRUE(CreatePeerConnectionWrappers());
5941 ConnectFakeSignaling();
5942 caller()->CreateDataChannel();
5943 caller()->AddAudioVideoTracks();
5944 callee()->AddAudioVideoTracks();
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02005945 caller()->CreateAndSetAndSignalOffer();
5946 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Harald Alvestrand17ea0682019-12-13 11:51:04 +01005947 ASSERT_EQ_WAIT(SctpTransportState::kConnected,
5948 caller()->pc()->GetSctpTransport()->Information().state(),
5949 kDefaultTimeout);
5950 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
5951 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5952}
5953
5954TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5955 EndToEndCallWithDataChannelOnlyConnects) {
5956 ASSERT_TRUE(CreatePeerConnectionWrappers());
5957 ConnectFakeSignaling();
5958 caller()->CreateDataChannel();
5959 caller()->CreateAndSetAndSignalOffer();
5960 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5961 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
5962 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5963 ASSERT_TRUE(caller()->data_observer()->IsOpen());
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02005964}
5965
Harald Alvestrand2697ac12019-12-16 10:37:04 +01005966TEST_F(PeerConnectionIntegrationTestUnifiedPlan, DataChannelClosesWhenClosed) {
5967 ASSERT_TRUE(CreatePeerConnectionWrappers());
5968 ConnectFakeSignaling();
5969 caller()->CreateDataChannel();
5970 caller()->CreateAndSetAndSignalOffer();
5971 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5972 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
5973 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5974 caller()->data_channel()->Close();
5975 ASSERT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
5976}
5977
5978TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5979 DataChannelClosesWhenClosedReverse) {
5980 ASSERT_TRUE(CreatePeerConnectionWrappers());
5981 ConnectFakeSignaling();
5982 caller()->CreateDataChannel();
5983 caller()->CreateAndSetAndSignalOffer();
5984 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5985 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
5986 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5987 callee()->data_channel()->Close();
5988 ASSERT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
5989}
5990
5991TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5992 DataChannelClosesWhenPeerConnectionClosed) {
5993 ASSERT_TRUE(CreatePeerConnectionWrappers());
5994 ConnectFakeSignaling();
5995 caller()->CreateDataChannel();
5996 caller()->CreateAndSetAndSignalOffer();
5997 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5998 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
5999 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
6000 caller()->pc()->Close();
6001 ASSERT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
6002}
6003
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01006004#endif // WEBRTC_HAVE_SCTP
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02006005
deadbeef1dcb1642017-03-29 21:08:16 -07006006} // namespace
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01006007} // namespace webrtc
deadbeef1dcb1642017-03-29 21:08:16 -07006008
6009#endif // if !defined(THREAD_SANITIZER)