blob: 00055527d1e0a69e2e42271935fa807ff82f8cea [file] [log] [blame]
deadbeef1dcb1642017-03-29 21:08:16 -07001/*
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11// Disable for TSan v2, see
12// https://code.google.com/p/webrtc/issues/detail?id=1205 for details.
13#if !defined(THREAD_SANITIZER)
14
15#include <stdio.h>
16
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -070017#include <algorithm>
deadbeef1dcb1642017-03-29 21:08:16 -070018#include <functional>
19#include <list>
20#include <map>
21#include <memory>
22#include <utility>
23#include <vector>
24
Steve Anton64b626b2019-01-28 17:25:26 -080025#include "absl/algorithm/container.h"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "api/media_stream_interface.h"
27#include "api/peer_connection_interface.h"
28#include "api/peer_connection_proxy.h"
Danil Chapovalov9da25bd2019-06-20 10:19:42 +020029#include "api/rtc_event_log/rtc_event_log_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080030#include "api/rtp_receiver_interface.h"
Danil Chapovalov9da25bd2019-06-20 10:19:42 +020031#include "api/task_queue/default_task_queue_factory.h"
Erik Språngceb44952020-09-22 11:36:35 +020032#include "api/transport/field_trial_based_config.h"
Steve Anton10542f22019-01-11 09:11:00 -080033#include "api/uma_metrics.h"
Anders Carlsson67537952018-05-03 11:28:29 +020034#include "api/video_codecs/sdp_video_format.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070035#include "call/call.h"
36#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080037#include "media/engine/fake_webrtc_video_engine.h"
38#include "media/engine/webrtc_media_engine.h"
Danil Chapovalov9da25bd2019-06-20 10:19:42 +020039#include "media/engine/webrtc_media_engine_defaults.h"
Per Åhgrencc73ed32020-04-26 23:56:17 +020040#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
Qingsi Wang25ec8882019-11-15 12:33:05 -080041#include "p2p/base/fake_ice_transport.h"
Steve Anton10542f22019-01-11 09:11:00 -080042#include "p2p/base/mock_async_resolver.h"
43#include "p2p/base/p2p_constants.h"
44#include "p2p/base/port_interface.h"
45#include "p2p/base/test_stun_server.h"
46#include "p2p/base/test_turn_customizer.h"
47#include "p2p/base/test_turn_server.h"
48#include "p2p/client/basic_port_allocator.h"
49#include "pc/dtmf_sender.h"
50#include "pc/local_audio_source.h"
51#include "pc/media_session.h"
52#include "pc/peer_connection.h"
53#include "pc/peer_connection_factory.h"
54#include "pc/rtp_media_utils.h"
55#include "pc/session_description.h"
56#include "pc/test/fake_audio_capture_module.h"
57#include "pc/test/fake_periodic_video_track_source.h"
58#include "pc/test/fake_rtc_certificate_generator.h"
59#include "pc/test/fake_video_track_renderer.h"
60#include "pc/test/mock_peer_connection_observers.h"
Jonas Olssonb75d9e92019-02-22 10:33:29 +010061#include "rtc_base/fake_clock.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070062#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080063#include "rtc_base/fake_network.h"
64#include "rtc_base/firewall_socket_server.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020065#include "rtc_base/gunit.h"
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +020066#include "rtc_base/numerics/safe_conversions.h"
Steve Anton10542f22019-01-11 09:11:00 -080067#include "rtc_base/test_certificate_verifier.h"
68#include "rtc_base/time_utils.h"
69#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020070#include "system_wrappers/include/metrics.h"
Qingsi Wangc129c352019-04-18 10:41:58 -070071#include "test/field_trial.h"
Elad Alon99c3fe52017-10-13 16:29:40 +020072#include "test/gmock.h"
deadbeef1dcb1642017-03-29 21:08:16 -070073
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010074namespace webrtc {
75namespace {
76
77using ::cricket::ContentInfo;
78using ::cricket::StreamParams;
79using ::rtc::SocketAddress;
80using ::testing::_;
Seth Hampson2f0d7022018-02-20 11:54:42 -080081using ::testing::Combine;
Steve Anton64b626b2019-01-28 17:25:26 -080082using ::testing::Contains;
Mirko Bonadeie46f5db2019-03-26 20:14:46 +010083using ::testing::DoAll;
Steve Antonede9ca52017-10-16 13:04:27 -070084using ::testing::ElementsAre;
Qingsi Wang1dac6d82018-12-12 15:28:47 -080085using ::testing::NiceMock;
Steve Anton64b626b2019-01-28 17:25:26 -080086using ::testing::Return;
Zach Stein6fcdc2f2018-08-23 16:25:55 -070087using ::testing::SetArgPointee;
Steve Antonffa6ce42018-11-30 09:26:08 -080088using ::testing::UnorderedElementsAreArray;
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010089using ::testing::Values;
Steve Anton74255ff2018-01-24 18:32:57 -080090using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
deadbeef1dcb1642017-03-29 21:08:16 -070091
92static const int kDefaultTimeout = 10000;
93static const int kMaxWaitForStatsMs = 3000;
94static const int kMaxWaitForActivationMs = 5000;
95static const int kMaxWaitForFramesMs = 10000;
96// Default number of audio/video frames to wait for before considering a test
97// successful.
98static const int kDefaultExpectedAudioFrameCount = 3;
99static const int kDefaultExpectedVideoFrameCount = 3;
100
deadbeef1dcb1642017-03-29 21:08:16 -0700101static const char kDataChannelLabel[] = "data_channel";
102
103// SRTP cipher name negotiated by the tests. This must be updated if the
104// default changes.
Taylor Brandstetterfd350d72018-04-03 16:29:26 -0700105static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_80;
deadbeef1dcb1642017-03-29 21:08:16 -0700106static const int kDefaultSrtpCryptoSuiteGcm = rtc::SRTP_AEAD_AES_256_GCM;
107
Steve Antonede9ca52017-10-16 13:04:27 -0700108static const SocketAddress kDefaultLocalAddress("192.168.1.1", 0);
109
deadbeef1dcb1642017-03-29 21:08:16 -0700110// Helper function for constructing offer/answer options to initiate an ICE
111// restart.
112PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions() {
113 PeerConnectionInterface::RTCOfferAnswerOptions options;
114 options.ice_restart = true;
115 return options;
116}
117
deadbeefd8ad7882017-04-18 16:01:17 -0700118// Remove all stream information (SSRCs, track IDs, etc.) and "msid-semantic"
119// attribute from received SDP, simulating a legacy endpoint.
120void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) {
121 for (ContentInfo& content : desc->contents()) {
Steve Antonb1c1de12017-12-21 15:14:30 -0800122 content.media_description()->mutable_streams().clear();
deadbeefd8ad7882017-04-18 16:01:17 -0700123 }
124 desc->set_msid_supported(false);
Henrik Boström5b147782018-12-04 11:25:05 +0100125 desc->set_msid_signaling(0);
deadbeefd8ad7882017-04-18 16:01:17 -0700126}
127
Seth Hampson5897a6e2018-04-03 11:16:33 -0700128// Removes all stream information besides the stream ids, simulating an
129// endpoint that only signals a=msid lines to convey stream_ids.
130void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) {
131 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700132 std::string track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700133 std::vector<std::string> stream_ids;
134 if (!content.media_description()->streams().empty()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700135 const StreamParams& first_stream =
136 content.media_description()->streams()[0];
137 track_id = first_stream.id;
138 stream_ids = first_stream.stream_ids();
Seth Hampson5897a6e2018-04-03 11:16:33 -0700139 }
140 content.media_description()->mutable_streams().clear();
Steve Antondf527fd2018-04-27 15:52:03 -0700141 StreamParams new_stream;
142 new_stream.id = track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700143 new_stream.set_stream_ids(stream_ids);
144 content.media_description()->AddStream(new_stream);
145 }
146}
147
zhihuangf8164932017-05-19 13:09:47 -0700148int FindFirstMediaStatsIndexByKind(
149 const std::string& kind,
150 const std::vector<const webrtc::RTCMediaStreamTrackStats*>&
151 media_stats_vec) {
152 for (size_t i = 0; i < media_stats_vec.size(); i++) {
153 if (media_stats_vec[i]->kind.ValueToString() == kind) {
154 return i;
155 }
156 }
157 return -1;
158}
159
deadbeef1dcb1642017-03-29 21:08:16 -0700160class SignalingMessageReceiver {
161 public:
Steve Antona3a92c22017-12-07 10:27:41 -0800162 virtual void ReceiveSdpMessage(SdpType type, const std::string& msg) = 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700163 virtual void ReceiveIceMessage(const std::string& sdp_mid,
164 int sdp_mline_index,
165 const std::string& msg) = 0;
166
167 protected:
168 SignalingMessageReceiver() {}
169 virtual ~SignalingMessageReceiver() {}
170};
171
172class MockRtpReceiverObserver : public webrtc::RtpReceiverObserverInterface {
173 public:
174 explicit MockRtpReceiverObserver(cricket::MediaType media_type)
175 : expected_media_type_(media_type) {}
176
177 void OnFirstPacketReceived(cricket::MediaType media_type) override {
178 ASSERT_EQ(expected_media_type_, media_type);
179 first_packet_received_ = true;
180 }
181
182 bool first_packet_received() const { return first_packet_received_; }
183
184 virtual ~MockRtpReceiverObserver() {}
185
186 private:
187 bool first_packet_received_ = false;
188 cricket::MediaType expected_media_type_;
189};
190
191// Helper class that wraps a peer connection, observes it, and can accept
192// signaling messages from another wrapper.
193//
194// Uses a fake network, fake A/V capture, and optionally fake
195// encoders/decoders, though they aren't used by default since they don't
196// advertise support of any codecs.
Steve Anton94286cb2017-09-26 16:20:19 -0700197// TODO(steveanton): See how this could become a subclass of
Seth Hampson2f0d7022018-02-20 11:54:42 -0800198// PeerConnectionWrapper defined in peerconnectionwrapper.h.
deadbeef1dcb1642017-03-29 21:08:16 -0700199class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
Steve Anton15324772018-01-16 10:26:49 -0800200 public SignalingMessageReceiver {
deadbeef1dcb1642017-03-29 21:08:16 -0700201 public:
202 // Different factory methods for convenience.
203 // TODO(deadbeef): Could use the pattern of:
204 //
205 // PeerConnectionWrapper =
206 // WrapperBuilder.WithConfig(...).WithOptions(...).build();
207 //
208 // To reduce some code duplication.
209 static PeerConnectionWrapper* CreateWithDtlsIdentityStore(
210 const std::string& debug_name,
211 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
212 rtc::Thread* network_thread,
213 rtc::Thread* worker_thread) {
214 PeerConnectionWrapper* client(new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700215 webrtc::PeerConnectionDependencies dependencies(nullptr);
216 dependencies.cert_generator = std::move(cert_generator);
Niels Möllerf06f9232018-08-07 12:32:18 +0200217 if (!client->Init(nullptr, nullptr, std::move(dependencies), network_thread,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800218 worker_thread, nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +0200219 /*reset_encoder_factory=*/false,
220 /*reset_decoder_factory=*/false)) {
deadbeef1dcb1642017-03-29 21:08:16 -0700221 delete client;
222 return nullptr;
223 }
224 return client;
225 }
226
deadbeef2f425aa2017-04-14 10:41:32 -0700227 webrtc::PeerConnectionFactoryInterface* pc_factory() const {
228 return peer_connection_factory_.get();
229 }
230
deadbeef1dcb1642017-03-29 21:08:16 -0700231 webrtc::PeerConnectionInterface* pc() const { return peer_connection_.get(); }
232
233 // If a signaling message receiver is set (via ConnectFakeSignaling), this
234 // will set the whole offer/answer exchange in motion. Just need to wait for
235 // the signaling state to reach "stable".
236 void CreateAndSetAndSignalOffer() {
Eldar Rello5ab79e62019-10-09 18:29:44 +0300237 auto offer = CreateOfferAndWait();
deadbeef1dcb1642017-03-29 21:08:16 -0700238 ASSERT_NE(nullptr, offer);
239 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(offer)));
240 }
241
242 // Sets the options to be used when CreateAndSetAndSignalOffer is called, or
243 // when a remote offer is received (via fake signaling) and an answer is
244 // generated. By default, uses default options.
245 void SetOfferAnswerOptions(
246 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
247 offer_answer_options_ = options;
248 }
249
250 // Set a callback to be invoked when SDP is received via the fake signaling
251 // channel, which provides an opportunity to munge (modify) the SDP. This is
252 // used to test SDP being applied that a PeerConnection would normally not
253 // generate, but a non-JSEP endpoint might.
254 void SetReceivedSdpMunger(
255 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100256 received_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700257 }
258
deadbeefc964d0b2017-04-03 10:03:35 -0700259 // Similar to the above, but this is run on SDP immediately after it's
deadbeef1dcb1642017-03-29 21:08:16 -0700260 // generated.
261 void SetGeneratedSdpMunger(
262 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100263 generated_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700264 }
265
Seth Hampson2f0d7022018-02-20 11:54:42 -0800266 // Set a callback to be invoked when a remote offer is received via the fake
267 // signaling channel. This provides an opportunity to change the
268 // PeerConnection state before an answer is created and sent to the caller.
269 void SetRemoteOfferHandler(std::function<void()> handler) {
270 remote_offer_handler_ = std::move(handler);
271 }
272
Qingsi Wang1dac6d82018-12-12 15:28:47 -0800273 void SetRemoteAsyncResolver(rtc::MockAsyncResolver* resolver) {
274 remote_async_resolver_ = resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700275 }
276
Steve Antonede9ca52017-10-16 13:04:27 -0700277 // Every ICE connection state in order that has been seen by the observer.
278 std::vector<PeerConnectionInterface::IceConnectionState>
279 ice_connection_state_history() const {
280 return ice_connection_state_history_;
281 }
Steve Anton6f25b092017-10-23 09:39:20 -0700282 void clear_ice_connection_state_history() {
283 ice_connection_state_history_.clear();
284 }
Steve Antonede9ca52017-10-16 13:04:27 -0700285
Jonas Olssonacd8ae72019-02-25 15:26:24 +0100286 // Every standardized ICE connection state in order that has been seen by the
287 // observer.
288 std::vector<PeerConnectionInterface::IceConnectionState>
289 standardized_ice_connection_state_history() const {
290 return standardized_ice_connection_state_history_;
291 }
292
Jonas Olsson635474e2018-10-18 15:58:17 +0200293 // Every PeerConnection state in order that has been seen by the observer.
294 std::vector<PeerConnectionInterface::PeerConnectionState>
295 peer_connection_state_history() const {
296 return peer_connection_state_history_;
297 }
298
Steve Antonede9ca52017-10-16 13:04:27 -0700299 // Every ICE gathering state in order that has been seen by the observer.
300 std::vector<PeerConnectionInterface::IceGatheringState>
301 ice_gathering_state_history() const {
302 return ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -0700303 }
Alex Drake00c7ecf2019-08-06 10:54:47 -0700304 std::vector<cricket::CandidatePairChangeEvent>
305 ice_candidate_pair_change_history() const {
306 return ice_candidate_pair_change_history_;
307 }
deadbeef1dcb1642017-03-29 21:08:16 -0700308
Eldar Rello5ab79e62019-10-09 18:29:44 +0300309 // Every PeerConnection signaling state in order that has been seen by the
310 // observer.
311 std::vector<PeerConnectionInterface::SignalingState>
312 peer_connection_signaling_state_history() const {
313 return peer_connection_signaling_state_history_;
314 }
315
Steve Anton15324772018-01-16 10:26:49 -0800316 void AddAudioVideoTracks() {
317 AddAudioTrack();
318 AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700319 }
320
Steve Anton74255ff2018-01-24 18:32:57 -0800321 rtc::scoped_refptr<RtpSenderInterface> AddAudioTrack() {
322 return AddTrack(CreateLocalAudioTrack());
323 }
deadbeef1dcb1642017-03-29 21:08:16 -0700324
Steve Anton74255ff2018-01-24 18:32:57 -0800325 rtc::scoped_refptr<RtpSenderInterface> AddVideoTrack() {
326 return AddTrack(CreateLocalVideoTrack());
327 }
deadbeef1dcb1642017-03-29 21:08:16 -0700328
329 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack() {
Niels Möller2d02e082018-05-21 11:23:35 +0200330 cricket::AudioOptions options;
deadbeef1dcb1642017-03-29 21:08:16 -0700331 // Disable highpass filter so that we can get all the test audio frames.
Niels Möller2d02e082018-05-21 11:23:35 +0200332 options.highpass_filter = false;
deadbeef1dcb1642017-03-29 21:08:16 -0700333 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
Niels Möller2d02e082018-05-21 11:23:35 +0200334 peer_connection_factory_->CreateAudioSource(options);
deadbeef1dcb1642017-03-29 21:08:16 -0700335 // TODO(perkj): Test audio source when it is implemented. Currently audio
336 // always use the default input.
deadbeefb1a15d72017-09-07 14:12:05 -0700337 return peer_connection_factory_->CreateAudioTrack(rtc::CreateRandomUuid(),
deadbeef1dcb1642017-03-29 21:08:16 -0700338 source);
339 }
340
341 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack() {
Johannes Kron965e7942018-09-13 15:36:20 +0200342 webrtc::FakePeriodicVideoSource::Config config;
343 config.timestamp_offset_ms = rtc::TimeMillis();
344 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700345 }
346
347 rtc::scoped_refptr<webrtc::VideoTrackInterface>
Niels Möller5c7efe72018-05-11 10:34:46 +0200348 CreateLocalVideoTrackWithConfig(
349 webrtc::FakePeriodicVideoSource::Config config) {
350 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700351 }
352
353 rtc::scoped_refptr<webrtc::VideoTrackInterface>
354 CreateLocalVideoTrackWithRotation(webrtc::VideoRotation rotation) {
Niels Möller5c7efe72018-05-11 10:34:46 +0200355 webrtc::FakePeriodicVideoSource::Config config;
356 config.rotation = rotation;
Johannes Kron965e7942018-09-13 15:36:20 +0200357 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +0200358 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700359 }
360
Steve Anton74255ff2018-01-24 18:32:57 -0800361 rtc::scoped_refptr<RtpSenderInterface> AddTrack(
362 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800363 const std::vector<std::string>& stream_ids = {}) {
364 auto result = pc()->AddTrack(track, stream_ids);
Steve Anton15324772018-01-16 10:26:49 -0800365 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
Steve Anton74255ff2018-01-24 18:32:57 -0800366 return result.MoveValue();
367 }
368
369 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceiversOfType(
370 cricket::MediaType media_type) {
371 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100372 for (const auto& receiver : pc()->GetReceivers()) {
Steve Anton74255ff2018-01-24 18:32:57 -0800373 if (receiver->media_type() == media_type) {
374 receivers.push_back(receiver);
375 }
376 }
377 return receivers;
deadbeef1dcb1642017-03-29 21:08:16 -0700378 }
379
Seth Hampson2f0d7022018-02-20 11:54:42 -0800380 rtc::scoped_refptr<RtpTransceiverInterface> GetFirstTransceiverOfType(
381 cricket::MediaType media_type) {
382 for (auto transceiver : pc()->GetTransceivers()) {
383 if (transceiver->receiver()->media_type() == media_type) {
384 return transceiver;
385 }
386 }
387 return nullptr;
388 }
389
deadbeef1dcb1642017-03-29 21:08:16 -0700390 bool SignalingStateStable() {
391 return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable;
392 }
393
394 void CreateDataChannel() { CreateDataChannel(nullptr); }
395
396 void CreateDataChannel(const webrtc::DataChannelInit* init) {
Steve Antonda6c0952017-10-23 11:41:54 -0700397 CreateDataChannel(kDataChannelLabel, init);
398 }
399
400 void CreateDataChannel(const std::string& label,
401 const webrtc::DataChannelInit* init) {
402 data_channel_ = pc()->CreateDataChannel(label, init);
deadbeef1dcb1642017-03-29 21:08:16 -0700403 ASSERT_TRUE(data_channel_.get() != nullptr);
404 data_observer_.reset(new MockDataChannelObserver(data_channel_));
405 }
406
407 DataChannelInterface* data_channel() { return data_channel_; }
408 const MockDataChannelObserver* data_observer() const {
409 return data_observer_.get();
410 }
411
412 int audio_frames_received() const {
413 return fake_audio_capture_module_->frames_received();
414 }
415
416 // Takes minimum of video frames received for each track.
417 //
418 // Can be used like:
419 // EXPECT_GE(expected_frames, min_video_frames_received_per_track());
420 //
421 // To ensure that all video tracks received at least a certain number of
422 // frames.
423 int min_video_frames_received_per_track() const {
424 int min_frames = INT_MAX;
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200425 if (fake_video_renderers_.empty()) {
426 return 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700427 }
deadbeef1dcb1642017-03-29 21:08:16 -0700428
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200429 for (const auto& pair : fake_video_renderers_) {
430 min_frames = std::min(min_frames, pair.second->num_rendered_frames());
deadbeef1dcb1642017-03-29 21:08:16 -0700431 }
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200432 return min_frames;
deadbeef1dcb1642017-03-29 21:08:16 -0700433 }
434
435 // Returns a MockStatsObserver in a state after stats gathering finished,
436 // which can be used to access the gathered stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700437 rtc::scoped_refptr<MockStatsObserver> OldGetStatsForTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700438 webrtc::MediaStreamTrackInterface* track) {
439 rtc::scoped_refptr<MockStatsObserver> observer(
440 new rtc::RefCountedObject<MockStatsObserver>());
441 EXPECT_TRUE(peer_connection_->GetStats(
442 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard));
443 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
444 return observer;
445 }
446
447 // Version that doesn't take a track "filter", and gathers all stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700448 rtc::scoped_refptr<MockStatsObserver> OldGetStats() {
449 return OldGetStatsForTrack(nullptr);
450 }
451
452 // Synchronously gets stats and returns them. If it times out, fails the test
453 // and returns null.
454 rtc::scoped_refptr<const webrtc::RTCStatsReport> NewGetStats() {
455 rtc::scoped_refptr<webrtc::MockRTCStatsCollectorCallback> callback(
456 new rtc::RefCountedObject<webrtc::MockRTCStatsCollectorCallback>());
457 peer_connection_->GetStats(callback);
458 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
459 return callback->report();
deadbeef1dcb1642017-03-29 21:08:16 -0700460 }
461
462 int rendered_width() {
463 EXPECT_FALSE(fake_video_renderers_.empty());
464 return fake_video_renderers_.empty()
465 ? 0
466 : fake_video_renderers_.begin()->second->width();
467 }
468
469 int rendered_height() {
470 EXPECT_FALSE(fake_video_renderers_.empty());
471 return fake_video_renderers_.empty()
472 ? 0
473 : fake_video_renderers_.begin()->second->height();
474 }
475
476 double rendered_aspect_ratio() {
477 if (rendered_height() == 0) {
478 return 0.0;
479 }
480 return static_cast<double>(rendered_width()) / rendered_height();
481 }
482
483 webrtc::VideoRotation rendered_rotation() {
484 EXPECT_FALSE(fake_video_renderers_.empty());
485 return fake_video_renderers_.empty()
486 ? webrtc::kVideoRotation_0
487 : fake_video_renderers_.begin()->second->rotation();
488 }
489
490 int local_rendered_width() {
491 return local_video_renderer_ ? local_video_renderer_->width() : 0;
492 }
493
494 int local_rendered_height() {
495 return local_video_renderer_ ? local_video_renderer_->height() : 0;
496 }
497
498 double local_rendered_aspect_ratio() {
499 if (local_rendered_height() == 0) {
500 return 0.0;
501 }
502 return static_cast<double>(local_rendered_width()) /
503 local_rendered_height();
504 }
505
506 size_t number_of_remote_streams() {
507 if (!pc()) {
508 return 0;
509 }
510 return pc()->remote_streams()->count();
511 }
512
513 StreamCollectionInterface* remote_streams() const {
514 if (!pc()) {
515 ADD_FAILURE();
516 return nullptr;
517 }
518 return pc()->remote_streams();
519 }
520
521 StreamCollectionInterface* local_streams() {
522 if (!pc()) {
523 ADD_FAILURE();
524 return nullptr;
525 }
526 return pc()->local_streams();
527 }
528
529 webrtc::PeerConnectionInterface::SignalingState signaling_state() {
530 return pc()->signaling_state();
531 }
532
533 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() {
534 return pc()->ice_connection_state();
535 }
536
Jonas Olsson7a6739e2019-01-15 16:31:55 +0100537 webrtc::PeerConnectionInterface::IceConnectionState
538 standardized_ice_connection_state() {
539 return pc()->standardized_ice_connection_state();
540 }
541
deadbeef1dcb1642017-03-29 21:08:16 -0700542 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() {
543 return pc()->ice_gathering_state();
544 }
545
546 // Returns a MockRtpReceiverObserver for each RtpReceiver returned by
547 // GetReceivers. They're updated automatically when a remote offer/answer
548 // from the fake signaling channel is applied, or when
549 // ResetRtpReceiverObservers below is called.
550 const std::vector<std::unique_ptr<MockRtpReceiverObserver>>&
551 rtp_receiver_observers() {
552 return rtp_receiver_observers_;
553 }
554
555 void ResetRtpReceiverObservers() {
556 rtp_receiver_observers_.clear();
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100557 for (const rtc::scoped_refptr<RtpReceiverInterface>& receiver :
558 pc()->GetReceivers()) {
deadbeef1dcb1642017-03-29 21:08:16 -0700559 std::unique_ptr<MockRtpReceiverObserver> observer(
560 new MockRtpReceiverObserver(receiver->media_type()));
561 receiver->SetObserver(observer.get());
562 rtp_receiver_observers_.push_back(std::move(observer));
563 }
564 }
565
Qingsi Wangecd30542019-05-22 14:34:56 -0700566 rtc::FakeNetworkManager* network_manager() const {
Steve Antonede9ca52017-10-16 13:04:27 -0700567 return fake_network_manager_.get();
568 }
569 cricket::PortAllocator* port_allocator() const { return port_allocator_; }
570
Qingsi Wang7685e862018-06-11 20:15:46 -0700571 webrtc::FakeRtcEventLogFactory* event_log_factory() const {
572 return event_log_factory_;
573 }
574
Qingsi Wangc129c352019-04-18 10:41:58 -0700575 const cricket::Candidate& last_candidate_gathered() const {
576 return last_candidate_gathered_;
577 }
Eldar Relloda13ea22019-06-01 12:23:43 +0300578 const cricket::IceCandidateErrorEvent& error_event() const {
579 return error_event_;
580 }
Qingsi Wangc129c352019-04-18 10:41:58 -0700581
Qingsi Wangecd30542019-05-22 14:34:56 -0700582 // Sets the mDNS responder for the owned fake network manager and keeps a
583 // reference to the responder.
584 void SetMdnsResponder(
585 std::unique_ptr<webrtc::FakeMdnsResponder> mdns_responder) {
586 RTC_DCHECK(mdns_responder != nullptr);
587 mdns_responder_ = mdns_responder.get();
588 network_manager()->set_mdns_responder(std::move(mdns_responder));
589 }
590
Eldar Rello5ab79e62019-10-09 18:29:44 +0300591 // Returns null on failure.
592 std::unique_ptr<SessionDescriptionInterface> CreateOfferAndWait() {
593 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
594 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
595 pc()->CreateOffer(observer, offer_answer_options_);
596 return WaitForDescriptionFromObserver(observer);
597 }
Eldar Rellod9ebe012020-03-18 20:41:45 +0200598 bool Rollback() {
599 return SetRemoteDescription(
600 webrtc::CreateSessionDescription(SdpType::kRollback, ""));
601 }
Eldar Rello5ab79e62019-10-09 18:29:44 +0300602
Harald Alvestrandcc6ae442021-01-18 08:06:23 +0000603 // Functions for querying stats.
604 void StartWatchingDelayStats() {
605 // Get the baseline numbers for audio_packets and audio_delay.
606 auto received_stats = NewGetStats();
607 auto track_stats =
608 received_stats->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>()[0];
609 ASSERT_TRUE(track_stats->relative_packet_arrival_delay.is_defined());
610 auto rtp_stats =
611 received_stats->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>()[0];
612 ASSERT_TRUE(rtp_stats->packets_received.is_defined());
613 ASSERT_TRUE(rtp_stats->track_id.is_defined());
614 audio_track_stats_id_ = track_stats->id();
615 ASSERT_TRUE(received_stats->Get(audio_track_stats_id_));
616 rtp_stats_id_ = rtp_stats->id();
617 ASSERT_EQ(audio_track_stats_id_, *rtp_stats->track_id);
618 audio_packets_stat_ = *rtp_stats->packets_received;
619 audio_delay_stat_ = *track_stats->relative_packet_arrival_delay;
620 }
621
622 void UpdateDelayStats(std::string tag, int desc_size) {
623 auto report = NewGetStats();
624 auto track_stats =
625 report->GetAs<webrtc::RTCMediaStreamTrackStats>(audio_track_stats_id_);
626 ASSERT_TRUE(track_stats);
627 auto rtp_stats =
628 report->GetAs<webrtc::RTCInboundRTPStreamStats>(rtp_stats_id_);
629 ASSERT_TRUE(rtp_stats);
630 auto delta_packets = *rtp_stats->packets_received - audio_packets_stat_;
631 auto delta_rpad =
632 *track_stats->relative_packet_arrival_delay - audio_delay_stat_;
633 auto recent_delay = delta_packets > 0 ? delta_rpad / delta_packets : -1;
634 // An average relative packet arrival delay over the renegotiation of
635 // > 100 ms indicates that something is dramatically wrong, and will impact
636 // quality for sure.
637 ASSERT_GT(0.1, recent_delay) << tag << " size " << desc_size;
638 // Increment trailing counters
639 audio_packets_stat_ = *rtp_stats->packets_received;
640 audio_delay_stat_ = *track_stats->relative_packet_arrival_delay;
641 }
642
deadbeef1dcb1642017-03-29 21:08:16 -0700643 private:
644 explicit PeerConnectionWrapper(const std::string& debug_name)
645 : debug_name_(debug_name) {}
646
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800647 bool Init(
648 const PeerConnectionFactory::Options* options,
649 const PeerConnectionInterface::RTCConfiguration* config,
650 webrtc::PeerConnectionDependencies dependencies,
651 rtc::Thread* network_thread,
652 rtc::Thread* worker_thread,
653 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory,
Johannes Kron3e983682020-03-29 22:17:00 +0200654 bool reset_encoder_factory,
655 bool reset_decoder_factory) {
deadbeef1dcb1642017-03-29 21:08:16 -0700656 // There's an error in this test code if Init ends up being called twice.
657 RTC_DCHECK(!peer_connection_);
658 RTC_DCHECK(!peer_connection_factory_);
659
660 fake_network_manager_.reset(new rtc::FakeNetworkManager());
Steve Antonede9ca52017-10-16 13:04:27 -0700661 fake_network_manager_->AddInterface(kDefaultLocalAddress);
deadbeef1dcb1642017-03-29 21:08:16 -0700662
663 std::unique_ptr<cricket::PortAllocator> port_allocator(
664 new cricket::BasicPortAllocator(fake_network_manager_.get()));
Steve Antonede9ca52017-10-16 13:04:27 -0700665 port_allocator_ = port_allocator.get();
deadbeef1dcb1642017-03-29 21:08:16 -0700666 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
667 if (!fake_audio_capture_module_) {
668 return false;
669 }
deadbeef1dcb1642017-03-29 21:08:16 -0700670 rtc::Thread* const signaling_thread = rtc::Thread::Current();
Qingsi Wang7685e862018-06-11 20:15:46 -0700671
672 webrtc::PeerConnectionFactoryDependencies pc_factory_dependencies;
673 pc_factory_dependencies.network_thread = network_thread;
674 pc_factory_dependencies.worker_thread = worker_thread;
675 pc_factory_dependencies.signaling_thread = signaling_thread;
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200676 pc_factory_dependencies.task_queue_factory =
677 webrtc::CreateDefaultTaskQueueFactory();
Erik Språngceb44952020-09-22 11:36:35 +0200678 pc_factory_dependencies.trials = std::make_unique<FieldTrialBasedConfig>();
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200679 cricket::MediaEngineDependencies media_deps;
680 media_deps.task_queue_factory =
681 pc_factory_dependencies.task_queue_factory.get();
682 media_deps.adm = fake_audio_capture_module_;
683 webrtc::SetMediaEngineDefaults(&media_deps);
Johannes Kron3e983682020-03-29 22:17:00 +0200684
685 if (reset_encoder_factory) {
686 media_deps.video_encoder_factory.reset();
687 }
688 if (reset_decoder_factory) {
689 media_deps.video_decoder_factory.reset();
690 }
691
Per Åhgrencc73ed32020-04-26 23:56:17 +0200692 if (!media_deps.audio_processing) {
693 // If the standard Creation method for APM returns a null pointer, instead
694 // use the builder for testing to create an APM object.
695 media_deps.audio_processing = AudioProcessingBuilderForTesting().Create();
696 }
697
Erik Språngceb44952020-09-22 11:36:35 +0200698 media_deps.trials = pc_factory_dependencies.trials.get();
699
Qingsi Wang7685e862018-06-11 20:15:46 -0700700 pc_factory_dependencies.media_engine =
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200701 cricket::CreateMediaEngine(std::move(media_deps));
Qingsi Wang7685e862018-06-11 20:15:46 -0700702 pc_factory_dependencies.call_factory = webrtc::CreateCallFactory();
703 if (event_log_factory) {
704 event_log_factory_ = event_log_factory.get();
705 pc_factory_dependencies.event_log_factory = std::move(event_log_factory);
706 } else {
707 pc_factory_dependencies.event_log_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200708 std::make_unique<webrtc::RtcEventLogFactory>(
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200709 pc_factory_dependencies.task_queue_factory.get());
Qingsi Wang7685e862018-06-11 20:15:46 -0700710 }
711 peer_connection_factory_ = webrtc::CreateModularPeerConnectionFactory(
712 std::move(pc_factory_dependencies));
713
deadbeef1dcb1642017-03-29 21:08:16 -0700714 if (!peer_connection_factory_) {
715 return false;
716 }
717 if (options) {
718 peer_connection_factory_->SetOptions(*options);
719 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800720 if (config) {
721 sdp_semantics_ = config->sdp_semantics;
722 }
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700723
724 dependencies.allocator = std::move(port_allocator);
Niels Möllerf06f9232018-08-07 12:32:18 +0200725 peer_connection_ = CreatePeerConnection(config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700726 return peer_connection_.get() != nullptr;
727 }
728
729 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(
deadbeef1dcb1642017-03-29 21:08:16 -0700730 const PeerConnectionInterface::RTCConfiguration* config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700731 webrtc::PeerConnectionDependencies dependencies) {
deadbeef1dcb1642017-03-29 21:08:16 -0700732 PeerConnectionInterface::RTCConfiguration modified_config;
733 // If |config| is null, this will result in a default configuration being
734 // used.
735 if (config) {
736 modified_config = *config;
737 }
738 // Disable resolution adaptation; we don't want it interfering with the
739 // test results.
740 // TODO(deadbeef): Do something more robust. Since we're testing for aspect
741 // ratios and not specific resolutions, is this even necessary?
742 modified_config.set_cpu_adaptation(false);
743
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700744 dependencies.observer = this;
deadbeef1dcb1642017-03-29 21:08:16 -0700745 return peer_connection_factory_->CreatePeerConnection(
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700746 modified_config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700747 }
748
749 void set_signaling_message_receiver(
750 SignalingMessageReceiver* signaling_message_receiver) {
751 signaling_message_receiver_ = signaling_message_receiver;
752 }
753
754 void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; }
755
Steve Antonede9ca52017-10-16 13:04:27 -0700756 void set_signal_ice_candidates(bool signal) {
757 signal_ice_candidates_ = signal;
758 }
759
deadbeef1dcb1642017-03-29 21:08:16 -0700760 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
Niels Möller5c7efe72018-05-11 10:34:46 +0200761 webrtc::FakePeriodicVideoSource::Config config) {
deadbeef1dcb1642017-03-29 21:08:16 -0700762 // Set max frame rate to 10fps to reduce the risk of test flakiness.
763 // TODO(deadbeef): Do something more robust.
Niels Möller5c7efe72018-05-11 10:34:46 +0200764 config.frame_interval_ms = 100;
deadbeef1dcb1642017-03-29 21:08:16 -0700765
Niels Möller5c7efe72018-05-11 10:34:46 +0200766 video_track_sources_.emplace_back(
Niels Möller0f405822018-05-17 09:16:41 +0200767 new rtc::RefCountedObject<webrtc::FakePeriodicVideoTrackSource>(
768 config, false /* remote */));
deadbeef1dcb1642017-03-29 21:08:16 -0700769 rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
Niels Möller5c7efe72018-05-11 10:34:46 +0200770 peer_connection_factory_->CreateVideoTrack(
771 rtc::CreateRandomUuid(), video_track_sources_.back()));
deadbeef1dcb1642017-03-29 21:08:16 -0700772 if (!local_video_renderer_) {
773 local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
774 }
775 return track;
776 }
777
778 void HandleIncomingOffer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100779 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer";
Steve Antona3a92c22017-12-07 10:27:41 -0800780 std::unique_ptr<SessionDescriptionInterface> desc =
781 webrtc::CreateSessionDescription(SdpType::kOffer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700782 if (received_sdp_munger_) {
783 received_sdp_munger_(desc->description());
784 }
785
786 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
787 // Setting a remote description may have changed the number of receivers,
788 // so reset the receiver observers.
789 ResetRtpReceiverObservers();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800790 if (remote_offer_handler_) {
791 remote_offer_handler_();
792 }
deadbeef1dcb1642017-03-29 21:08:16 -0700793 auto answer = CreateAnswer();
794 ASSERT_NE(nullptr, answer);
795 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
796 }
797
798 void HandleIncomingAnswer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100799 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
Steve Antona3a92c22017-12-07 10:27:41 -0800800 std::unique_ptr<SessionDescriptionInterface> desc =
801 webrtc::CreateSessionDescription(SdpType::kAnswer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700802 if (received_sdp_munger_) {
803 received_sdp_munger_(desc->description());
804 }
805
806 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
807 // Set the RtpReceiverObserver after receivers are created.
808 ResetRtpReceiverObservers();
809 }
810
811 // Returns null on failure.
deadbeef1dcb1642017-03-29 21:08:16 -0700812 std::unique_ptr<SessionDescriptionInterface> CreateAnswer() {
813 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
814 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
815 pc()->CreateAnswer(observer, offer_answer_options_);
816 return WaitForDescriptionFromObserver(observer);
817 }
818
819 std::unique_ptr<SessionDescriptionInterface> WaitForDescriptionFromObserver(
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100820 MockCreateSessionDescriptionObserver* observer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700821 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
822 if (!observer->result()) {
823 return nullptr;
824 }
825 auto description = observer->MoveDescription();
826 if (generated_sdp_munger_) {
827 generated_sdp_munger_(description->description());
828 }
829 return description;
830 }
831
832 // Setting the local description and sending the SDP message over the fake
833 // signaling channel are combined into the same method because the SDP
834 // message needs to be sent as soon as SetLocalDescription finishes, without
835 // waiting for the observer to be called. This ensures that ICE candidates
836 // don't outrace the description.
837 bool SetLocalDescriptionAndSendSdpMessage(
838 std::unique_ptr<SessionDescriptionInterface> desc) {
839 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
840 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100841 RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage";
Steve Antona3a92c22017-12-07 10:27:41 -0800842 SdpType type = desc->GetType();
deadbeef1dcb1642017-03-29 21:08:16 -0700843 std::string sdp;
844 EXPECT_TRUE(desc->ToString(&sdp));
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700845 RTC_LOG(LS_INFO) << debug_name_ << ": local SDP contents=\n" << sdp;
deadbeef1dcb1642017-03-29 21:08:16 -0700846 pc()->SetLocalDescription(observer, desc.release());
Harald Alvestrand6060df52020-08-11 09:54:02 +0200847 RemoveUnusedVideoRenderers();
deadbeef1dcb1642017-03-29 21:08:16 -0700848 // As mentioned above, we need to send the message immediately after
849 // SetLocalDescription.
850 SendSdpMessage(type, sdp);
851 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
852 return true;
853 }
854
855 bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
856 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
857 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100858 RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription";
deadbeef1dcb1642017-03-29 21:08:16 -0700859 pc()->SetRemoteDescription(observer, desc.release());
Harald Alvestrand6060df52020-08-11 09:54:02 +0200860 RemoveUnusedVideoRenderers();
deadbeef1dcb1642017-03-29 21:08:16 -0700861 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
862 return observer->result();
863 }
864
Seth Hampson2f0d7022018-02-20 11:54:42 -0800865 // This is a work around to remove unused fake_video_renderers from
866 // transceivers that have either stopped or are no longer receiving.
867 void RemoveUnusedVideoRenderers() {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200868 if (sdp_semantics_ != SdpSemantics::kUnifiedPlan) {
869 return;
870 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800871 auto transceivers = pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +0200872 std::set<std::string> active_renderers;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800873 for (auto& transceiver : transceivers) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200874 // Note - we don't check for direction here. This function is called
875 // before direction is set, and in that case, we should not remove
876 // the renderer.
877 if (transceiver->receiver()->media_type() == cricket::MEDIA_TYPE_VIDEO) {
878 active_renderers.insert(transceiver->receiver()->track()->id());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800879 }
Harald Alvestrand6060df52020-08-11 09:54:02 +0200880 }
881 for (auto it = fake_video_renderers_.begin();
882 it != fake_video_renderers_.end();) {
883 // Remove fake video renderers belonging to any non-active transceivers.
884 if (!active_renderers.count(it->first)) {
885 it = fake_video_renderers_.erase(it);
886 } else {
887 it++;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800888 }
889 }
890 }
891
deadbeef1dcb1642017-03-29 21:08:16 -0700892 // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by
893 // default).
Steve Antona3a92c22017-12-07 10:27:41 -0800894 void SendSdpMessage(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700895 if (signaling_delay_ms_ == 0) {
896 RelaySdpMessageIfReceiverExists(type, msg);
897 } else {
898 invoker_.AsyncInvokeDelayed<void>(
899 RTC_FROM_HERE, rtc::Thread::Current(),
Niels Möller4bab23f2021-01-18 09:24:33 +0100900 [this, type, msg] { RelaySdpMessageIfReceiverExists(type, msg); },
deadbeef1dcb1642017-03-29 21:08:16 -0700901 signaling_delay_ms_);
902 }
903 }
904
Steve Antona3a92c22017-12-07 10:27:41 -0800905 void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700906 if (signaling_message_receiver_) {
907 signaling_message_receiver_->ReceiveSdpMessage(type, msg);
908 }
909 }
910
911 // Simulate trickling an ICE candidate with delay |signaling_delay_ms_| (0 by
912 // default).
913 void SendIceMessage(const std::string& sdp_mid,
914 int sdp_mline_index,
915 const std::string& msg) {
916 if (signaling_delay_ms_ == 0) {
917 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
918 } else {
919 invoker_.AsyncInvokeDelayed<void>(
920 RTC_FROM_HERE, rtc::Thread::Current(),
Niels Möller4bab23f2021-01-18 09:24:33 +0100921 [this, sdp_mid, sdp_mline_index, msg] {
922 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
923 },
deadbeef1dcb1642017-03-29 21:08:16 -0700924 signaling_delay_ms_);
925 }
926 }
927
928 void RelayIceMessageIfReceiverExists(const std::string& sdp_mid,
929 int sdp_mline_index,
930 const std::string& msg) {
931 if (signaling_message_receiver_) {
932 signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index,
933 msg);
934 }
935 }
936
937 // SignalingMessageReceiver callbacks.
Steve Antona3a92c22017-12-07 10:27:41 -0800938 void ReceiveSdpMessage(SdpType type, const std::string& msg) override {
939 if (type == SdpType::kOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700940 HandleIncomingOffer(msg);
941 } else {
942 HandleIncomingAnswer(msg);
943 }
944 }
945
946 void ReceiveIceMessage(const std::string& sdp_mid,
947 int sdp_mline_index,
948 const std::string& msg) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100949 RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage";
deadbeef1dcb1642017-03-29 21:08:16 -0700950 std::unique_ptr<webrtc::IceCandidateInterface> candidate(
951 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr));
952 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
953 }
954
955 // PeerConnectionObserver callbacks.
956 void OnSignalingChange(
957 webrtc::PeerConnectionInterface::SignalingState new_state) override {
958 EXPECT_EQ(pc()->signaling_state(), new_state);
Eldar Rello5ab79e62019-10-09 18:29:44 +0300959 peer_connection_signaling_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700960 }
Steve Anton15324772018-01-16 10:26:49 -0800961 void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
962 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
963 streams) override {
964 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
965 rtc::scoped_refptr<VideoTrackInterface> video_track(
966 static_cast<VideoTrackInterface*>(receiver->track().get()));
967 ASSERT_TRUE(fake_video_renderers_.find(video_track->id()) ==
deadbeef1dcb1642017-03-29 21:08:16 -0700968 fake_video_renderers_.end());
Steve Anton15324772018-01-16 10:26:49 -0800969 fake_video_renderers_[video_track->id()] =
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200970 std::make_unique<FakeVideoTrackRenderer>(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -0700971 }
972 }
Steve Anton15324772018-01-16 10:26:49 -0800973 void OnRemoveTrack(
974 rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
975 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
976 auto it = fake_video_renderers_.find(receiver->track()->id());
Harald Alvestrand6060df52020-08-11 09:54:02 +0200977 if (it != fake_video_renderers_.end()) {
978 fake_video_renderers_.erase(it);
979 } else {
980 RTC_LOG(LS_ERROR) << "OnRemoveTrack called for non-active renderer";
981 }
Steve Anton15324772018-01-16 10:26:49 -0800982 }
983 }
deadbeef1dcb1642017-03-29 21:08:16 -0700984 void OnRenegotiationNeeded() override {}
985 void OnIceConnectionChange(
986 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
987 EXPECT_EQ(pc()->ice_connection_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700988 ice_connection_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700989 }
Jonas Olssonacd8ae72019-02-25 15:26:24 +0100990 void OnStandardizedIceConnectionChange(
991 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
992 standardized_ice_connection_state_history_.push_back(new_state);
993 }
Jonas Olsson635474e2018-10-18 15:58:17 +0200994 void OnConnectionChange(
995 webrtc::PeerConnectionInterface::PeerConnectionState new_state) override {
996 peer_connection_state_history_.push_back(new_state);
997 }
998
deadbeef1dcb1642017-03-29 21:08:16 -0700999 void OnIceGatheringChange(
1000 webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
deadbeef1dcb1642017-03-29 21:08:16 -07001001 EXPECT_EQ(pc()->ice_gathering_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -07001002 ice_gathering_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -07001003 }
Alex Drake00c7ecf2019-08-06 10:54:47 -07001004
1005 void OnIceSelectedCandidatePairChanged(
1006 const cricket::CandidatePairChangeEvent& event) {
1007 ice_candidate_pair_change_history_.push_back(event);
1008 }
Alex Drake43faee02019-08-12 16:27:34 -07001009
deadbeef1dcb1642017-03-29 21:08:16 -07001010 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001011 RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate";
deadbeef1dcb1642017-03-29 21:08:16 -07001012
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001013 if (remote_async_resolver_) {
1014 const auto& local_candidate = candidate->candidate();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001015 if (local_candidate.address().IsUnresolvedIP()) {
1016 RTC_DCHECK(local_candidate.type() == cricket::LOCAL_PORT_TYPE);
1017 rtc::SocketAddress resolved_addr(local_candidate.address());
Qingsi Wangecd30542019-05-22 14:34:56 -07001018 const auto resolved_ip = mdns_responder_->GetMappedAddressForName(
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001019 local_candidate.address().hostname());
1020 RTC_DCHECK(!resolved_ip.IsNil());
1021 resolved_addr.SetResolvedIP(resolved_ip);
1022 EXPECT_CALL(*remote_async_resolver_, GetResolvedAddress(_, _))
1023 .WillOnce(DoAll(SetArgPointee<1>(resolved_addr), Return(true)));
1024 EXPECT_CALL(*remote_async_resolver_, Destroy(_));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001025 }
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001026 }
1027
deadbeef1dcb1642017-03-29 21:08:16 -07001028 std::string ice_sdp;
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001029 EXPECT_TRUE(candidate->ToString(&ice_sdp));
Steve Antonede9ca52017-10-16 13:04:27 -07001030 if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) {
deadbeef1dcb1642017-03-29 21:08:16 -07001031 // Remote party may be deleted.
1032 return;
1033 }
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001034 SendIceMessage(candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp);
Qingsi Wangc129c352019-04-18 10:41:58 -07001035 last_candidate_gathered_ = candidate->candidate();
deadbeef1dcb1642017-03-29 21:08:16 -07001036 }
Eldar Rello0095d372019-12-02 22:22:07 +02001037 void OnIceCandidateError(const std::string& address,
1038 int port,
Eldar Relloda13ea22019-06-01 12:23:43 +03001039 const std::string& url,
1040 int error_code,
1041 const std::string& error_text) override {
Eldar Rello0095d372019-12-02 22:22:07 +02001042 error_event_ = cricket::IceCandidateErrorEvent(address, port, url,
Eldar Relloda13ea22019-06-01 12:23:43 +03001043 error_code, error_text);
1044 }
deadbeef1dcb1642017-03-29 21:08:16 -07001045 void OnDataChannel(
1046 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001047 RTC_LOG(LS_INFO) << debug_name_ << ": OnDataChannel";
deadbeef1dcb1642017-03-29 21:08:16 -07001048 data_channel_ = data_channel;
1049 data_observer_.reset(new MockDataChannelObserver(data_channel));
1050 }
1051
deadbeef1dcb1642017-03-29 21:08:16 -07001052 std::string debug_name_;
1053
1054 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
Qingsi Wangecd30542019-05-22 14:34:56 -07001055 // Reference to the mDNS responder owned by |fake_network_manager_| after set.
1056 webrtc::FakeMdnsResponder* mdns_responder_ = nullptr;
deadbeef1dcb1642017-03-29 21:08:16 -07001057
1058 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
1059 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
1060 peer_connection_factory_;
1061
Steve Antonede9ca52017-10-16 13:04:27 -07001062 cricket::PortAllocator* port_allocator_;
deadbeef1dcb1642017-03-29 21:08:16 -07001063 // Needed to keep track of number of frames sent.
1064 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
1065 // Needed to keep track of number of frames received.
1066 std::map<std::string, std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
1067 fake_video_renderers_;
1068 // Needed to ensure frames aren't received for removed tracks.
1069 std::vector<std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
1070 removed_fake_video_renderers_;
deadbeef1dcb1642017-03-29 21:08:16 -07001071
1072 // For remote peer communication.
1073 SignalingMessageReceiver* signaling_message_receiver_ = nullptr;
1074 int signaling_delay_ms_ = 0;
Steve Antonede9ca52017-10-16 13:04:27 -07001075 bool signal_ice_candidates_ = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07001076 cricket::Candidate last_candidate_gathered_;
Eldar Relloda13ea22019-06-01 12:23:43 +03001077 cricket::IceCandidateErrorEvent error_event_;
deadbeef1dcb1642017-03-29 21:08:16 -07001078
Niels Möller5c7efe72018-05-11 10:34:46 +02001079 // Store references to the video sources we've created, so that we can stop
deadbeef1dcb1642017-03-29 21:08:16 -07001080 // them, if required.
Niels Möller5c7efe72018-05-11 10:34:46 +02001081 std::vector<rtc::scoped_refptr<webrtc::VideoTrackSource>>
1082 video_track_sources_;
deadbeef1dcb1642017-03-29 21:08:16 -07001083 // |local_video_renderer_| attached to the first created local video track.
1084 std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
1085
Seth Hampson2f0d7022018-02-20 11:54:42 -08001086 SdpSemantics sdp_semantics_;
deadbeef1dcb1642017-03-29 21:08:16 -07001087 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_;
1088 std::function<void(cricket::SessionDescription*)> received_sdp_munger_;
1089 std::function<void(cricket::SessionDescription*)> generated_sdp_munger_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001090 std::function<void()> remote_offer_handler_;
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001091 rtc::MockAsyncResolver* remote_async_resolver_ = nullptr;
deadbeef1dcb1642017-03-29 21:08:16 -07001092 rtc::scoped_refptr<DataChannelInterface> data_channel_;
1093 std::unique_ptr<MockDataChannelObserver> data_observer_;
1094
1095 std::vector<std::unique_ptr<MockRtpReceiverObserver>> rtp_receiver_observers_;
1096
Steve Antonede9ca52017-10-16 13:04:27 -07001097 std::vector<PeerConnectionInterface::IceConnectionState>
1098 ice_connection_state_history_;
Jonas Olssonacd8ae72019-02-25 15:26:24 +01001099 std::vector<PeerConnectionInterface::IceConnectionState>
1100 standardized_ice_connection_state_history_;
Jonas Olsson635474e2018-10-18 15:58:17 +02001101 std::vector<PeerConnectionInterface::PeerConnectionState>
1102 peer_connection_state_history_;
Steve Antonede9ca52017-10-16 13:04:27 -07001103 std::vector<PeerConnectionInterface::IceGatheringState>
1104 ice_gathering_state_history_;
Alex Drake00c7ecf2019-08-06 10:54:47 -07001105 std::vector<cricket::CandidatePairChangeEvent>
1106 ice_candidate_pair_change_history_;
Eldar Rello5ab79e62019-10-09 18:29:44 +03001107 std::vector<PeerConnectionInterface::SignalingState>
1108 peer_connection_signaling_state_history_;
Qingsi Wang7685e862018-06-11 20:15:46 -07001109 webrtc::FakeRtcEventLogFactory* event_log_factory_;
1110
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00001111 // Variables for tracking delay stats on an audio track
1112 int audio_packets_stat_ = 0;
1113 double audio_delay_stat_ = 0.0;
1114 std::string rtp_stats_id_;
1115 std::string audio_track_stats_id_;
1116
deadbeef1dcb1642017-03-29 21:08:16 -07001117 rtc::AsyncInvoker invoker_;
1118
Seth Hampson2f0d7022018-02-20 11:54:42 -08001119 friend class PeerConnectionIntegrationBaseTest;
deadbeef1dcb1642017-03-29 21:08:16 -07001120};
1121
Elad Alon99c3fe52017-10-13 16:29:40 +02001122class MockRtcEventLogOutput : public webrtc::RtcEventLogOutput {
1123 public:
1124 virtual ~MockRtcEventLogOutput() = default;
Danil Chapovalov3a353122020-05-15 11:16:53 +02001125 MOCK_METHOD(bool, IsActive, (), (const, override));
1126 MOCK_METHOD(bool, Write, (const std::string&), (override));
Elad Alon99c3fe52017-10-13 16:29:40 +02001127};
1128
Seth Hampson2f0d7022018-02-20 11:54:42 -08001129// This helper object is used for both specifying how many audio/video frames
1130// are expected to be received for a caller/callee. It provides helper functions
1131// to specify these expectations. The object initially starts in a state of no
1132// expectations.
1133class MediaExpectations {
1134 public:
1135 enum ExpectFrames {
1136 kExpectSomeFrames,
1137 kExpectNoFrames,
1138 kNoExpectation,
1139 };
1140
1141 void ExpectBidirectionalAudioAndVideo() {
1142 ExpectBidirectionalAudio();
1143 ExpectBidirectionalVideo();
1144 }
1145
1146 void ExpectBidirectionalAudio() {
1147 CallerExpectsSomeAudio();
1148 CalleeExpectsSomeAudio();
1149 }
1150
1151 void ExpectNoAudio() {
1152 CallerExpectsNoAudio();
1153 CalleeExpectsNoAudio();
1154 }
1155
1156 void ExpectBidirectionalVideo() {
1157 CallerExpectsSomeVideo();
1158 CalleeExpectsSomeVideo();
1159 }
1160
1161 void ExpectNoVideo() {
1162 CallerExpectsNoVideo();
1163 CalleeExpectsNoVideo();
1164 }
1165
1166 void CallerExpectsSomeAudioAndVideo() {
1167 CallerExpectsSomeAudio();
1168 CallerExpectsSomeVideo();
1169 }
1170
1171 void CalleeExpectsSomeAudioAndVideo() {
1172 CalleeExpectsSomeAudio();
1173 CalleeExpectsSomeVideo();
1174 }
1175
1176 // Caller's audio functions.
1177 void CallerExpectsSomeAudio(
1178 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1179 caller_audio_expectation_ = kExpectSomeFrames;
1180 caller_audio_frames_expected_ = expected_audio_frames;
1181 }
1182
1183 void CallerExpectsNoAudio() {
1184 caller_audio_expectation_ = kExpectNoFrames;
1185 caller_audio_frames_expected_ = 0;
1186 }
1187
1188 // Caller's video functions.
1189 void CallerExpectsSomeVideo(
1190 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1191 caller_video_expectation_ = kExpectSomeFrames;
1192 caller_video_frames_expected_ = expected_video_frames;
1193 }
1194
1195 void CallerExpectsNoVideo() {
1196 caller_video_expectation_ = kExpectNoFrames;
1197 caller_video_frames_expected_ = 0;
1198 }
1199
1200 // Callee's audio functions.
1201 void CalleeExpectsSomeAudio(
1202 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1203 callee_audio_expectation_ = kExpectSomeFrames;
1204 callee_audio_frames_expected_ = expected_audio_frames;
1205 }
1206
1207 void CalleeExpectsNoAudio() {
1208 callee_audio_expectation_ = kExpectNoFrames;
1209 callee_audio_frames_expected_ = 0;
1210 }
1211
1212 // Callee's video functions.
1213 void CalleeExpectsSomeVideo(
1214 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1215 callee_video_expectation_ = kExpectSomeFrames;
1216 callee_video_frames_expected_ = expected_video_frames;
1217 }
1218
1219 void CalleeExpectsNoVideo() {
1220 callee_video_expectation_ = kExpectNoFrames;
1221 callee_video_frames_expected_ = 0;
1222 }
1223
1224 ExpectFrames caller_audio_expectation_ = kNoExpectation;
1225 ExpectFrames caller_video_expectation_ = kNoExpectation;
1226 ExpectFrames callee_audio_expectation_ = kNoExpectation;
1227 ExpectFrames callee_video_expectation_ = kNoExpectation;
1228 int caller_audio_frames_expected_ = 0;
1229 int caller_video_frames_expected_ = 0;
1230 int callee_audio_frames_expected_ = 0;
1231 int callee_video_frames_expected_ = 0;
1232};
1233
Qingsi Wang25ec8882019-11-15 12:33:05 -08001234class MockIceTransport : public webrtc::IceTransportInterface {
1235 public:
1236 MockIceTransport(const std::string& name, int component)
1237 : internal_(std::make_unique<cricket::FakeIceTransport>(
1238 name,
1239 component,
1240 nullptr /* network_thread */)) {}
1241 ~MockIceTransport() = default;
1242 cricket::IceTransportInternal* internal() { return internal_.get(); }
1243
1244 private:
1245 std::unique_ptr<cricket::FakeIceTransport> internal_;
1246};
1247
1248class MockIceTransportFactory : public IceTransportFactory {
1249 public:
1250 ~MockIceTransportFactory() override = default;
1251 rtc::scoped_refptr<IceTransportInterface> CreateIceTransport(
1252 const std::string& transport_name,
1253 int component,
1254 IceTransportInit init) {
1255 RecordIceTransportCreated();
1256 return new rtc::RefCountedObject<MockIceTransport>(transport_name,
1257 component);
1258 }
Danil Chapovalov3a353122020-05-15 11:16:53 +02001259 MOCK_METHOD(void, RecordIceTransportCreated, ());
Qingsi Wang25ec8882019-11-15 12:33:05 -08001260};
1261
deadbeef1dcb1642017-03-29 21:08:16 -07001262// Tests two PeerConnections connecting to each other end-to-end, using a
1263// virtual network, fake A/V capture and fake encoder/decoders. The
1264// PeerConnections share the threads/socket servers, but use separate versions
1265// of everything else (including "PeerConnectionFactory"s).
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001266class PeerConnectionIntegrationBaseTest : public ::testing::Test {
deadbeef1dcb1642017-03-29 21:08:16 -07001267 public:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001268 explicit PeerConnectionIntegrationBaseTest(SdpSemantics sdp_semantics)
1269 : sdp_semantics_(sdp_semantics),
1270 ss_(new rtc::VirtualSocketServer()),
Steve Antonede9ca52017-10-16 13:04:27 -07001271 fss_(new rtc::FirewallSocketServer(ss_.get())),
1272 network_thread_(new rtc::Thread(fss_.get())),
Niels Möller2a707032020-06-16 16:39:13 +02001273 worker_thread_(rtc::Thread::Create()) {
Sebastian Jansson8a793a02018-03-13 15:21:48 +01001274 network_thread_->SetName("PCNetworkThread", this);
1275 worker_thread_->SetName("PCWorkerThread", this);
deadbeef1dcb1642017-03-29 21:08:16 -07001276 RTC_CHECK(network_thread_->Start());
1277 RTC_CHECK(worker_thread_->Start());
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001278 webrtc::metrics::Reset();
deadbeef1dcb1642017-03-29 21:08:16 -07001279 }
1280
Seth Hampson2f0d7022018-02-20 11:54:42 -08001281 ~PeerConnectionIntegrationBaseTest() {
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00001282 // The PeerConnections should be deleted before the TurnCustomizers.
Seth Hampsonaed71642018-06-11 07:41:32 -07001283 // A TurnPort is created with a raw pointer to a TurnCustomizer. The
1284 // TurnPort has the same lifetime as the PeerConnection, so it's expected
1285 // that the TurnCustomizer outlives the life of the PeerConnection or else
1286 // when Send() is called it will hit a seg fault.
deadbeef1dcb1642017-03-29 21:08:16 -07001287 if (caller_) {
1288 caller_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001289 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001290 }
1291 if (callee_) {
1292 callee_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001293 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001294 }
Seth Hampsonaed71642018-06-11 07:41:32 -07001295
1296 // If turn servers were created for the test they need to be destroyed on
1297 // the network thread.
1298 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
1299 turn_servers_.clear();
1300 turn_customizers_.clear();
1301 });
deadbeef1dcb1642017-03-29 21:08:16 -07001302 }
1303
1304 bool SignalingStateStable() {
1305 return caller_->SignalingStateStable() && callee_->SignalingStateStable();
1306 }
1307
deadbeef71452802017-05-07 17:21:01 -07001308 bool DtlsConnected() {
Alex Loiko9289eda2018-11-23 16:18:59 +00001309 // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS
1310 // are connected. This is an important distinction. Once we have separate
1311 // ICE and DTLS state, this check needs to use the DTLS state.
1312 return (callee()->ice_connection_state() ==
1313 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1314 callee()->ice_connection_state() ==
1315 webrtc::PeerConnectionInterface::kIceConnectionCompleted) &&
1316 (caller()->ice_connection_state() ==
1317 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1318 caller()->ice_connection_state() ==
1319 webrtc::PeerConnectionInterface::kIceConnectionCompleted);
deadbeef71452802017-05-07 17:21:01 -07001320 }
1321
Qingsi Wang7685e862018-06-11 20:15:46 -07001322 // When |event_log_factory| is null, the default implementation of the event
1323 // log factory will be used.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001324 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWrapper(
1325 const std::string& debug_name,
Seth Hampson2f0d7022018-02-20 11:54:42 -08001326 const PeerConnectionFactory::Options* options,
1327 const RTCConfiguration* config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001328 webrtc::PeerConnectionDependencies dependencies,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001329 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory,
Johannes Kron3e983682020-03-29 22:17:00 +02001330 bool reset_encoder_factory,
1331 bool reset_decoder_factory) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001332 RTCConfiguration modified_config;
1333 if (config) {
1334 modified_config = *config;
1335 }
Steve Anton3acffc32018-04-12 17:21:03 -07001336 modified_config.sdp_semantics = sdp_semantics_;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001337 if (!dependencies.cert_generator) {
1338 dependencies.cert_generator =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001339 std::make_unique<FakeRTCCertificateGenerator>();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001340 }
1341 std::unique_ptr<PeerConnectionWrapper> client(
1342 new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001343
Niels Möllerf06f9232018-08-07 12:32:18 +02001344 if (!client->Init(options, &modified_config, std::move(dependencies),
1345 network_thread_.get(), worker_thread_.get(),
Niels Möller2a707032020-06-16 16:39:13 +02001346 std::move(event_log_factory), reset_encoder_factory,
Johannes Kron3e983682020-03-29 22:17:00 +02001347 reset_decoder_factory)) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001348 return nullptr;
1349 }
1350 return client;
1351 }
1352
Qingsi Wang7685e862018-06-11 20:15:46 -07001353 std::unique_ptr<PeerConnectionWrapper>
1354 CreatePeerConnectionWrapperWithFakeRtcEventLog(
1355 const std::string& debug_name,
Qingsi Wang7685e862018-06-11 20:15:46 -07001356 const PeerConnectionFactory::Options* options,
1357 const RTCConfiguration* config,
1358 webrtc::PeerConnectionDependencies dependencies) {
1359 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory(
1360 new webrtc::FakeRtcEventLogFactory(rtc::Thread::Current()));
Niels Möller2a707032020-06-16 16:39:13 +02001361 return CreatePeerConnectionWrapper(debug_name, options, config,
1362 std::move(dependencies),
1363 std::move(event_log_factory),
1364 /*reset_encoder_factory=*/false,
1365 /*reset_decoder_factory=*/false);
Qingsi Wang7685e862018-06-11 20:15:46 -07001366 }
1367
deadbeef1dcb1642017-03-29 21:08:16 -07001368 bool CreatePeerConnectionWrappers() {
1369 return CreatePeerConnectionWrappersWithConfig(
1370 PeerConnectionInterface::RTCConfiguration(),
1371 PeerConnectionInterface::RTCConfiguration());
1372 }
1373
Steve Anton3acffc32018-04-12 17:21:03 -07001374 bool CreatePeerConnectionWrappersWithSdpSemantics(
1375 SdpSemantics caller_semantics,
1376 SdpSemantics callee_semantics) {
1377 // Can't specify the sdp_semantics in the passed-in configuration since it
1378 // will be overwritten by CreatePeerConnectionWrapper with whatever is
1379 // stored in sdp_semantics_. So get around this by modifying the instance
1380 // variable before calling CreatePeerConnectionWrapper for the caller and
1381 // callee PeerConnections.
1382 SdpSemantics original_semantics = sdp_semantics_;
1383 sdp_semantics_ = caller_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001384 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001385 "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001386 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001387 /*reset_encoder_factory=*/false,
1388 /*reset_decoder_factory=*/false);
Steve Anton3acffc32018-04-12 17:21:03 -07001389 sdp_semantics_ = callee_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001390 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001391 "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001392 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001393 /*reset_encoder_factory=*/false,
1394 /*reset_decoder_factory=*/false);
Steve Anton3acffc32018-04-12 17:21:03 -07001395 sdp_semantics_ = original_semantics;
1396 return caller_ && callee_;
1397 }
1398
deadbeef1dcb1642017-03-29 21:08:16 -07001399 bool CreatePeerConnectionWrappersWithConfig(
1400 const PeerConnectionInterface::RTCConfiguration& caller_config,
1401 const PeerConnectionInterface::RTCConfiguration& callee_config) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001402 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001403 "Caller", nullptr, &caller_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001404 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001405 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001406 /*reset_decoder_factory=*/false);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001407 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001408 "Callee", nullptr, &callee_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001409 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001410 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001411 /*reset_decoder_factory=*/false);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001412 return caller_ && callee_;
1413 }
1414
1415 bool CreatePeerConnectionWrappersWithConfigAndDeps(
1416 const PeerConnectionInterface::RTCConfiguration& caller_config,
1417 webrtc::PeerConnectionDependencies caller_dependencies,
1418 const PeerConnectionInterface::RTCConfiguration& callee_config,
1419 webrtc::PeerConnectionDependencies callee_dependencies) {
Niels Möller2a707032020-06-16 16:39:13 +02001420 caller_ =
1421 CreatePeerConnectionWrapper("Caller", nullptr, &caller_config,
1422 std::move(caller_dependencies), nullptr,
1423 /*reset_encoder_factory=*/false,
1424 /*reset_decoder_factory=*/false);
1425 callee_ =
1426 CreatePeerConnectionWrapper("Callee", nullptr, &callee_config,
1427 std::move(callee_dependencies), nullptr,
1428 /*reset_encoder_factory=*/false,
1429 /*reset_decoder_factory=*/false);
deadbeef1dcb1642017-03-29 21:08:16 -07001430 return caller_ && callee_;
1431 }
1432
1433 bool CreatePeerConnectionWrappersWithOptions(
1434 const PeerConnectionFactory::Options& caller_options,
1435 const PeerConnectionFactory::Options& callee_options) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001436 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001437 "Caller", &caller_options, nullptr,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001438 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001439 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001440 /*reset_decoder_factory=*/false);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001441 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001442 "Callee", &callee_options, nullptr,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001443 webrtc::PeerConnectionDependencies(nullptr), nullptr,
Niels Möller2a707032020-06-16 16:39:13 +02001444 /*reset_encoder_factory=*/false,
Johannes Kron3e983682020-03-29 22:17:00 +02001445 /*reset_decoder_factory=*/false);
Qingsi Wang7685e862018-06-11 20:15:46 -07001446 return caller_ && callee_;
1447 }
1448
1449 bool CreatePeerConnectionWrappersWithFakeRtcEventLog() {
1450 PeerConnectionInterface::RTCConfiguration default_config;
1451 caller_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001452 "Caller", nullptr, &default_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001453 webrtc::PeerConnectionDependencies(nullptr));
1454 callee_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001455 "Callee", nullptr, &default_config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001456 webrtc::PeerConnectionDependencies(nullptr));
deadbeef1dcb1642017-03-29 21:08:16 -07001457 return caller_ && callee_;
1458 }
1459
Seth Hampson2f0d7022018-02-20 11:54:42 -08001460 std::unique_ptr<PeerConnectionWrapper>
1461 CreatePeerConnectionWrapperWithAlternateKey() {
deadbeef1dcb1642017-03-29 21:08:16 -07001462 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
1463 new FakeRTCCertificateGenerator());
1464 cert_generator->use_alternate_key();
1465
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001466 webrtc::PeerConnectionDependencies dependencies(nullptr);
1467 dependencies.cert_generator = std::move(cert_generator);
Niels Möller2a707032020-06-16 16:39:13 +02001468 return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr,
1469 std::move(dependencies), nullptr,
1470 /*reset_encoder_factory=*/false,
1471 /*reset_decoder_factory=*/false);
Johannes Kron3e983682020-03-29 22:17:00 +02001472 }
1473
1474 bool CreateOneDirectionalPeerConnectionWrappers(bool caller_to_callee) {
1475 caller_ = CreatePeerConnectionWrapper(
1476 "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001477 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001478 /*reset_encoder_factory=*/!caller_to_callee,
1479 /*reset_decoder_factory=*/caller_to_callee);
1480 callee_ = CreatePeerConnectionWrapper(
1481 "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Niels Möller2a707032020-06-16 16:39:13 +02001482 nullptr,
Johannes Kron3e983682020-03-29 22:17:00 +02001483 /*reset_encoder_factory=*/caller_to_callee,
1484 /*reset_decoder_factory=*/!caller_to_callee);
1485 return caller_ && callee_;
deadbeef1dcb1642017-03-29 21:08:16 -07001486 }
1487
Seth Hampsonaed71642018-06-11 07:41:32 -07001488 cricket::TestTurnServer* CreateTurnServer(
1489 rtc::SocketAddress internal_address,
1490 rtc::SocketAddress external_address,
1491 cricket::ProtocolType type = cricket::ProtocolType::PROTO_UDP,
1492 const std::string& common_name = "test turn server") {
1493 rtc::Thread* thread = network_thread();
1494 std::unique_ptr<cricket::TestTurnServer> turn_server =
1495 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnServer>>(
1496 RTC_FROM_HERE,
1497 [thread, internal_address, external_address, type, common_name] {
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001498 return std::make_unique<cricket::TestTurnServer>(
Seth Hampsonaed71642018-06-11 07:41:32 -07001499 thread, internal_address, external_address, type,
1500 /*ignore_bad_certs=*/true, common_name);
1501 });
1502 turn_servers_.push_back(std::move(turn_server));
1503 // Interactions with the turn server should be done on the network thread.
1504 return turn_servers_.back().get();
1505 }
1506
1507 cricket::TestTurnCustomizer* CreateTurnCustomizer() {
1508 std::unique_ptr<cricket::TestTurnCustomizer> turn_customizer =
1509 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnCustomizer>>(
1510 RTC_FROM_HERE,
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001511 [] { return std::make_unique<cricket::TestTurnCustomizer>(); });
Seth Hampsonaed71642018-06-11 07:41:32 -07001512 turn_customizers_.push_back(std::move(turn_customizer));
1513 // Interactions with the turn customizer should be done on the network
1514 // thread.
1515 return turn_customizers_.back().get();
1516 }
1517
1518 // Checks that the function counters for a TestTurnCustomizer are greater than
1519 // 0.
1520 void ExpectTurnCustomizerCountersIncremented(
1521 cricket::TestTurnCustomizer* turn_customizer) {
1522 unsigned int allow_channel_data_counter =
1523 network_thread()->Invoke<unsigned int>(
1524 RTC_FROM_HERE, [turn_customizer] {
1525 return turn_customizer->allow_channel_data_cnt_;
1526 });
1527 EXPECT_GT(allow_channel_data_counter, 0u);
1528 unsigned int modify_counter = network_thread()->Invoke<unsigned int>(
1529 RTC_FROM_HERE,
1530 [turn_customizer] { return turn_customizer->modify_cnt_; });
1531 EXPECT_GT(modify_counter, 0u);
1532 }
1533
deadbeef1dcb1642017-03-29 21:08:16 -07001534 // Once called, SDP blobs and ICE candidates will be automatically signaled
1535 // between PeerConnections.
1536 void ConnectFakeSignaling() {
1537 caller_->set_signaling_message_receiver(callee_.get());
1538 callee_->set_signaling_message_receiver(caller_.get());
1539 }
1540
Steve Antonede9ca52017-10-16 13:04:27 -07001541 // Once called, SDP blobs will be automatically signaled between
1542 // PeerConnections. Note that ICE candidates will not be signaled unless they
1543 // are in the exchanged SDP blobs.
1544 void ConnectFakeSignalingForSdpOnly() {
1545 ConnectFakeSignaling();
1546 SetSignalIceCandidates(false);
1547 }
1548
deadbeef1dcb1642017-03-29 21:08:16 -07001549 void SetSignalingDelayMs(int delay_ms) {
1550 caller_->set_signaling_delay_ms(delay_ms);
1551 callee_->set_signaling_delay_ms(delay_ms);
1552 }
1553
Steve Antonede9ca52017-10-16 13:04:27 -07001554 void SetSignalIceCandidates(bool signal) {
1555 caller_->set_signal_ice_candidates(signal);
1556 callee_->set_signal_ice_candidates(signal);
1557 }
1558
deadbeef1dcb1642017-03-29 21:08:16 -07001559 // Messages may get lost on the unreliable DataChannel, so we send multiple
1560 // times to avoid test flakiness.
1561 void SendRtpDataWithRetries(webrtc::DataChannelInterface* dc,
1562 const std::string& data,
1563 int retries) {
1564 for (int i = 0; i < retries; ++i) {
1565 dc->Send(DataBuffer(data));
1566 }
1567 }
1568
1569 rtc::Thread* network_thread() { return network_thread_.get(); }
1570
1571 rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); }
1572
1573 PeerConnectionWrapper* caller() { return caller_.get(); }
1574
1575 // Set the |caller_| to the |wrapper| passed in and return the
1576 // original |caller_|.
1577 PeerConnectionWrapper* SetCallerPcWrapperAndReturnCurrent(
1578 PeerConnectionWrapper* wrapper) {
1579 PeerConnectionWrapper* old = caller_.release();
1580 caller_.reset(wrapper);
1581 return old;
1582 }
1583
1584 PeerConnectionWrapper* callee() { return callee_.get(); }
1585
1586 // Set the |callee_| to the |wrapper| passed in and return the
1587 // original |callee_|.
1588 PeerConnectionWrapper* SetCalleePcWrapperAndReturnCurrent(
1589 PeerConnectionWrapper* wrapper) {
1590 PeerConnectionWrapper* old = callee_.release();
1591 callee_.reset(wrapper);
1592 return old;
1593 }
1594
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001595 void SetPortAllocatorFlags(uint32_t caller_flags, uint32_t callee_flags) {
Niels Möller4bab23f2021-01-18 09:24:33 +01001596 network_thread()->Invoke<void>(RTC_FROM_HERE, [this, caller_flags] {
1597 caller()->port_allocator()->set_flags(caller_flags);
1598 });
1599 network_thread()->Invoke<void>(RTC_FROM_HERE, [this, callee_flags] {
1600 callee()->port_allocator()->set_flags(callee_flags);
1601 });
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001602 }
1603
Steve Antonede9ca52017-10-16 13:04:27 -07001604 rtc::FirewallSocketServer* firewall() const { return fss_.get(); }
1605
Seth Hampson2f0d7022018-02-20 11:54:42 -08001606 // Expects the provided number of new frames to be received within
1607 // kMaxWaitForFramesMs. The new expected frames are specified in
1608 // |media_expectations|. Returns false if any of the expectations were
1609 // not met.
1610 bool ExpectNewFrames(const MediaExpectations& media_expectations) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02001611 // Make sure there are no bogus tracks confusing the issue.
1612 caller()->RemoveUnusedVideoRenderers();
1613 callee()->RemoveUnusedVideoRenderers();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001614 // First initialize the expected frame counts based upon the current
1615 // frame count.
1616 int total_caller_audio_frames_expected = caller()->audio_frames_received();
1617 if (media_expectations.caller_audio_expectation_ ==
1618 MediaExpectations::kExpectSomeFrames) {
1619 total_caller_audio_frames_expected +=
1620 media_expectations.caller_audio_frames_expected_;
1621 }
1622 int total_caller_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001623 caller()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001624 if (media_expectations.caller_video_expectation_ ==
1625 MediaExpectations::kExpectSomeFrames) {
1626 total_caller_video_frames_expected +=
1627 media_expectations.caller_video_frames_expected_;
1628 }
1629 int total_callee_audio_frames_expected = callee()->audio_frames_received();
1630 if (media_expectations.callee_audio_expectation_ ==
1631 MediaExpectations::kExpectSomeFrames) {
1632 total_callee_audio_frames_expected +=
1633 media_expectations.callee_audio_frames_expected_;
1634 }
1635 int total_callee_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001636 callee()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001637 if (media_expectations.callee_video_expectation_ ==
1638 MediaExpectations::kExpectSomeFrames) {
1639 total_callee_video_frames_expected +=
1640 media_expectations.callee_video_frames_expected_;
1641 }
deadbeef1dcb1642017-03-29 21:08:16 -07001642
Seth Hampson2f0d7022018-02-20 11:54:42 -08001643 // Wait for the expected frames.
deadbeef1dcb1642017-03-29 21:08:16 -07001644 EXPECT_TRUE_WAIT(caller()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001645 total_caller_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001646 caller()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001647 total_caller_video_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001648 callee()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001649 total_callee_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001650 callee()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001651 total_callee_video_frames_expected,
1652 kMaxWaitForFramesMs);
1653 bool expectations_correct =
1654 caller()->audio_frames_received() >=
1655 total_caller_audio_frames_expected &&
1656 caller()->min_video_frames_received_per_track() >=
1657 total_caller_video_frames_expected &&
1658 callee()->audio_frames_received() >=
1659 total_callee_audio_frames_expected &&
1660 callee()->min_video_frames_received_per_track() >=
1661 total_callee_video_frames_expected;
deadbeef1dcb1642017-03-29 21:08:16 -07001662
Seth Hampson2f0d7022018-02-20 11:54:42 -08001663 // After the combined wait, print out a more detailed message upon
1664 // failure.
deadbeef1dcb1642017-03-29 21:08:16 -07001665 EXPECT_GE(caller()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001666 total_caller_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001667 EXPECT_GE(caller()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001668 total_caller_video_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001669 EXPECT_GE(callee()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001670 total_callee_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001671 EXPECT_GE(callee()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001672 total_callee_video_frames_expected);
1673
1674 // We want to make sure nothing unexpected was received.
1675 if (media_expectations.caller_audio_expectation_ ==
1676 MediaExpectations::kExpectNoFrames) {
1677 EXPECT_EQ(caller()->audio_frames_received(),
1678 total_caller_audio_frames_expected);
1679 if (caller()->audio_frames_received() !=
1680 total_caller_audio_frames_expected) {
1681 expectations_correct = false;
1682 }
1683 }
1684 if (media_expectations.caller_video_expectation_ ==
1685 MediaExpectations::kExpectNoFrames) {
1686 EXPECT_EQ(caller()->min_video_frames_received_per_track(),
1687 total_caller_video_frames_expected);
1688 if (caller()->min_video_frames_received_per_track() !=
1689 total_caller_video_frames_expected) {
1690 expectations_correct = false;
1691 }
1692 }
1693 if (media_expectations.callee_audio_expectation_ ==
1694 MediaExpectations::kExpectNoFrames) {
1695 EXPECT_EQ(callee()->audio_frames_received(),
1696 total_callee_audio_frames_expected);
1697 if (callee()->audio_frames_received() !=
1698 total_callee_audio_frames_expected) {
1699 expectations_correct = false;
1700 }
1701 }
1702 if (media_expectations.callee_video_expectation_ ==
1703 MediaExpectations::kExpectNoFrames) {
1704 EXPECT_EQ(callee()->min_video_frames_received_per_track(),
1705 total_callee_video_frames_expected);
1706 if (callee()->min_video_frames_received_per_track() !=
1707 total_callee_video_frames_expected) {
1708 expectations_correct = false;
1709 }
1710 }
1711 return expectations_correct;
deadbeef1dcb1642017-03-29 21:08:16 -07001712 }
1713
Steve Antond91969e2019-05-30 12:27:03 -07001714 void ClosePeerConnections() {
1715 caller()->pc()->Close();
1716 callee()->pc()->Close();
1717 }
1718
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001719 void TestNegotiatedCipherSuite(
1720 const PeerConnectionFactory::Options& caller_options,
1721 const PeerConnectionFactory::Options& callee_options,
1722 int expected_cipher_suite) {
deadbeef1dcb1642017-03-29 21:08:16 -07001723 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options,
1724 callee_options));
deadbeef1dcb1642017-03-29 21:08:16 -07001725 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001726 caller()->AddAudioVideoTracks();
1727 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001728 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001729 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001730 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite),
deadbeefd8ad7882017-04-18 16:01:17 -07001731 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001732 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001733 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1734 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1735 expected_cipher_suite));
deadbeef1dcb1642017-03-29 21:08:16 -07001736 }
1737
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001738 void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
1739 bool remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001740 bool aes_ctr_enabled,
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001741 int expected_cipher_suite) {
1742 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001743 caller_options.crypto_options.srtp.enable_gcm_crypto_suites =
1744 local_gcm_enabled;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001745 caller_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher =
1746 aes_ctr_enabled;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001747 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001748 callee_options.crypto_options.srtp.enable_gcm_crypto_suites =
1749 remote_gcm_enabled;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001750 callee_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher =
1751 aes_ctr_enabled;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001752 TestNegotiatedCipherSuite(caller_options, callee_options,
1753 expected_cipher_suite);
1754 }
1755
Seth Hampson2f0d7022018-02-20 11:54:42 -08001756 protected:
Steve Anton3acffc32018-04-12 17:21:03 -07001757 SdpSemantics sdp_semantics_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001758
deadbeef1dcb1642017-03-29 21:08:16 -07001759 private:
1760 // |ss_| is used by |network_thread_| so it must be destroyed later.
deadbeef1dcb1642017-03-29 21:08:16 -07001761 std::unique_ptr<rtc::VirtualSocketServer> ss_;
Steve Antonede9ca52017-10-16 13:04:27 -07001762 std::unique_ptr<rtc::FirewallSocketServer> fss_;
deadbeef1dcb1642017-03-29 21:08:16 -07001763 // |network_thread_| and |worker_thread_| are used by both
1764 // |caller_| and |callee_| so they must be destroyed
1765 // later.
1766 std::unique_ptr<rtc::Thread> network_thread_;
1767 std::unique_ptr<rtc::Thread> worker_thread_;
Seth Hampsonaed71642018-06-11 07:41:32 -07001768 // The turn servers and turn customizers should be accessed & deleted on the
1769 // network thread to avoid a race with the socket read/write that occurs
1770 // on the network thread.
1771 std::vector<std::unique_ptr<cricket::TestTurnServer>> turn_servers_;
1772 std::vector<std::unique_ptr<cricket::TestTurnCustomizer>> turn_customizers_;
deadbeef1dcb1642017-03-29 21:08:16 -07001773 std::unique_ptr<PeerConnectionWrapper> caller_;
1774 std::unique_ptr<PeerConnectionWrapper> callee_;
1775};
1776
Seth Hampson2f0d7022018-02-20 11:54:42 -08001777class PeerConnectionIntegrationTest
1778 : public PeerConnectionIntegrationBaseTest,
1779 public ::testing::WithParamInterface<SdpSemantics> {
1780 protected:
1781 PeerConnectionIntegrationTest()
1782 : PeerConnectionIntegrationBaseTest(GetParam()) {}
1783};
1784
Yves Gerey100fe632020-01-17 19:15:53 +01001785// Fake clock must be set before threads are started to prevent race on
1786// Set/GetClockForTesting().
1787// To achieve that, multiple inheritance is used as a mixin pattern
1788// where order of construction is finely controlled.
1789// This also ensures peerconnection is closed before switching back to non-fake
1790// clock, avoiding other races and DCHECK failures such as in rtp_sender.cc.
1791class FakeClockForTest : public rtc::ScopedFakeClock {
1792 protected:
1793 FakeClockForTest() {
1794 // Some things use a time of "0" as a special value, so we need to start out
1795 // the fake clock at a nonzero time.
1796 // TODO(deadbeef): Fix this.
Danil Chapovalov0c626af2020-02-10 11:16:00 +01001797 AdvanceTime(webrtc::TimeDelta::Seconds(1));
Yves Gerey100fe632020-01-17 19:15:53 +01001798 }
1799
1800 // Explicit handle.
1801 ScopedFakeClock& FakeClock() { return *this; }
1802};
1803
1804// Ensure FakeClockForTest is constructed first (see class for rationale).
1805class PeerConnectionIntegrationTestWithFakeClock
1806 : public FakeClockForTest,
1807 public PeerConnectionIntegrationTest {};
1808
Seth Hampson2f0d7022018-02-20 11:54:42 -08001809class PeerConnectionIntegrationTestPlanB
1810 : public PeerConnectionIntegrationBaseTest {
1811 protected:
1812 PeerConnectionIntegrationTestPlanB()
1813 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
1814};
1815
1816class PeerConnectionIntegrationTestUnifiedPlan
1817 : public PeerConnectionIntegrationBaseTest {
1818 protected:
1819 PeerConnectionIntegrationTestUnifiedPlan()
1820 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
1821};
1822
deadbeef1dcb1642017-03-29 21:08:16 -07001823// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
1824// includes testing that the callback is invoked if an observer is connected
1825// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001826TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001827 RtpReceiverObserverOnFirstPacketReceived) {
1828 ASSERT_TRUE(CreatePeerConnectionWrappers());
1829 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001830 caller()->AddAudioVideoTracks();
1831 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001832 // Start offer/answer exchange and wait for it to complete.
1833 caller()->CreateAndSetAndSignalOffer();
1834 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1835 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001836 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1837 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001838 // Wait for all "first packet received" callbacks to be fired.
1839 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -08001840 absl::c_all_of(caller()->rtp_receiver_observers(),
1841 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1842 return o->first_packet_received();
1843 }),
deadbeef1dcb1642017-03-29 21:08:16 -07001844 kMaxWaitForFramesMs);
1845 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -08001846 absl::c_all_of(callee()->rtp_receiver_observers(),
1847 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1848 return o->first_packet_received();
1849 }),
deadbeef1dcb1642017-03-29 21:08:16 -07001850 kMaxWaitForFramesMs);
1851 // If new observers are set after the first packet was already received, the
1852 // callback should still be invoked.
1853 caller()->ResetRtpReceiverObservers();
1854 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001855 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1856 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001857 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -08001858 absl::c_all_of(caller()->rtp_receiver_observers(),
1859 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1860 return o->first_packet_received();
1861 }));
deadbeef1dcb1642017-03-29 21:08:16 -07001862 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -08001863 absl::c_all_of(callee()->rtp_receiver_observers(),
1864 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1865 return o->first_packet_received();
1866 }));
deadbeef1dcb1642017-03-29 21:08:16 -07001867}
1868
1869class DummyDtmfObserver : public DtmfSenderObserverInterface {
1870 public:
1871 DummyDtmfObserver() : completed_(false) {}
1872
1873 // Implements DtmfSenderObserverInterface.
1874 void OnToneChange(const std::string& tone) override {
1875 tones_.push_back(tone);
1876 if (tone.empty()) {
1877 completed_ = true;
1878 }
1879 }
1880
1881 const std::vector<std::string>& tones() const { return tones_; }
1882 bool completed() const { return completed_; }
1883
1884 private:
1885 bool completed_;
1886 std::vector<std::string> tones_;
1887};
1888
1889// Assumes |sender| already has an audio track added and the offer/answer
1890// exchange is done.
1891void TestDtmfFromSenderToReceiver(PeerConnectionWrapper* sender,
1892 PeerConnectionWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -08001893 // We should be able to get a DTMF sender from the local sender.
1894 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
1895 sender->pc()->GetSenders().at(0)->GetDtmfSender();
1896 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -07001897 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -07001898 dtmf_sender->RegisterObserver(&observer);
1899
1900 // Test the DtmfSender object just created.
1901 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
1902 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
1903
1904 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
1905 std::vector<std::string> tones = {"1", "a", ""};
1906 EXPECT_EQ(tones, observer.tones());
1907 dtmf_sender->UnregisterObserver();
1908 // TODO(deadbeef): Verify the tones were actually received end-to-end.
1909}
1910
1911// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
1912// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001913TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -07001914 ASSERT_TRUE(CreatePeerConnectionWrappers());
1915 ConnectFakeSignaling();
1916 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -08001917 caller()->AddAudioTrack();
1918 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001919 caller()->CreateAndSetAndSignalOffer();
1920 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -07001921 // DTLS must finish before the DTMF sender can be used reliably.
1922 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001923 TestDtmfFromSenderToReceiver(caller(), callee());
1924 TestDtmfFromSenderToReceiver(callee(), caller());
1925}
1926
1927// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
1928// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001929TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -07001930 ASSERT_TRUE(CreatePeerConnectionWrappers());
1931 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +01001932
deadbeef1dcb1642017-03-29 21:08:16 -07001933 // Do normal offer/answer and wait for some frames to be received in each
1934 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001935 caller()->AddAudioVideoTracks();
1936 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001937 caller()->CreateAndSetAndSignalOffer();
1938 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001939 MediaExpectations media_expectations;
1940 media_expectations.ExpectBidirectionalAudioAndVideo();
1941 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Ying Wangef3998f2019-12-09 13:06:53 +01001942 EXPECT_METRIC_LE(
1943 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1944 webrtc::kEnumCounterKeyProtocolDtls));
1945 EXPECT_METRIC_EQ(
1946 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1947 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -07001948}
1949
1950// Uses SDES instead of DTLS for key agreement.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001951TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
deadbeef1dcb1642017-03-29 21:08:16 -07001952 PeerConnectionInterface::RTCConfiguration sdes_config;
1953 sdes_config.enable_dtls_srtp.emplace(false);
1954 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
1955 ConnectFakeSignaling();
1956
1957 // Do normal offer/answer and wait for some frames to be received in each
1958 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001959 caller()->AddAudioVideoTracks();
1960 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001961 caller()->CreateAndSetAndSignalOffer();
1962 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001963 MediaExpectations media_expectations;
1964 media_expectations.ExpectBidirectionalAudioAndVideo();
1965 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Ying Wangef3998f2019-12-09 13:06:53 +01001966 EXPECT_METRIC_LE(
1967 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1968 webrtc::kEnumCounterKeyProtocolSdes));
1969 EXPECT_METRIC_EQ(
1970 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1971 webrtc::kEnumCounterKeyProtocolDtls));
deadbeef1dcb1642017-03-29 21:08:16 -07001972}
1973
Steve Anton9a44b2d2019-07-12 12:58:30 -07001974// Basic end-to-end test specifying the |enable_encrypted_rtp_header_extensions|
1975// option to offer encrypted versions of all header extensions alongside the
1976// unencrypted versions.
1977TEST_P(PeerConnectionIntegrationTest,
1978 EndToEndCallWithEncryptedRtpHeaderExtensions) {
1979 CryptoOptions crypto_options;
1980 crypto_options.srtp.enable_encrypted_rtp_header_extensions = true;
1981 PeerConnectionInterface::RTCConfiguration config;
1982 config.crypto_options = crypto_options;
1983 // Note: This allows offering >14 RTP header extensions.
1984 config.offer_extmap_allow_mixed = true;
1985 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
1986 ConnectFakeSignaling();
1987
1988 // Do normal offer/answer and wait for some frames to be received in each
1989 // direction.
1990 caller()->AddAudioVideoTracks();
1991 callee()->AddAudioVideoTracks();
1992 caller()->CreateAndSetAndSignalOffer();
1993 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1994 MediaExpectations media_expectations;
1995 media_expectations.ExpectBidirectionalAudioAndVideo();
1996 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1997}
1998
deadbeef1dcb1642017-03-29 21:08:16 -07001999// This test sets up a call between two parties with a source resolution of
2000// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002001TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002002 Send1280By720ResolutionAndReceive16To9AspectRatio) {
2003 ASSERT_TRUE(CreatePeerConnectionWrappers());
2004 ConnectFakeSignaling();
2005
Niels Möller5c7efe72018-05-11 10:34:46 +02002006 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
2007 webrtc::FakePeriodicVideoSource::Config config;
2008 config.width = 1280;
2009 config.height = 720;
Johannes Kron965e7942018-09-13 15:36:20 +02002010 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +02002011 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
2012 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -07002013
2014 // Do normal offer/answer and wait for at least one frame to be received in
2015 // each direction.
2016 caller()->CreateAndSetAndSignalOffer();
2017 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2018 callee()->min_video_frames_received_per_track() > 0,
2019 kMaxWaitForFramesMs);
2020
2021 // Check rendered aspect ratio.
2022 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
2023 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
2024 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
2025 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
2026}
2027
2028// This test sets up an one-way call, with media only from caller to
2029// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002030TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -07002031 ASSERT_TRUE(CreatePeerConnectionWrappers());
2032 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002033 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002034 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002035 MediaExpectations media_expectations;
2036 media_expectations.CalleeExpectsSomeAudioAndVideo();
2037 media_expectations.CallerExpectsNoAudio();
2038 media_expectations.CallerExpectsNoVideo();
2039 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002040}
2041
Johannes Kron3e983682020-03-29 22:17:00 +02002042// Tests that send only works without the caller having a decoder factory and
2043// the callee having an encoder factory.
2044TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSendOnlyVideo) {
2045 ASSERT_TRUE(
2046 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
2047 ConnectFakeSignaling();
2048 // Add one-directional video, from caller to callee.
2049 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2050 caller()->CreateLocalVideoTrack();
2051 caller()->AddTrack(caller_track);
2052 PeerConnectionInterface::RTCOfferAnswerOptions options;
2053 options.offer_to_receive_video = 0;
2054 caller()->SetOfferAnswerOptions(options);
2055 caller()->CreateAndSetAndSignalOffer();
2056 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2057 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2058
2059 // Expect video to be received in one direction.
2060 MediaExpectations media_expectations;
2061 media_expectations.CallerExpectsNoVideo();
2062 media_expectations.CalleeExpectsSomeVideo();
2063
2064 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2065}
2066
2067// Tests that receive only works without the caller having an encoder factory
2068// and the callee having a decoder factory.
2069TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithReceiveOnlyVideo) {
2070 ASSERT_TRUE(
2071 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/false));
2072 ConnectFakeSignaling();
2073 // Add one-directional video, from callee to caller.
2074 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2075 callee()->CreateLocalVideoTrack();
2076 callee()->AddTrack(callee_track);
2077 PeerConnectionInterface::RTCOfferAnswerOptions options;
2078 options.offer_to_receive_video = 1;
2079 caller()->SetOfferAnswerOptions(options);
2080 caller()->CreateAndSetAndSignalOffer();
2081 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2082 ASSERT_EQ(caller()->pc()->GetReceivers().size(), 1u);
2083
2084 // Expect video to be received in one direction.
2085 MediaExpectations media_expectations;
2086 media_expectations.CallerExpectsSomeVideo();
2087 media_expectations.CalleeExpectsNoVideo();
2088
2089 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2090}
2091
2092TEST_P(PeerConnectionIntegrationTest,
2093 EndToEndCallAddReceiveVideoToSendOnlyCall) {
2094 ASSERT_TRUE(CreatePeerConnectionWrappers());
2095 ConnectFakeSignaling();
2096 // Add one-directional video, from caller to callee.
2097 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2098 caller()->CreateLocalVideoTrack();
2099 caller()->AddTrack(caller_track);
2100 caller()->CreateAndSetAndSignalOffer();
2101 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2102
2103 // Add receive video.
2104 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2105 callee()->CreateLocalVideoTrack();
2106 callee()->AddTrack(callee_track);
2107 caller()->CreateAndSetAndSignalOffer();
2108 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2109
2110 // Ensure that video frames are received end-to-end.
2111 MediaExpectations media_expectations;
2112 media_expectations.ExpectBidirectionalVideo();
2113 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2114}
2115
2116TEST_P(PeerConnectionIntegrationTest,
2117 EndToEndCallAddSendVideoToReceiveOnlyCall) {
2118 ASSERT_TRUE(CreatePeerConnectionWrappers());
2119 ConnectFakeSignaling();
2120 // Add one-directional video, from callee to caller.
2121 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2122 callee()->CreateLocalVideoTrack();
2123 callee()->AddTrack(callee_track);
2124 caller()->CreateAndSetAndSignalOffer();
2125 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2126
2127 // Add send video.
2128 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2129 caller()->CreateLocalVideoTrack();
2130 caller()->AddTrack(caller_track);
2131 caller()->CreateAndSetAndSignalOffer();
2132 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2133
2134 // Expect video to be received in one direction.
2135 MediaExpectations media_expectations;
2136 media_expectations.ExpectBidirectionalVideo();
2137 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2138}
2139
2140TEST_P(PeerConnectionIntegrationTest,
2141 EndToEndCallRemoveReceiveVideoFromSendReceiveCall) {
2142 ASSERT_TRUE(CreatePeerConnectionWrappers());
2143 ConnectFakeSignaling();
2144 // Add send video, from caller to callee.
2145 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2146 caller()->CreateLocalVideoTrack();
2147 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
2148 caller()->AddTrack(caller_track);
2149 // Add receive video, from callee to caller.
2150 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2151 callee()->CreateLocalVideoTrack();
2152
2153 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
2154 callee()->AddTrack(callee_track);
2155 caller()->CreateAndSetAndSignalOffer();
2156 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2157
2158 // Remove receive video (i.e., callee sender track).
2159 callee()->pc()->RemoveTrack(callee_sender);
2160
2161 caller()->CreateAndSetAndSignalOffer();
2162 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2163
2164 // Expect one-directional video.
2165 MediaExpectations media_expectations;
2166 media_expectations.CallerExpectsNoVideo();
2167 media_expectations.CalleeExpectsSomeVideo();
2168
2169 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2170}
2171
2172TEST_P(PeerConnectionIntegrationTest,
2173 EndToEndCallRemoveSendVideoFromSendReceiveCall) {
2174 ASSERT_TRUE(CreatePeerConnectionWrappers());
2175 ConnectFakeSignaling();
2176 // Add send video, from caller to callee.
2177 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
2178 caller()->CreateLocalVideoTrack();
2179 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
2180 caller()->AddTrack(caller_track);
2181 // Add receive video, from callee to caller.
2182 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2183 callee()->CreateLocalVideoTrack();
2184
2185 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
2186 callee()->AddTrack(callee_track);
2187 caller()->CreateAndSetAndSignalOffer();
2188 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2189
2190 // Remove send video (i.e., caller sender track).
2191 caller()->pc()->RemoveTrack(caller_sender);
2192
2193 caller()->CreateAndSetAndSignalOffer();
2194 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2195
2196 // Expect one-directional video.
2197 MediaExpectations media_expectations;
2198 media_expectations.CalleeExpectsNoVideo();
2199 media_expectations.CallerExpectsSomeVideo();
2200
2201 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2202}
2203
deadbeef1dcb1642017-03-29 21:08:16 -07002204// This test sets up a audio call initially, with the callee rejecting video
2205// initially. Then later the callee decides to upgrade to audio/video, and
2206// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002207TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -07002208 ASSERT_TRUE(CreatePeerConnectionWrappers());
2209 ConnectFakeSignaling();
2210 // Initially, offer an audio/video stream from the caller, but refuse to
2211 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -08002212 caller()->AddAudioVideoTracks();
2213 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002214 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2215 PeerConnectionInterface::RTCOfferAnswerOptions options;
2216 options.offer_to_receive_video = 0;
2217 callee()->SetOfferAnswerOptions(options);
2218 } else {
2219 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002220 callee()
2221 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2222 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002223 });
2224 }
deadbeef1dcb1642017-03-29 21:08:16 -07002225 // Do offer/answer and make sure audio is still received end-to-end.
2226 caller()->CreateAndSetAndSignalOffer();
2227 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002228 {
2229 MediaExpectations media_expectations;
2230 media_expectations.ExpectBidirectionalAudio();
2231 media_expectations.ExpectNoVideo();
2232 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2233 }
deadbeef1dcb1642017-03-29 21:08:16 -07002234 // Sanity check that the callee's description has a rejected video section.
2235 ASSERT_NE(nullptr, callee()->pc()->local_description());
2236 const ContentInfo* callee_video_content =
2237 GetFirstVideoContent(callee()->pc()->local_description()->description());
2238 ASSERT_NE(nullptr, callee_video_content);
2239 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002240
deadbeef1dcb1642017-03-29 21:08:16 -07002241 // Now negotiate with video and ensure negotiation succeeds, with video
2242 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -08002243 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002244 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2245 PeerConnectionInterface::RTCOfferAnswerOptions options;
2246 options.offer_to_receive_video = 1;
2247 callee()->SetOfferAnswerOptions(options);
2248 } else {
2249 callee()->SetRemoteOfferHandler(nullptr);
2250 caller()->SetRemoteOfferHandler([this] {
2251 // The caller creates a new transceiver to receive video on when receiving
2252 // the offer, but by default it is send only.
2253 auto transceivers = caller()->pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +02002254 ASSERT_EQ(2U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002255 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
Harald Alvestrand6060df52020-08-11 09:54:02 +02002256 transceivers[1]->receiver()->media_type());
2257 transceivers[1]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
2258 transceivers[1]->SetDirectionWithError(
2259 RtpTransceiverDirection::kSendRecv);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002260 });
2261 }
deadbeef1dcb1642017-03-29 21:08:16 -07002262 callee()->CreateAndSetAndSignalOffer();
2263 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002264 {
2265 // Expect additional audio frames to be received after the upgrade.
2266 MediaExpectations media_expectations;
2267 media_expectations.ExpectBidirectionalAudioAndVideo();
2268 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2269 }
deadbeef1dcb1642017-03-29 21:08:16 -07002270}
2271
deadbeef4389b4d2017-09-07 09:07:36 -07002272// Simpler than the above test; just add an audio track to an established
2273// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002274TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -07002275 ASSERT_TRUE(CreatePeerConnectionWrappers());
2276 ConnectFakeSignaling();
2277 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -08002278 caller()->AddVideoTrack();
2279 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07002280 caller()->CreateAndSetAndSignalOffer();
2281 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2282 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08002283 caller()->AddAudioTrack();
2284 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07002285 caller()->CreateAndSetAndSignalOffer();
2286 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2287 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002288 MediaExpectations media_expectations;
2289 media_expectations.ExpectBidirectionalAudioAndVideo();
2290 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -07002291}
2292
deadbeef1dcb1642017-03-29 21:08:16 -07002293// This test sets up a call that's transferred to a new caller with a different
2294// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002295TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -07002296 ASSERT_TRUE(CreatePeerConnectionWrappers());
2297 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002298 caller()->AddAudioVideoTracks();
2299 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002300 caller()->CreateAndSetAndSignalOffer();
2301 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2302
2303 // Keep the original peer around which will still send packets to the
2304 // receiving client. These SRTP packets will be dropped.
2305 std::unique_ptr<PeerConnectionWrapper> original_peer(
2306 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002307 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07002308 // TODO(deadbeef): Why do we call Close here? That goes against the comment
2309 // directly above.
2310 original_peer->pc()->Close();
2311
2312 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002313 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002314 caller()->CreateAndSetAndSignalOffer();
2315 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2316 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002317 MediaExpectations media_expectations;
2318 media_expectations.ExpectBidirectionalAudioAndVideo();
2319 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002320}
2321
2322// This test sets up a call that's transferred to a new callee with a different
2323// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002324TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -07002325 ASSERT_TRUE(CreatePeerConnectionWrappers());
2326 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002327 caller()->AddAudioVideoTracks();
2328 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002329 caller()->CreateAndSetAndSignalOffer();
2330 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2331
2332 // Keep the original peer around which will still send packets to the
2333 // receiving client. These SRTP packets will be dropped.
2334 std::unique_ptr<PeerConnectionWrapper> original_peer(
2335 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002336 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07002337 // TODO(deadbeef): Why do we call Close here? That goes against the comment
2338 // directly above.
2339 original_peer->pc()->Close();
2340
2341 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002342 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002343 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2344 caller()->CreateAndSetAndSignalOffer();
2345 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2346 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002347 MediaExpectations media_expectations;
2348 media_expectations.ExpectBidirectionalAudioAndVideo();
2349 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002350}
2351
2352// This test sets up a non-bundled call and negotiates bundling at the same
2353// time as starting an ICE restart. When bundling is in effect in the restart,
2354// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002355TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -07002356 ASSERT_TRUE(CreatePeerConnectionWrappers());
2357 ConnectFakeSignaling();
2358
Steve Anton15324772018-01-16 10:26:49 -08002359 caller()->AddAudioVideoTracks();
2360 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002361 // Remove the bundle group from the SDP received by the callee.
2362 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2363 desc->RemoveGroupByName("BUNDLE");
2364 });
2365 caller()->CreateAndSetAndSignalOffer();
2366 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002367 {
2368 MediaExpectations media_expectations;
2369 media_expectations.ExpectBidirectionalAudioAndVideo();
2370 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2371 }
deadbeef1dcb1642017-03-29 21:08:16 -07002372 // Now stop removing the BUNDLE group, and trigger an ICE restart.
2373 callee()->SetReceivedSdpMunger(nullptr);
2374 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2375 caller()->CreateAndSetAndSignalOffer();
2376 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2377
2378 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002379 {
2380 MediaExpectations media_expectations;
2381 media_expectations.ExpectBidirectionalAudioAndVideo();
2382 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2383 }
deadbeef1dcb1642017-03-29 21:08:16 -07002384}
2385
2386// Test CVO (Coordination of Video Orientation). If a video source is rotated
2387// and both peers support the CVO RTP header extension, the actual video frames
2388// don't need to be encoded in different resolutions, since the rotation is
2389// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002390TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002391 ASSERT_TRUE(CreatePeerConnectionWrappers());
2392 ConnectFakeSignaling();
2393 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002394 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002395 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002396 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002397 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2398
2399 // Wait for video frames to be received by both sides.
2400 caller()->CreateAndSetAndSignalOffer();
2401 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2402 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2403 callee()->min_video_frames_received_per_track() > 0,
2404 kMaxWaitForFramesMs);
2405
2406 // Ensure that the aspect ratio is unmodified.
2407 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2408 // not just assumed.
2409 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
2410 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
2411 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
2412 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
2413 // Ensure that the CVO bits were surfaced to the renderer.
2414 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
2415 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
2416}
2417
2418// Test that when the CVO extension isn't supported, video is rotated the
2419// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002420TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002421 ASSERT_TRUE(CreatePeerConnectionWrappers());
2422 ConnectFakeSignaling();
2423 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002424 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002425 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002426 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002427 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2428
2429 // Remove the CVO extension from the offered SDP.
2430 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2431 cricket::VideoContentDescription* video =
2432 GetFirstVideoContentDescription(desc);
2433 video->ClearRtpHeaderExtensions();
2434 });
2435 // Wait for video frames to be received by both sides.
2436 caller()->CreateAndSetAndSignalOffer();
2437 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2438 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2439 callee()->min_video_frames_received_per_track() > 0,
2440 kMaxWaitForFramesMs);
2441
2442 // Expect that the aspect ratio is inversed to account for the 90/270 degree
2443 // rotation.
2444 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2445 // not just assumed.
2446 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
2447 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
2448 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
2449 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
2450 // Expect that each endpoint is unaware of the rotation of the other endpoint.
2451 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
2452 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
2453}
2454
deadbeef1dcb1642017-03-29 21:08:16 -07002455// Test that if the answerer rejects the audio m= section, no audio is sent or
2456// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002457TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002458 ASSERT_TRUE(CreatePeerConnectionWrappers());
2459 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002460 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002461 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2462 // Only add video track for callee, and set offer_to_receive_audio to 0, so
2463 // it will reject the audio m= section completely.
2464 PeerConnectionInterface::RTCOfferAnswerOptions options;
2465 options.offer_to_receive_audio = 0;
2466 callee()->SetOfferAnswerOptions(options);
2467 } else {
2468 // Stopping the audio RtpTransceiver will cause the media section to be
2469 // rejected in the answer.
2470 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002471 callee()
2472 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
2473 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002474 });
2475 }
Steve Anton15324772018-01-16 10:26:49 -08002476 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002477 // Do offer/answer and wait for successful end-to-end video frames.
2478 caller()->CreateAndSetAndSignalOffer();
2479 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002480 MediaExpectations media_expectations;
2481 media_expectations.ExpectBidirectionalVideo();
2482 media_expectations.ExpectNoAudio();
2483 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2484
deadbeef1dcb1642017-03-29 21:08:16 -07002485 // Sanity check that the callee's description has a rejected audio section.
2486 ASSERT_NE(nullptr, callee()->pc()->local_description());
2487 const ContentInfo* callee_audio_content =
2488 GetFirstAudioContent(callee()->pc()->local_description()->description());
2489 ASSERT_NE(nullptr, callee_audio_content);
2490 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002491 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002492 // The caller's transceiver should have stopped after receiving the answer,
2493 // and thus no longer listed in transceivers.
2494 EXPECT_EQ(nullptr,
2495 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002496 }
deadbeef1dcb1642017-03-29 21:08:16 -07002497}
2498
2499// Test that if the answerer rejects the video m= section, no video is sent or
2500// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002501TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002502 ASSERT_TRUE(CreatePeerConnectionWrappers());
2503 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002504 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002505 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2506 // Only add audio track for callee, and set offer_to_receive_video to 0, so
2507 // it will reject the video m= section completely.
2508 PeerConnectionInterface::RTCOfferAnswerOptions options;
2509 options.offer_to_receive_video = 0;
2510 callee()->SetOfferAnswerOptions(options);
2511 } else {
2512 // Stopping the video RtpTransceiver will cause the media section to be
2513 // rejected in the answer.
2514 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002515 callee()
2516 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2517 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002518 });
2519 }
Steve Anton15324772018-01-16 10:26:49 -08002520 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002521 // Do offer/answer and wait for successful end-to-end audio frames.
2522 caller()->CreateAndSetAndSignalOffer();
2523 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002524 MediaExpectations media_expectations;
2525 media_expectations.ExpectBidirectionalAudio();
2526 media_expectations.ExpectNoVideo();
2527 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2528
deadbeef1dcb1642017-03-29 21:08:16 -07002529 // Sanity check that the callee's description has a rejected video section.
2530 ASSERT_NE(nullptr, callee()->pc()->local_description());
2531 const ContentInfo* callee_video_content =
2532 GetFirstVideoContent(callee()->pc()->local_description()->description());
2533 ASSERT_NE(nullptr, callee_video_content);
2534 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002535 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002536 // The caller's transceiver should have stopped after receiving the answer,
2537 // and thus is no longer present.
2538 EXPECT_EQ(nullptr,
2539 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002540 }
deadbeef1dcb1642017-03-29 21:08:16 -07002541}
2542
2543// Test that if the answerer rejects both audio and video m= sections, nothing
2544// bad happens.
2545// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
2546// test anything but the fact that negotiation succeeds, which doesn't mean
2547// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002548TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -07002549 ASSERT_TRUE(CreatePeerConnectionWrappers());
2550 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002551 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002552 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2553 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
2554 // will reject both audio and video m= sections.
2555 PeerConnectionInterface::RTCOfferAnswerOptions options;
2556 options.offer_to_receive_audio = 0;
2557 options.offer_to_receive_video = 0;
2558 callee()->SetOfferAnswerOptions(options);
2559 } else {
2560 callee()->SetRemoteOfferHandler([this] {
2561 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +01002562 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002563 transceiver->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002564 }
2565 });
2566 }
deadbeef1dcb1642017-03-29 21:08:16 -07002567 // Do offer/answer and wait for stable signaling state.
2568 caller()->CreateAndSetAndSignalOffer();
2569 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002570
deadbeef1dcb1642017-03-29 21:08:16 -07002571 // Sanity check that the callee's description has rejected m= sections.
2572 ASSERT_NE(nullptr, callee()->pc()->local_description());
2573 const ContentInfo* callee_audio_content =
2574 GetFirstAudioContent(callee()->pc()->local_description()->description());
2575 ASSERT_NE(nullptr, callee_audio_content);
2576 EXPECT_TRUE(callee_audio_content->rejected);
2577 const ContentInfo* callee_video_content =
2578 GetFirstVideoContent(callee()->pc()->local_description()->description());
2579 ASSERT_NE(nullptr, callee_video_content);
2580 EXPECT_TRUE(callee_video_content->rejected);
2581}
2582
2583// This test sets up an audio and video call between two parties. After the
2584// call runs for a while, the caller sends an updated offer with video being
2585// rejected. Once the re-negotiation is done, the video flow should stop and
2586// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002587TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07002588 ASSERT_TRUE(CreatePeerConnectionWrappers());
2589 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002590 caller()->AddAudioVideoTracks();
2591 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002592 caller()->CreateAndSetAndSignalOffer();
2593 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002594 {
2595 MediaExpectations media_expectations;
2596 media_expectations.ExpectBidirectionalAudioAndVideo();
2597 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2598 }
deadbeef1dcb1642017-03-29 21:08:16 -07002599 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002600 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2601 caller()->SetGeneratedSdpMunger(
2602 [](cricket::SessionDescription* description) {
2603 for (cricket::ContentInfo& content : description->contents()) {
2604 if (cricket::IsVideoContent(&content)) {
2605 content.rejected = true;
2606 }
2607 }
2608 });
2609 } else {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002610 caller()
2611 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2612 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002613 }
deadbeef1dcb1642017-03-29 21:08:16 -07002614 caller()->CreateAndSetAndSignalOffer();
2615 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2616
2617 // Sanity check that the caller's description has a rejected video section.
2618 ASSERT_NE(nullptr, caller()->pc()->local_description());
2619 const ContentInfo* caller_video_content =
2620 GetFirstVideoContent(caller()->pc()->local_description()->description());
2621 ASSERT_NE(nullptr, caller_video_content);
2622 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -07002623 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002624 {
2625 MediaExpectations media_expectations;
2626 media_expectations.ExpectBidirectionalAudio();
2627 media_expectations.ExpectNoVideo();
2628 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2629 }
deadbeef1dcb1642017-03-29 21:08:16 -07002630}
2631
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -07002632// Do one offer/answer with audio, another that disables it (rejecting the m=
2633// section), and another that re-enables it. Regression test for:
2634// bugs.webrtc.org/6023
2635TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
2636 ASSERT_TRUE(CreatePeerConnectionWrappers());
2637 ConnectFakeSignaling();
2638
2639 // Add audio track, do normal offer/answer.
2640 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2641 caller()->CreateLocalAudioTrack();
2642 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2643 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2644 caller()->CreateAndSetAndSignalOffer();
2645 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2646
2647 // Remove audio track, and set offer_to_receive_audio to false to cause the
2648 // m= section to be completely disabled, not just "recvonly".
2649 caller()->pc()->RemoveTrack(sender);
2650 PeerConnectionInterface::RTCOfferAnswerOptions options;
2651 options.offer_to_receive_audio = 0;
2652 caller()->SetOfferAnswerOptions(options);
2653 caller()->CreateAndSetAndSignalOffer();
2654 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2655
2656 // Add the audio track again, expecting negotiation to succeed and frames to
2657 // flow.
2658 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2659 options.offer_to_receive_audio = 1;
2660 caller()->SetOfferAnswerOptions(options);
2661 caller()->CreateAndSetAndSignalOffer();
2662 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2663
2664 MediaExpectations media_expectations;
2665 media_expectations.CalleeExpectsSomeAudio();
2666 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2667}
2668
deadbeef1dcb1642017-03-29 21:08:16 -07002669// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
2670// is needed to support legacy endpoints.
2671// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
2672// add a test for an end-to-end test without MID signaling either (basically,
2673// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002674TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -07002675 ASSERT_TRUE(CreatePeerConnectionWrappers());
2676 ConnectFakeSignaling();
2677 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08002678 caller()->AddAudioVideoTracks();
2679 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07002680 // Remove SSRCs and MSIDs from the received offer SDP.
2681 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07002682 caller()->CreateAndSetAndSignalOffer();
2683 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002684 MediaExpectations media_expectations;
2685 media_expectations.ExpectBidirectionalAudioAndVideo();
2686 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002687}
2688
Seth Hampson5897a6e2018-04-03 11:16:33 -07002689// Basic end-to-end test, without SSRC signaling. This means that the track
2690// was created properly and frames are delivered when the MSIDs are communicated
2691// with a=msid lines and no a=ssrc lines.
2692TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2693 EndToEndCallWithoutSsrcSignaling) {
2694 const char kStreamId[] = "streamId";
2695 ASSERT_TRUE(CreatePeerConnectionWrappers());
2696 ConnectFakeSignaling();
2697 // Add just audio tracks.
2698 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
2699 callee()->AddAudioTrack();
2700
2701 // Remove SSRCs from the received offer SDP.
2702 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
2703 caller()->CreateAndSetAndSignalOffer();
2704 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2705 MediaExpectations media_expectations;
2706 media_expectations.ExpectBidirectionalAudio();
2707 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2708}
2709
Johannes Kron3e983682020-03-29 22:17:00 +02002710TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2711 EndToEndCallAddReceiveVideoToSendOnlyCall) {
2712 ASSERT_TRUE(CreatePeerConnectionWrappers());
2713 ConnectFakeSignaling();
2714 // Add one-directional video, from caller to callee.
2715 rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
2716 caller()->CreateLocalVideoTrack();
2717
2718 RtpTransceiverInit video_transceiver_init;
2719 video_transceiver_init.stream_ids = {"video1"};
2720 video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly;
2721 auto video_sender =
2722 caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue();
2723 caller()->CreateAndSetAndSignalOffer();
2724 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2725
2726 // Add receive direction.
Harald Alvestrand6060df52020-08-11 09:54:02 +02002727 video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);
Johannes Kron3e983682020-03-29 22:17:00 +02002728
2729 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
2730 callee()->CreateLocalVideoTrack();
2731
2732 callee()->AddTrack(callee_track);
2733 caller()->CreateAndSetAndSignalOffer();
2734 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2735 // Ensure that video frames are received end-to-end.
2736 MediaExpectations media_expectations;
2737 media_expectations.ExpectBidirectionalVideo();
2738 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2739}
2740
Steve Antondf527fd2018-04-27 15:52:03 -07002741// Tests that video flows between multiple video tracks when SSRCs are not
2742// signaled. This exercises the MID RTP header extension which is needed to
2743// demux the incoming video tracks.
2744TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2745 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
2746 ASSERT_TRUE(CreatePeerConnectionWrappers());
2747 ConnectFakeSignaling();
2748 caller()->AddVideoTrack();
2749 caller()->AddVideoTrack();
2750 callee()->AddVideoTrack();
2751 callee()->AddVideoTrack();
2752
2753 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2754 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2755 caller()->CreateAndSetAndSignalOffer();
2756 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2757 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2758 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2759
2760 // Expect video to be received in both directions on both tracks.
2761 MediaExpectations media_expectations;
2762 media_expectations.ExpectBidirectionalVideo();
2763 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2764}
2765
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -07002766// Used for the test below.
2767void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
2768 RemoveSsrcsAndKeepMsids(desc);
2769 desc->RemoveGroupByName("BUNDLE");
2770 for (ContentInfo& content : desc->contents()) {
2771 cricket::MediaContentDescription* media = content.media_description();
2772 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
2773 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
2774 [](const RtpExtension& extension) {
2775 return extension.uri ==
2776 RtpExtension::kMidUri;
2777 }),
2778 extensions.end());
2779 media->set_rtp_header_extensions(extensions);
2780 }
2781}
2782
2783// Tests that video flows between multiple video tracks when BUNDLE is not used,
2784// SSRCs are not signaled and the MID RTP header extension is not used. This
2785// relies on demuxing by payload type, which normally doesn't work if you have
2786// multiple media sections using the same payload type, but which should work as
2787// long as the media sections aren't bundled.
2788// Regression test for: http://crbug.com/webrtc/12023
2789TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2790 EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid) {
2791 ASSERT_TRUE(CreatePeerConnectionWrappers());
2792 ConnectFakeSignaling();
2793 caller()->AddVideoTrack();
2794 caller()->AddVideoTrack();
2795 callee()->AddVideoTrack();
2796 callee()->AddVideoTrack();
2797 caller()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
2798 callee()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
2799 caller()->CreateAndSetAndSignalOffer();
2800 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2801 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2802 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2803 // Make sure we are not bundled.
2804 ASSERT_NE(caller()->pc()->GetSenders()[0]->dtls_transport(),
2805 caller()->pc()->GetSenders()[1]->dtls_transport());
2806
2807 // Expect video to be received in both directions on both tracks.
2808 MediaExpectations media_expectations;
2809 media_expectations.ExpectBidirectionalVideo();
2810 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2811}
2812
2813// Used for the test below.
2814void ModifyPayloadTypesAndRemoveMidExtension(
2815 cricket::SessionDescription* desc) {
2816 int pt = 96;
2817 for (ContentInfo& content : desc->contents()) {
2818 cricket::MediaContentDescription* media = content.media_description();
2819 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
2820 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
2821 [](const RtpExtension& extension) {
2822 return extension.uri ==
2823 RtpExtension::kMidUri;
2824 }),
2825 extensions.end());
2826 media->set_rtp_header_extensions(extensions);
2827 cricket::VideoContentDescription* video = media->as_video();
2828 ASSERT_TRUE(video != nullptr);
2829 std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
2830 video->set_codecs(codecs);
2831 }
2832}
2833
2834// Tests that two video tracks can be demultiplexed by payload type alone, by
2835// using different payload types for the same codec in different m= sections.
2836// This practice is discouraged but historically has been supported.
2837// Regression test for: http://crbug.com/webrtc/12029
2838TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2839 EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType) {
2840 ASSERT_TRUE(CreatePeerConnectionWrappers());
2841 ConnectFakeSignaling();
2842 caller()->AddVideoTrack();
2843 caller()->AddVideoTrack();
2844 callee()->AddVideoTrack();
2845 callee()->AddVideoTrack();
2846 caller()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
2847 callee()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
2848 // We can't remove SSRCs from the generated SDP because then no send streams
2849 // would be created.
2850 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2851 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2852 caller()->CreateAndSetAndSignalOffer();
2853 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2854 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2855 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2856 // Make sure we are bundled.
2857 ASSERT_EQ(caller()->pc()->GetSenders()[0]->dtls_transport(),
2858 caller()->pc()->GetSenders()[1]->dtls_transport());
2859
2860 // Expect video to be received in both directions on both tracks.
2861 MediaExpectations media_expectations;
2862 media_expectations.ExpectBidirectionalVideo();
2863 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2864}
2865
Henrik Boström5b147782018-12-04 11:25:05 +01002866TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
2867 ASSERT_TRUE(CreatePeerConnectionWrappers());
2868 ConnectFakeSignaling();
2869 caller()->AddAudioTrack();
2870 caller()->AddVideoTrack();
2871 caller()->CreateAndSetAndSignalOffer();
2872 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2873 auto callee_receivers = callee()->pc()->GetReceivers();
2874 ASSERT_EQ(2u, callee_receivers.size());
2875 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
2876 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
2877}
2878
2879TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
2880 ASSERT_TRUE(CreatePeerConnectionWrappers());
2881 ConnectFakeSignaling();
2882 caller()->AddAudioTrack();
2883 caller()->AddVideoTrack();
2884 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2885 caller()->CreateAndSetAndSignalOffer();
2886 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2887 auto callee_receivers = callee()->pc()->GetReceivers();
2888 ASSERT_EQ(2u, callee_receivers.size());
2889 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
2890 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
2891 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
2892 callee_receivers[1]->stream_ids()[0]);
2893 EXPECT_EQ(callee_receivers[0]->streams()[0],
2894 callee_receivers[1]->streams()[0]);
2895}
2896
deadbeef1dcb1642017-03-29 21:08:16 -07002897// Test that if two video tracks are sent (from caller to callee, in this test),
2898// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002899TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07002900 ASSERT_TRUE(CreatePeerConnectionWrappers());
2901 ConnectFakeSignaling();
2902 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08002903 caller()->AddAudioVideoTracks();
2904 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002905 caller()->CreateAndSetAndSignalOffer();
2906 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08002907 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002908
2909 MediaExpectations media_expectations;
2910 media_expectations.CalleeExpectsSomeAudioAndVideo();
2911 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002912}
2913
2914static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
2915 bool first = true;
2916 for (cricket::ContentInfo& content : desc->contents()) {
2917 if (first) {
2918 first = false;
2919 continue;
2920 }
2921 content.bundle_only = true;
2922 }
2923 first = true;
2924 for (cricket::TransportInfo& transport : desc->transport_infos()) {
2925 if (first) {
2926 first = false;
2927 continue;
2928 }
2929 transport.description.ice_ufrag.clear();
2930 transport.description.ice_pwd.clear();
2931 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
2932 transport.description.identity_fingerprint.reset(nullptr);
2933 }
2934}
2935
2936// Test that if applying a true "max bundle" offer, which uses ports of 0,
2937// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
2938// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
2939// successfully and media flows.
2940// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
2941// TODO(deadbeef): Won't need this test once we start generating actual
2942// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002943TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002944 EndToEndCallWithSpecCompliantMaxBundleOffer) {
2945 ASSERT_TRUE(CreatePeerConnectionWrappers());
2946 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002947 caller()->AddAudioVideoTracks();
2948 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002949 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
2950 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
2951 // but the first m= section.
2952 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
2953 caller()->CreateAndSetAndSignalOffer();
2954 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002955 MediaExpectations media_expectations;
2956 media_expectations.ExpectBidirectionalAudioAndVideo();
2957 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002958}
2959
2960// Test that we can receive the audio output level from a remote audio track.
2961// TODO(deadbeef): Use a fake audio source and verify that the output level is
2962// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002963TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002964 ASSERT_TRUE(CreatePeerConnectionWrappers());
2965 ConnectFakeSignaling();
2966 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002967 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002968 caller()->CreateAndSetAndSignalOffer();
2969 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2970
2971 // Get the audio output level stats. Note that the level is not available
2972 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07002973 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002974 kMaxWaitForFramesMs);
2975}
2976
2977// Test that an audio input level is reported.
2978// TODO(deadbeef): Use a fake audio source and verify that the input level is
2979// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002980TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002981 ASSERT_TRUE(CreatePeerConnectionWrappers());
2982 ConnectFakeSignaling();
2983 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002984 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002985 caller()->CreateAndSetAndSignalOffer();
2986 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2987
2988 // Get the audio input level stats. The level should be available very
2989 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07002990 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002991 kMaxWaitForStatsMs);
2992}
2993
2994// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002995TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002996 ASSERT_TRUE(CreatePeerConnectionWrappers());
2997 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002998 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002999 // Do offer/answer, wait for the callee to receive some frames.
3000 caller()->CreateAndSetAndSignalOffer();
3001 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003002
3003 MediaExpectations media_expectations;
3004 media_expectations.CalleeExpectsSomeAudioAndVideo();
3005 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003006
3007 // Get a handle to the remote tracks created, so they can be used as GetStats
3008 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01003009 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08003010 // We received frames, so we definitely should have nonzero "received bytes"
3011 // stats at this point.
3012 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
3013 0);
3014 }
deadbeef1dcb1642017-03-29 21:08:16 -07003015}
3016
3017// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003018TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07003019 ASSERT_TRUE(CreatePeerConnectionWrappers());
3020 ConnectFakeSignaling();
3021 auto audio_track = caller()->CreateLocalAudioTrack();
3022 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08003023 caller()->AddTrack(audio_track);
3024 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07003025 // Do offer/answer, wait for the callee to receive some frames.
3026 caller()->CreateAndSetAndSignalOffer();
3027 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003028 MediaExpectations media_expectations;
3029 media_expectations.CalleeExpectsSomeAudioAndVideo();
3030 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003031
3032 // The callee received frames, so we definitely should have nonzero "sent
3033 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07003034 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
3035 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
3036}
3037
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003038// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003039TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003040 ASSERT_TRUE(CreatePeerConnectionWrappers());
3041 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003042 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003043
Steve Anton15324772018-01-16 10:26:49 -08003044 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003045
3046 // Do offer/answer, wait for the callee to receive some frames.
3047 caller()->CreateAndSetAndSignalOffer();
3048 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3049
3050 // Get the remote audio track created on the receiver, so they can be used as
3051 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08003052 auto receivers = callee()->pc()->GetReceivers();
3053 ASSERT_EQ(1u, receivers.size());
3054 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003055
3056 // Get the audio output level stats. Note that the level is not available
3057 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07003058 EXPECT_TRUE_WAIT(
3059 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
3060 0,
3061 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02003062}
3063
Steve Antona41959e2018-11-28 11:15:33 -08003064// Test that the track ID is associated with all local and remote SSRC stats
3065// using the old GetStats() and more than 1 audio and more than 1 video track.
3066// This is a regression test for crbug.com/906988
3067TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3068 OldGetStatsAssociatesTrackIdForManyMediaSections) {
3069 ASSERT_TRUE(CreatePeerConnectionWrappers());
3070 ConnectFakeSignaling();
3071 auto audio_sender_1 = caller()->AddAudioTrack();
3072 auto video_sender_1 = caller()->AddVideoTrack();
3073 auto audio_sender_2 = caller()->AddAudioTrack();
3074 auto video_sender_2 = caller()->AddVideoTrack();
3075 caller()->CreateAndSetAndSignalOffer();
3076 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3077
3078 MediaExpectations media_expectations;
3079 media_expectations.CalleeExpectsSomeAudioAndVideo();
3080 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
3081
3082 std::vector<std::string> track_ids = {
3083 audio_sender_1->track()->id(), video_sender_1->track()->id(),
3084 audio_sender_2->track()->id(), video_sender_2->track()->id()};
3085
3086 auto caller_stats = caller()->OldGetStats();
3087 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
3088 auto callee_stats = callee()->OldGetStats();
3089 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
3090}
3091
Steve Antonffa6ce42018-11-30 09:26:08 -08003092// Test that the new GetStats() returns stats for all outgoing/incoming streams
3093// with the correct track IDs if there are more than one audio and more than one
3094// video senders/receivers.
3095TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
3096 ASSERT_TRUE(CreatePeerConnectionWrappers());
3097 ConnectFakeSignaling();
3098 auto audio_sender_1 = caller()->AddAudioTrack();
3099 auto video_sender_1 = caller()->AddVideoTrack();
3100 auto audio_sender_2 = caller()->AddAudioTrack();
3101 auto video_sender_2 = caller()->AddVideoTrack();
3102 caller()->CreateAndSetAndSignalOffer();
3103 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3104
3105 MediaExpectations media_expectations;
3106 media_expectations.CalleeExpectsSomeAudioAndVideo();
3107 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
3108
3109 std::vector<std::string> track_ids = {
3110 audio_sender_1->track()->id(), video_sender_1->track()->id(),
3111 audio_sender_2->track()->id(), video_sender_2->track()->id()};
3112
3113 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
3114 caller()->NewGetStats();
3115 ASSERT_TRUE(caller_report);
3116 auto outbound_stream_stats =
3117 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
Henrik Boströma0ff50c2020-05-05 15:54:46 +02003118 ASSERT_EQ(outbound_stream_stats.size(), 4u);
Steve Antonffa6ce42018-11-30 09:26:08 -08003119 std::vector<std::string> outbound_track_ids;
3120 for (const auto& stat : outbound_stream_stats) {
3121 ASSERT_TRUE(stat->bytes_sent.is_defined());
3122 EXPECT_LT(0u, *stat->bytes_sent);
Rasmus Brandt2efae772019-06-27 14:29:34 +02003123 if (*stat->kind == "video") {
3124 ASSERT_TRUE(stat->key_frames_encoded.is_defined());
3125 EXPECT_GT(*stat->key_frames_encoded, 0u);
3126 ASSERT_TRUE(stat->frames_encoded.is_defined());
3127 EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
3128 }
Steve Antonffa6ce42018-11-30 09:26:08 -08003129 ASSERT_TRUE(stat->track_id.is_defined());
3130 const auto* track_stat =
3131 caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
3132 ASSERT_TRUE(track_stat);
3133 outbound_track_ids.push_back(*track_stat->track_identifier);
3134 }
3135 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
3136
3137 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
3138 callee()->NewGetStats();
3139 ASSERT_TRUE(callee_report);
3140 auto inbound_stream_stats =
3141 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
3142 ASSERT_EQ(4u, inbound_stream_stats.size());
3143 std::vector<std::string> inbound_track_ids;
3144 for (const auto& stat : inbound_stream_stats) {
3145 ASSERT_TRUE(stat->bytes_received.is_defined());
3146 EXPECT_LT(0u, *stat->bytes_received);
Rasmus Brandt2efae772019-06-27 14:29:34 +02003147 if (*stat->kind == "video") {
3148 ASSERT_TRUE(stat->key_frames_decoded.is_defined());
3149 EXPECT_GT(*stat->key_frames_decoded, 0u);
3150 ASSERT_TRUE(stat->frames_decoded.is_defined());
3151 EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
3152 }
Steve Antonffa6ce42018-11-30 09:26:08 -08003153 ASSERT_TRUE(stat->track_id.is_defined());
3154 const auto* track_stat =
3155 callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
3156 ASSERT_TRUE(track_stat);
3157 inbound_track_ids.push_back(*track_stat->track_identifier);
3158 }
3159 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
3160}
3161
3162// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07003163// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
3164// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003165TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07003166 GetStatsForUnsignaledStreamWithNewStatsApi) {
3167 ASSERT_TRUE(CreatePeerConnectionWrappers());
3168 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003169 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07003170 // Remove SSRCs and MSIDs from the received offer SDP.
3171 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3172 caller()->CreateAndSetAndSignalOffer();
3173 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003174 MediaExpectations media_expectations;
3175 media_expectations.CalleeExpectsSomeAudio(1);
3176 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07003177
3178 // We received a frame, so we should have nonzero "bytes received" stats for
3179 // the unsignaled stream, if stats are working for it.
3180 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
3181 callee()->NewGetStats();
3182 ASSERT_NE(nullptr, report);
3183 auto inbound_stream_stats =
3184 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
3185 ASSERT_EQ(1U, inbound_stream_stats.size());
3186 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
3187 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07003188 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
3189}
3190
Taylor Brandstettera4653442018-06-19 09:44:26 -07003191// Same as above but for the legacy stats implementation.
3192TEST_P(PeerConnectionIntegrationTest,
3193 GetStatsForUnsignaledStreamWithOldStatsApi) {
3194 ASSERT_TRUE(CreatePeerConnectionWrappers());
3195 ConnectFakeSignaling();
3196 caller()->AddAudioTrack();
3197 // Remove SSRCs and MSIDs from the received offer SDP.
3198 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3199 caller()->CreateAndSetAndSignalOffer();
3200 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3201
3202 // Note that, since the old stats implementation associates SSRCs with tracks
3203 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
3204 // associated track ID. So we can't use the track "selector" argument.
3205 //
3206 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
3207 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003208 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07003209 kDefaultTimeout);
3210}
3211
zhihuangf8164932017-05-19 13:09:47 -07003212// Test that we can successfully get the media related stats (audio level
3213// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003214TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07003215 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
3216 ASSERT_TRUE(CreatePeerConnectionWrappers());
3217 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003218 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07003219 // Remove SSRCs and MSIDs from the received offer SDP.
3220 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3221 caller()->CreateAndSetAndSignalOffer();
3222 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003223 MediaExpectations media_expectations;
3224 media_expectations.CalleeExpectsSomeAudio(1);
3225 media_expectations.CalleeExpectsSomeVideo(1);
3226 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07003227
3228 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
3229 callee()->NewGetStats();
3230 ASSERT_NE(nullptr, report);
3231
3232 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3233 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
3234 ASSERT_GE(audio_index, 0);
3235 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07003236}
3237
deadbeef4e2deab2017-09-20 13:56:21 -07003238// Helper for test below.
3239void ModifySsrcs(cricket::SessionDescription* desc) {
3240 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07003241 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08003242 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07003243 for (uint32_t& ssrc : stream.ssrcs) {
3244 ssrc = rtc::CreateRandomId();
3245 }
3246 }
3247 }
3248}
3249
3250// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
3251// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
3252// This should result in two "RTCInboundRTPStreamStats", but only one
3253// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
3254// being reset to 0 once the SSRC change occurs.
3255//
3256// Regression test for this bug:
3257// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
3258//
3259// The bug causes the track stats to only represent one of the two streams:
3260// whichever one has the higher SSRC. So with this bug, there was a 50% chance
3261// that the track stat counters would reset to 0 when the new stream is
3262// received, and a 50% chance that they'll stop updating (while
3263// "concealed_samples" continues increasing, due to silence being generated for
3264// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003265TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08003266 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07003267 ASSERT_TRUE(CreatePeerConnectionWrappers());
3268 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003269 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07003270 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
3271 // that doesn't signal SSRCs (from the callee's perspective).
3272 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
3273 caller()->CreateAndSetAndSignalOffer();
3274 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3275 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003276 {
3277 MediaExpectations media_expectations;
3278 media_expectations.CalleeExpectsSomeAudio(50);
3279 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3280 }
deadbeef4e2deab2017-09-20 13:56:21 -07003281 // Some audio frames were received, so we should have nonzero "samples
3282 // received" for the track.
3283 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
3284 callee()->NewGetStats();
3285 ASSERT_NE(nullptr, report);
3286 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3287 ASSERT_EQ(1U, track_stats.size());
3288 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
3289 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
3290 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
3291
3292 // Create a new offer and munge it to cause the caller to use a new SSRC.
3293 caller()->SetGeneratedSdpMunger(ModifySsrcs);
3294 caller()->CreateAndSetAndSignalOffer();
3295 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3296 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
3297 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003298 {
3299 MediaExpectations media_expectations;
3300 media_expectations.CalleeExpectsSomeAudio(25);
3301 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3302 }
deadbeef4e2deab2017-09-20 13:56:21 -07003303
3304 report = callee()->NewGetStats();
3305 ASSERT_NE(nullptr, report);
3306 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3307 ASSERT_EQ(1U, track_stats.size());
3308 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
3309 // The "total samples received" stat should only be greater than it was
3310 // before.
3311 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
3312 // Right now, the new SSRC will cause the counters to reset to 0.
3313 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
3314
3315 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08003316 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07003317 // good sign that we're seeing stats from the old stream that's no longer
3318 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08003319 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07003320 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
3321 EXPECT_LT(*track_stats[0]->concealed_samples,
3322 *track_stats[0]->total_samples_received *
3323 kAcceptableConcealedSamplesPercentage);
3324
3325 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
3326 // sanity check that the SSRC really changed.
3327 // TODO(deadbeef): This isn't working right now, because we're not returning
3328 // *any* stats for the inactive stream. Uncomment when the bug is completely
3329 // fixed.
3330 // auto inbound_stream_stats =
3331 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
3332 // ASSERT_EQ(2U, inbound_stream_stats.size());
3333}
3334
deadbeef1dcb1642017-03-29 21:08:16 -07003335// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003336TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07003337 PeerConnectionFactory::Options dtls_10_options;
3338 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3339 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
3340 dtls_10_options));
3341 ConnectFakeSignaling();
3342 // Do normal offer/answer and wait for some frames to be received in each
3343 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003344 caller()->AddAudioVideoTracks();
3345 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003346 caller()->CreateAndSetAndSignalOffer();
3347 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003348 MediaExpectations media_expectations;
3349 media_expectations.ExpectBidirectionalAudioAndVideo();
3350 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003351}
3352
3353// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003354TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07003355 PeerConnectionFactory::Options dtls_10_options;
3356 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3357 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
3358 dtls_10_options));
3359 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003360 caller()->AddAudioVideoTracks();
3361 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003362 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003363 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07003364 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07003365 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07003366 kDefaultTimeout);
3367 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07003368 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003369 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01003370 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
3371 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
3372 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07003373}
3374
3375// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003376TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07003377 PeerConnectionFactory::Options dtls_12_options;
3378 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3379 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
3380 dtls_12_options));
3381 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003382 caller()->AddAudioVideoTracks();
3383 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003384 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003385 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07003386 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07003387 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07003388 kDefaultTimeout);
3389 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07003390 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003391 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01003392 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
3393 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
3394 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07003395}
3396
3397// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
3398// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003399TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07003400 PeerConnectionFactory::Options caller_options;
3401 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3402 PeerConnectionFactory::Options callee_options;
3403 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3404 ASSERT_TRUE(
3405 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
3406 ConnectFakeSignaling();
3407 // Do normal offer/answer and wait for some frames to be received in each
3408 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003409 caller()->AddAudioVideoTracks();
3410 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003411 caller()->CreateAndSetAndSignalOffer();
3412 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003413 MediaExpectations media_expectations;
3414 media_expectations.ExpectBidirectionalAudioAndVideo();
3415 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003416}
3417
3418// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
3419// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003420TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07003421 PeerConnectionFactory::Options caller_options;
3422 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3423 PeerConnectionFactory::Options callee_options;
3424 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3425 ASSERT_TRUE(
3426 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
3427 ConnectFakeSignaling();
3428 // Do normal offer/answer and wait for some frames to be received in each
3429 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003430 caller()->AddAudioVideoTracks();
3431 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003432 caller()->CreateAndSetAndSignalOffer();
3433 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003434 MediaExpectations media_expectations;
3435 media_expectations.ExpectBidirectionalAudioAndVideo();
3436 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003437}
3438
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003439// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
3440// works as expected; the cipher should only be used if enabled by both sides.
3441TEST_P(PeerConnectionIntegrationTest,
3442 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
3443 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003444 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003445 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003446 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
3447 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003448 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
3449 TestNegotiatedCipherSuite(caller_options, callee_options,
3450 expected_cipher_suite);
3451}
3452
3453TEST_P(PeerConnectionIntegrationTest,
3454 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
3455 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003456 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
3457 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003458 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003459 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003460 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
3461 TestNegotiatedCipherSuite(caller_options, callee_options,
3462 expected_cipher_suite);
3463}
3464
3465TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
3466 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003467 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003468 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003469 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003470 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
3471 TestNegotiatedCipherSuite(caller_options, callee_options,
3472 expected_cipher_suite);
3473}
3474
deadbeef1dcb1642017-03-29 21:08:16 -07003475// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003476TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07003477 bool local_gcm_enabled = false;
3478 bool remote_gcm_enabled = false;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003479 bool aes_ctr_enabled = true;
deadbeef1dcb1642017-03-29 21:08:16 -07003480 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
3481 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003482 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07003483}
3484
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003485// Test that a GCM cipher is used if both ends support it and non-GCM is
3486// disabled.
3487TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07003488 bool local_gcm_enabled = true;
3489 bool remote_gcm_enabled = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003490 bool aes_ctr_enabled = false;
deadbeef1dcb1642017-03-29 21:08:16 -07003491 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
3492 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003493 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07003494}
3495
deadbeef7914b8c2017-04-21 03:23:33 -07003496// Verify that media can be transmitted end-to-end when GCM crypto suites are
3497// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
3498// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
3499// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003500TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07003501 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003502 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02003503 gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false;
deadbeef7914b8c2017-04-21 03:23:33 -07003504 ASSERT_TRUE(
3505 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
3506 ConnectFakeSignaling();
3507 // Do normal offer/answer and wait for some frames to be received in each
3508 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003509 caller()->AddAudioVideoTracks();
3510 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003511 caller()->CreateAndSetAndSignalOffer();
3512 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003513 MediaExpectations media_expectations;
3514 media_expectations.ExpectBidirectionalAudioAndVideo();
3515 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003516}
3517
deadbeef1dcb1642017-03-29 21:08:16 -07003518// This test sets up a call between two parties with audio, video and an RTP
3519// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003520TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003521 PeerConnectionInterface::RTCConfiguration rtc_config;
3522 rtc_config.enable_rtp_data_channel = true;
3523 rtc_config.enable_dtls_srtp = false;
3524 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003525 ConnectFakeSignaling();
3526 // Expect that data channel created on caller side will show up for callee as
3527 // well.
3528 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003529 caller()->AddAudioVideoTracks();
3530 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003531 caller()->CreateAndSetAndSignalOffer();
3532 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3533 // Ensure the existence of the RTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003534 MediaExpectations media_expectations;
3535 media_expectations.ExpectBidirectionalAudioAndVideo();
3536 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003537 ASSERT_NE(nullptr, caller()->data_channel());
3538 ASSERT_NE(nullptr, callee()->data_channel());
3539 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3540 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3541
3542 // Ensure data can be sent in both directions.
3543 std::string data = "hello world";
3544 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3545 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3546 kDefaultTimeout);
3547 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3548 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3549 kDefaultTimeout);
3550}
3551
Eldar Rellod9ebe012020-03-18 20:41:45 +02003552TEST_P(PeerConnectionIntegrationTest, RtpDataChannelWorksAfterRollback) {
3553 PeerConnectionInterface::RTCConfiguration rtc_config;
3554 rtc_config.enable_rtp_data_channel = true;
3555 rtc_config.enable_dtls_srtp = false;
3556 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
3557 ConnectFakeSignaling();
3558 auto data_channel = caller()->pc()->CreateDataChannel("label_1", nullptr);
3559 ASSERT_TRUE(data_channel.get() != nullptr);
3560 caller()->CreateAndSetAndSignalOffer();
3561 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3562
3563 caller()->CreateDataChannel("label_2", nullptr);
3564 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
3565 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
3566 caller()->pc()->SetLocalDescription(observer,
3567 caller()->CreateOfferAndWait().release());
3568 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3569 caller()->Rollback();
3570
3571 std::string data = "hello world";
3572 SendRtpDataWithRetries(data_channel, data, 5);
3573 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3574 kDefaultTimeout);
3575}
3576
deadbeef1dcb1642017-03-29 21:08:16 -07003577// Ensure that an RTP data channel is signaled as closed for the caller when
3578// the callee rejects it in a subsequent offer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003579TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003580 RtpDataChannelSignaledClosedInCalleeOffer) {
3581 // Same procedure as above test.
Niels Möllerf06f9232018-08-07 12:32:18 +02003582 PeerConnectionInterface::RTCConfiguration rtc_config;
3583 rtc_config.enable_rtp_data_channel = true;
3584 rtc_config.enable_dtls_srtp = false;
3585 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003586 ConnectFakeSignaling();
3587 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003588 caller()->AddAudioVideoTracks();
3589 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003590 caller()->CreateAndSetAndSignalOffer();
3591 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3592 ASSERT_NE(nullptr, caller()->data_channel());
3593 ASSERT_NE(nullptr, callee()->data_channel());
3594 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3595 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3596
3597 // Close the data channel on the callee, and do an updated offer/answer.
3598 callee()->data_channel()->Close();
3599 callee()->CreateAndSetAndSignalOffer();
3600 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3601 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3602 EXPECT_FALSE(callee()->data_observer()->IsOpen());
3603}
3604
3605// Tests that data is buffered in an RTP data channel until an observer is
3606// registered for it.
3607//
3608// NOTE: RTP data channels can receive data before the underlying
3609// transport has detected that a channel is writable and thus data can be
3610// received before the data channel state changes to open. That is hard to test
3611// but the same buffering is expected to be used in that case.
Yves Gerey100fe632020-01-17 19:15:53 +01003612//
3613// Use fake clock and simulated network delay so that we predictably can wait
3614// until an SCTP message has been delivered without "sleep()"ing.
3615TEST_P(PeerConnectionIntegrationTestWithFakeClock,
deadbeef1dcb1642017-03-29 21:08:16 -07003616 DataBufferedUntilRtpDataChannelObserverRegistered) {
deadbeef1dcb1642017-03-29 21:08:16 -07003617 virtual_socket_server()->set_delay_mean(5); // 5 ms per hop.
3618 virtual_socket_server()->UpdateDelayDistribution();
3619
Niels Möllerf06f9232018-08-07 12:32:18 +02003620 PeerConnectionInterface::RTCConfiguration rtc_config;
3621 rtc_config.enable_rtp_data_channel = true;
3622 rtc_config.enable_dtls_srtp = false;
3623 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003624 ConnectFakeSignaling();
3625 caller()->CreateDataChannel();
3626 caller()->CreateAndSetAndSignalOffer();
3627 ASSERT_TRUE(caller()->data_channel() != nullptr);
3628 ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr,
Yves Gerey100fe632020-01-17 19:15:53 +01003629 kDefaultTimeout, FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003630 ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(),
Yves Gerey100fe632020-01-17 19:15:53 +01003631 kDefaultTimeout, FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003632 ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen,
3633 callee()->data_channel()->state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01003634 FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003635
3636 // Unregister the observer which is normally automatically registered.
3637 callee()->data_channel()->UnregisterObserver();
3638 // Send data and advance fake clock until it should have been received.
3639 std::string data = "hello world";
3640 caller()->data_channel()->Send(DataBuffer(data));
Yves Gerey100fe632020-01-17 19:15:53 +01003641 SIMULATED_WAIT(false, 50, FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003642
3643 // Attach data channel and expect data to be received immediately. Note that
3644 // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any
3645 // further, but data can be received even if the callback is asynchronous.
3646 MockDataChannelObserver new_observer(callee()->data_channel());
3647 EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01003648 FakeClock());
deadbeef1dcb1642017-03-29 21:08:16 -07003649}
3650
3651// This test sets up a call between two parties with audio, video and but only
3652// the caller client supports RTP data channels.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003653TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003654 PeerConnectionInterface::RTCConfiguration rtc_config_1;
3655 rtc_config_1.enable_rtp_data_channel = true;
deadbeef1dcb1642017-03-29 21:08:16 -07003656 // Must disable DTLS to make negotiation succeed.
Niels Möllerf06f9232018-08-07 12:32:18 +02003657 rtc_config_1.enable_dtls_srtp = false;
3658 PeerConnectionInterface::RTCConfiguration rtc_config_2;
3659 rtc_config_2.enable_dtls_srtp = false;
3660 rtc_config_2.enable_dtls_srtp = false;
3661 ASSERT_TRUE(
3662 CreatePeerConnectionWrappersWithConfig(rtc_config_1, rtc_config_2));
deadbeef1dcb1642017-03-29 21:08:16 -07003663 ConnectFakeSignaling();
3664 caller()->CreateDataChannel();
Harald Alvestrandf3736ed2019-04-08 13:09:30 +02003665 ASSERT_TRUE(caller()->data_channel() != nullptr);
Steve Anton15324772018-01-16 10:26:49 -08003666 caller()->AddAudioVideoTracks();
3667 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003668 caller()->CreateAndSetAndSignalOffer();
3669 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3670 // The caller should still have a data channel, but it should be closed, and
3671 // one should ever have been created for the callee.
3672 EXPECT_TRUE(caller()->data_channel() != nullptr);
3673 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3674 EXPECT_EQ(nullptr, callee()->data_channel());
3675}
3676
3677// This test sets up a call between two parties with audio, and video. When
3678// audio and video is setup and flowing, an RTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003679TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003680 PeerConnectionInterface::RTCConfiguration rtc_config;
3681 rtc_config.enable_rtp_data_channel = true;
3682 rtc_config.enable_dtls_srtp = false;
3683 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003684 ConnectFakeSignaling();
3685 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003686 caller()->AddAudioVideoTracks();
3687 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003688 caller()->CreateAndSetAndSignalOffer();
3689 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3690 // Create data channel and do new offer and answer.
3691 caller()->CreateDataChannel();
3692 caller()->CreateAndSetAndSignalOffer();
3693 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3694 ASSERT_NE(nullptr, caller()->data_channel());
3695 ASSERT_NE(nullptr, callee()->data_channel());
3696 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3697 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3698 // Ensure data can be sent in both directions.
3699 std::string data = "hello world";
3700 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3701 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3702 kDefaultTimeout);
3703 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3704 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3705 kDefaultTimeout);
3706}
3707
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01003708#ifdef WEBRTC_HAVE_SCTP
deadbeef1dcb1642017-03-29 21:08:16 -07003709
3710// This test sets up a call between two parties with audio, video and an SCTP
3711// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003712TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003713 ASSERT_TRUE(CreatePeerConnectionWrappers());
3714 ConnectFakeSignaling();
3715 // Expect that data channel created on caller side will show up for callee as
3716 // well.
3717 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003718 caller()->AddAudioVideoTracks();
3719 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003720 caller()->CreateAndSetAndSignalOffer();
3721 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3722 // Ensure the existence of the SCTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003723 MediaExpectations media_expectations;
3724 media_expectations.ExpectBidirectionalAudioAndVideo();
3725 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003726 // Caller data channel should already exist (it created one). Callee data
3727 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3728 ASSERT_NE(nullptr, caller()->data_channel());
3729 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3730 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3731 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3732
3733 // Ensure data can be sent in both directions.
3734 std::string data = "hello world";
3735 caller()->data_channel()->Send(DataBuffer(data));
3736 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3737 kDefaultTimeout);
3738 callee()->data_channel()->Send(DataBuffer(data));
3739 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3740 kDefaultTimeout);
3741}
3742
3743// Ensure that when the callee closes an SCTP data channel, the closing
3744// procedure results in the data channel being closed for the caller as well.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003745TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003746 // Same procedure as above test.
3747 ASSERT_TRUE(CreatePeerConnectionWrappers());
3748 ConnectFakeSignaling();
3749 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003750 caller()->AddAudioVideoTracks();
3751 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003752 caller()->CreateAndSetAndSignalOffer();
3753 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3754 ASSERT_NE(nullptr, caller()->data_channel());
3755 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3756 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3757 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3758
3759 // Close the data channel on the callee side, and wait for it to reach the
3760 // "closed" state on both sides.
3761 callee()->data_channel()->Close();
3762 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3763 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3764}
3765
Seth Hampson2f0d7022018-02-20 11:54:42 -08003766TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
Steve Antonda6c0952017-10-23 11:41:54 -07003767 ASSERT_TRUE(CreatePeerConnectionWrappers());
3768 ConnectFakeSignaling();
3769 webrtc::DataChannelInit init;
3770 init.id = 53;
3771 init.maxRetransmits = 52;
3772 caller()->CreateDataChannel("data-channel", &init);
Steve Anton15324772018-01-16 10:26:49 -08003773 caller()->AddAudioVideoTracks();
3774 callee()->AddAudioVideoTracks();
Steve Antonda6c0952017-10-23 11:41:54 -07003775 caller()->CreateAndSetAndSignalOffer();
3776 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton074dece2017-10-24 13:04:12 -07003777 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3778 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Harald Alvestrand5c4d2ee2019-04-01 12:58:15 +02003779 // Since "negotiated" is false, the "id" parameter should be ignored.
3780 EXPECT_NE(init.id, callee()->data_channel()->id());
Steve Antonda6c0952017-10-23 11:41:54 -07003781 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3782 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3783 EXPECT_FALSE(callee()->data_channel()->negotiated());
3784}
3785
deadbeef1dcb1642017-03-29 21:08:16 -07003786// Test usrsctp's ability to process unordered data stream, where data actually
3787// arrives out of order using simulated delays. Previously there have been some
3788// bugs in this area.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003789TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003790 // Introduce random network delays.
3791 // Otherwise it's not a true "unordered" test.
3792 virtual_socket_server()->set_delay_mean(20);
3793 virtual_socket_server()->set_delay_stddev(5);
3794 virtual_socket_server()->UpdateDelayDistribution();
3795 // Normal procedure, but with unordered data channel config.
3796 ASSERT_TRUE(CreatePeerConnectionWrappers());
3797 ConnectFakeSignaling();
3798 webrtc::DataChannelInit init;
3799 init.ordered = false;
3800 caller()->CreateDataChannel(&init);
3801 caller()->CreateAndSetAndSignalOffer();
3802 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3803 ASSERT_NE(nullptr, caller()->data_channel());
3804 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3805 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3806 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3807
3808 static constexpr int kNumMessages = 100;
3809 // Deliberately chosen to be larger than the MTU so messages get fragmented.
3810 static constexpr size_t kMaxMessageSize = 4096;
3811 // Create and send random messages.
3812 std::vector<std::string> sent_messages;
3813 for (int i = 0; i < kNumMessages; ++i) {
3814 size_t length =
3815 (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand)
3816 std::string message;
3817 ASSERT_TRUE(rtc::CreateRandomString(length, &message));
3818 caller()->data_channel()->Send(DataBuffer(message));
3819 callee()->data_channel()->Send(DataBuffer(message));
3820 sent_messages.push_back(message);
3821 }
3822
3823 // Wait for all messages to be received.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003824 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003825 caller()->data_observer()->received_message_count(),
3826 kDefaultTimeout);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003827 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003828 callee()->data_observer()->received_message_count(),
3829 kDefaultTimeout);
3830
3831 // Sort and compare to make sure none of the messages were corrupted.
3832 std::vector<std::string> caller_received_messages =
3833 caller()->data_observer()->messages();
3834 std::vector<std::string> callee_received_messages =
3835 callee()->data_observer()->messages();
Steve Anton64b626b2019-01-28 17:25:26 -08003836 absl::c_sort(sent_messages);
3837 absl::c_sort(caller_received_messages);
3838 absl::c_sort(callee_received_messages);
deadbeef1dcb1642017-03-29 21:08:16 -07003839 EXPECT_EQ(sent_messages, caller_received_messages);
3840 EXPECT_EQ(sent_messages, callee_received_messages);
3841}
3842
3843// This test sets up a call between two parties with audio, and video. When
3844// audio and video are setup and flowing, an SCTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003845TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07003846 ASSERT_TRUE(CreatePeerConnectionWrappers());
3847 ConnectFakeSignaling();
3848 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003849 caller()->AddAudioVideoTracks();
3850 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003851 caller()->CreateAndSetAndSignalOffer();
3852 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3853 // Create data channel and do new offer and answer.
3854 caller()->CreateDataChannel();
3855 caller()->CreateAndSetAndSignalOffer();
3856 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3857 // Caller data channel should already exist (it created one). Callee data
3858 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3859 ASSERT_NE(nullptr, caller()->data_channel());
3860 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3861 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3862 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3863 // Ensure data can be sent in both directions.
3864 std::string data = "hello world";
3865 caller()->data_channel()->Send(DataBuffer(data));
3866 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3867 kDefaultTimeout);
3868 callee()->data_channel()->Send(DataBuffer(data));
3869 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3870 kDefaultTimeout);
3871}
3872
deadbeef7914b8c2017-04-21 03:23:33 -07003873// Set up a connection initially just using SCTP data channels, later upgrading
3874// to audio/video, ensuring frames are received end-to-end. Effectively the
3875// inverse of the test above.
3876// This was broken in M57; see https://crbug.com/711243
Seth Hampson2f0d7022018-02-20 11:54:42 -08003877TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
deadbeef7914b8c2017-04-21 03:23:33 -07003878 ASSERT_TRUE(CreatePeerConnectionWrappers());
3879 ConnectFakeSignaling();
3880 // Do initial offer/answer with just data channel.
3881 caller()->CreateDataChannel();
3882 caller()->CreateAndSetAndSignalOffer();
3883 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3884 // Wait until data can be sent over the data channel.
3885 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3886 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3887 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3888
3889 // Do subsequent offer/answer with two-way audio and video. Audio and video
3890 // should end up bundled on the DTLS/ICE transport already used for data.
Steve Anton15324772018-01-16 10:26:49 -08003891 caller()->AddAudioVideoTracks();
3892 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003893 caller()->CreateAndSetAndSignalOffer();
3894 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003895 MediaExpectations media_expectations;
3896 media_expectations.ExpectBidirectionalAudioAndVideo();
3897 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003898}
3899
deadbeef8b7e9ad2017-05-25 09:38:55 -07003900static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
Harald Alvestrand5fc28b12019-05-13 13:36:16 +02003901 cricket::SctpDataContentDescription* dcd_offer =
3902 GetFirstSctpDataContentDescription(desc);
Harald Alvestrand17ea0682019-12-13 11:51:04 +01003903 // See https://crbug.com/webrtc/11211 - this function is a no-op
Steve Antonb1c1de12017-12-21 15:14:30 -08003904 ASSERT_TRUE(dcd_offer);
deadbeef8b7e9ad2017-05-25 09:38:55 -07003905 dcd_offer->set_use_sctpmap(false);
3906 dcd_offer->set_protocol("UDP/DTLS/SCTP");
3907}
3908
3909// Test that the data channel works when a spec-compliant SCTP m= section is
3910// offered (using "a=sctp-port" instead of "a=sctpmap", and using
3911// "UDP/DTLS/SCTP" as the protocol).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003912TEST_P(PeerConnectionIntegrationTest,
deadbeef8b7e9ad2017-05-25 09:38:55 -07003913 DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
3914 ASSERT_TRUE(CreatePeerConnectionWrappers());
3915 ConnectFakeSignaling();
3916 caller()->CreateDataChannel();
3917 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
3918 caller()->CreateAndSetAndSignalOffer();
3919 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3920 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3921 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3922 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3923
3924 // Ensure data can be sent in both directions.
3925 std::string data = "hello world";
3926 caller()->data_channel()->Send(DataBuffer(data));
3927 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3928 kDefaultTimeout);
3929 callee()->data_channel()->Send(DataBuffer(data));
3930 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3931 kDefaultTimeout);
3932}
3933
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01003934#endif // WEBRTC_HAVE_SCTP
deadbeef1dcb1642017-03-29 21:08:16 -07003935
3936// Test that the ICE connection and gathering states eventually reach
3937// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08003938TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07003939 ASSERT_TRUE(CreatePeerConnectionWrappers());
3940 ConnectFakeSignaling();
3941 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08003942 caller()->AddAudioVideoTracks();
3943 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003944 caller()->CreateAndSetAndSignalOffer();
3945 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3946 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3947 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
3948 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3949 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
3950 // After the best candidate pair is selected and all candidates are signaled,
3951 // the ICE connection state should reach "complete".
3952 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
3953 // answerer/"callee" by default) only reaches "connected". When this is
3954 // fixed, this test should be updated.
3955 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3956 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00003957 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3958 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07003959}
3960
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003961constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
3962 cricket::PORTALLOCATOR_DISABLE_RELAY |
3963 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003964
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003965// Use a mock resolver to resolve the hostname back to the original IP on both
3966// sides and check that the ICE connection connects.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003967TEST_P(PeerConnectionIntegrationTest,
3968 IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003969 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003970 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003971 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003972 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003973 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
3974 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003975
3976 // This also verifies that the injected AsyncResolverFactory is used by
3977 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003978 EXPECT_CALL(*caller_resolver_factory, Create())
3979 .WillOnce(Return(&caller_async_resolver));
3980 webrtc::PeerConnectionDependencies caller_deps(nullptr);
3981 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
3982
3983 EXPECT_CALL(*callee_resolver_factory, Create())
3984 .WillOnce(Return(&callee_async_resolver));
3985 webrtc::PeerConnectionDependencies callee_deps(nullptr);
3986 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
3987
3988 PeerConnectionInterface::RTCConfiguration config;
3989 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3990 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3991
3992 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
3993 config, std::move(caller_deps), config, std::move(callee_deps)));
3994
3995 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
3996 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
3997
3998 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07003999 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004000 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07004001 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02004002 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004003
4004 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004005
4006 ConnectFakeSignaling();
4007 caller()->AddAudioVideoTracks();
4008 callee()->AddAudioVideoTracks();
4009 caller()->CreateAndSetAndSignalOffer();
4010 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4011 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4012 caller()->ice_connection_state(), kDefaultTimeout);
4013 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4014 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08004015
Ying Wangef3998f2019-12-09 13:06:53 +01004016 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
4017 "WebRTC.PeerConnection.CandidatePairType_UDP",
4018 webrtc::kIceCandidatePairHostNameHostName));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07004019}
4020
Steve Antonede9ca52017-10-16 13:04:27 -07004021// Test that firewalling the ICE connection causes the clients to identify the
4022// disconnected state and then removing the firewall causes them to reconnect.
4023class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08004024 : public PeerConnectionIntegrationBaseTest,
4025 public ::testing::WithParamInterface<
4026 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07004027 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08004028 PeerConnectionIntegrationIceStatesTest()
4029 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
4030 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07004031 }
4032
4033 void StartStunServer(const SocketAddress& server_address) {
4034 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01004035 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07004036 }
4037
4038 bool TestIPv6() {
4039 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
4040 }
4041
4042 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08004043 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
4044 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07004045 }
4046
4047 std::vector<SocketAddress> CallerAddresses() {
4048 std::vector<SocketAddress> addresses;
4049 addresses.push_back(SocketAddress("1.1.1.1", 0));
4050 if (TestIPv6()) {
4051 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
4052 }
4053 return addresses;
4054 }
4055
4056 std::vector<SocketAddress> CalleeAddresses() {
4057 std::vector<SocketAddress> addresses;
4058 addresses.push_back(SocketAddress("2.2.2.2", 0));
4059 if (TestIPv6()) {
4060 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
4061 }
4062 return addresses;
4063 }
4064
4065 void SetUpNetworkInterfaces() {
4066 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07004067 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
4068 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07004069
4070 // Add network addresses for test.
4071 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07004072 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07004073 }
4074 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07004075 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07004076 }
4077 }
4078
4079 private:
4080 uint32_t port_allocator_flags_;
4081 std::unique_ptr<cricket::TestStunServer> stun_server_;
4082};
4083
Yves Gerey100fe632020-01-17 19:15:53 +01004084// Ensure FakeClockForTest is constructed first (see class for rationale).
4085class PeerConnectionIntegrationIceStatesTestWithFakeClock
4086 : public FakeClockForTest,
4087 public PeerConnectionIntegrationIceStatesTest {};
4088
Steve Antonede9ca52017-10-16 13:04:27 -07004089// Tests that the PeerConnection goes through all the ICE gathering/connection
4090// states over the duration of the call. This includes Disconnected and Failed
4091// states, induced by putting a firewall between the peers and waiting for them
4092// to time out.
Yves Gerey100fe632020-01-17 19:15:53 +01004093TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock, VerifyIceStates) {
Steve Antonede9ca52017-10-16 13:04:27 -07004094 const SocketAddress kStunServerAddress =
4095 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
4096 StartStunServer(kStunServerAddress);
4097
4098 PeerConnectionInterface::RTCConfiguration config;
4099 PeerConnectionInterface::IceServer ice_stun_server;
4100 ice_stun_server.urls.push_back(
4101 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
4102 kStunServerAddress.PortAsString());
4103 config.servers.push_back(ice_stun_server);
4104
4105 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
4106 ConnectFakeSignaling();
4107 SetPortAllocatorFlags();
4108 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08004109 caller()->AddAudioVideoTracks();
4110 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004111
4112 // Initial state before anything happens.
4113 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
4114 caller()->ice_gathering_state());
4115 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
4116 caller()->ice_connection_state());
Jonas Olsson7a6739e2019-01-15 16:31:55 +01004117 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
4118 caller()->standardized_ice_connection_state());
Steve Antonede9ca52017-10-16 13:04:27 -07004119
4120 // Start the call by creating the offer, setting it as the local description,
4121 // then sending it to the peer who will respond with an answer. This happens
4122 // asynchronously so that we can watch the states as it runs in the
4123 // background.
4124 caller()->CreateAndSetAndSignalOffer();
4125
Steve Antona9b67ce2020-01-16 14:00:44 -08004126 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4127 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004128 FakeClock());
Steve Antona9b67ce2020-01-16 14:00:44 -08004129 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4130 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004131 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004132
4133 // Verify that the observer was notified of the intermediate transitions.
4134 EXPECT_THAT(caller()->ice_connection_state_history(),
4135 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
4136 PeerConnectionInterface::kIceConnectionConnected,
4137 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olssonacd8ae72019-02-25 15:26:24 +01004138 EXPECT_THAT(caller()->standardized_ice_connection_state_history(),
4139 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
4140 PeerConnectionInterface::kIceConnectionConnected,
4141 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olsson635474e2018-10-18 15:58:17 +02004142 EXPECT_THAT(
4143 caller()->peer_connection_state_history(),
4144 ElementsAre(PeerConnectionInterface::PeerConnectionState::kConnecting,
Jonas Olsson635474e2018-10-18 15:58:17 +02004145 PeerConnectionInterface::PeerConnectionState::kConnected));
Steve Antonede9ca52017-10-16 13:04:27 -07004146 EXPECT_THAT(caller()->ice_gathering_state_history(),
4147 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
4148 PeerConnectionInterface::kIceGatheringComplete));
4149
4150 // Block connections to/from the caller and wait for ICE to become
4151 // disconnected.
4152 for (const auto& caller_address : CallerAddresses()) {
4153 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4154 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01004155 RTC_LOG(LS_INFO) << "Firewall rules applied";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004156 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
4157 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004158 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004159 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
4160 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004161 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004162
4163 // Let ICE re-establish by removing the firewall rules.
4164 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01004165 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004166 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4167 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004168 FakeClock());
Jonas Olssonacd8ae72019-02-25 15:26:24 +01004169 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004170 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004171 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004172
4173 // According to RFC7675, if there is no response within 30 seconds then the
4174 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08004175 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07004176 constexpr int kConsentTimeout = 30000;
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 again";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004181 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4182 caller()->ice_connection_state(), kConsentTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01004183 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004184 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4185 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004186 kConsentTimeout, FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004187}
4188
4189// Tests that if the connection doesn't get set up properly we eventually reach
4190// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01004191TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
4192 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004193 // Block connections to/from the caller and wait for ICE to become
4194 // disconnected.
4195 for (const auto& caller_address : CallerAddresses()) {
4196 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4197 }
4198
4199 ASSERT_TRUE(CreatePeerConnectionWrappers());
4200 ConnectFakeSignaling();
4201 SetPortAllocatorFlags();
4202 SetUpNetworkInterfaces();
4203 caller()->AddAudioVideoTracks();
4204 caller()->CreateAndSetAndSignalOffer();
4205
4206 // According to RFC7675, if there is no response within 30 seconds then the
4207 // peer should consider the other side to have rejected the connection. This
4208 // is signaled by the state transitioning to "failed".
4209 constexpr int kConsentTimeout = 30000;
4210 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4211 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01004212 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07004213}
4214
4215// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
4216// and that the statistics in the metric observers are updated correctly.
4217TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) {
4218 ASSERT_TRUE(CreatePeerConnectionWrappers());
4219 ConnectFakeSignaling();
4220 SetPortAllocatorFlags();
4221 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08004222 caller()->AddAudioVideoTracks();
4223 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004224 caller()->CreateAndSetAndSignalOffer();
4225
4226 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08004227 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4228 caller()->ice_connection_state(), kDefaultTimeout);
4229 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4230 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07004231
Qingsi Wang7fc821d2018-07-12 12:54:53 -07004232 // TODO(bugs.webrtc.org/9456): Fix it.
4233 const int num_best_ipv4 = webrtc::metrics::NumEvents(
4234 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
4235 const int num_best_ipv6 = webrtc::metrics::NumEvents(
4236 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004237 if (TestIPv6()) {
4238 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
4239 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01004240 EXPECT_METRIC_EQ(0, num_best_ipv4);
4241 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004242 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01004243 EXPECT_METRIC_EQ(1, num_best_ipv4);
4244 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004245 }
4246
Ying Wangef3998f2019-12-09 13:06:53 +01004247 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
4248 "WebRTC.PeerConnection.CandidatePairType_UDP",
4249 webrtc::kIceCandidatePairHostHost));
4250 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
4251 "WebRTC.PeerConnection.CandidatePairType_UDP",
4252 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07004253}
4254
4255constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
4256 cricket::PORTALLOCATOR_DISABLE_STUN |
4257 cricket::PORTALLOCATOR_DISABLE_RELAY;
4258constexpr uint32_t kFlagsIPv6NoStun =
4259 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
4260 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
4261constexpr uint32_t kFlagsIPv4Stun =
4262 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
4263
Mirko Bonadeic84f6612019-01-31 12:20:57 +01004264INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004265 PeerConnectionIntegrationTest,
4266 PeerConnectionIntegrationIceStatesTest,
4267 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4268 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
4269 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
4270 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07004271
Yves Gerey100fe632020-01-17 19:15:53 +01004272INSTANTIATE_TEST_SUITE_P(
4273 PeerConnectionIntegrationTest,
4274 PeerConnectionIntegrationIceStatesTestWithFakeClock,
4275 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4276 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
4277 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
4278 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
4279
deadbeef1dcb1642017-03-29 21:08:16 -07004280// This test sets up a call between two parties with audio and video.
4281// During the call, the caller restarts ICE and the test verifies that
4282// new ICE candidates are generated and audio and video still can flow, and the
4283// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004284TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07004285 ASSERT_TRUE(CreatePeerConnectionWrappers());
4286 ConnectFakeSignaling();
4287 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08004288 caller()->AddAudioVideoTracks();
4289 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004290 caller()->CreateAndSetAndSignalOffer();
4291 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4292 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4293 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00004294 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4295 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07004296
4297 // To verify that the ICE restart actually occurs, get
4298 // ufrag/password/candidates before and after restart.
4299 // Create an SDP string of the first audio candidate for both clients.
4300 const webrtc::IceCandidateCollection* audio_candidates_caller =
4301 caller()->pc()->local_description()->candidates(0);
4302 const webrtc::IceCandidateCollection* audio_candidates_callee =
4303 callee()->pc()->local_description()->candidates(0);
4304 ASSERT_GT(audio_candidates_caller->count(), 0u);
4305 ASSERT_GT(audio_candidates_callee->count(), 0u);
4306 std::string caller_candidate_pre_restart;
4307 ASSERT_TRUE(
4308 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
4309 std::string callee_candidate_pre_restart;
4310 ASSERT_TRUE(
4311 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
4312 const cricket::SessionDescription* desc =
4313 caller()->pc()->local_description()->description();
4314 std::string caller_ufrag_pre_restart =
4315 desc->transport_infos()[0].description.ice_ufrag;
4316 desc = callee()->pc()->local_description()->description();
4317 std::string callee_ufrag_pre_restart =
4318 desc->transport_infos()[0].description.ice_ufrag;
4319
Alex Drake00c7ecf2019-08-06 10:54:47 -07004320 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07004321 // Have the caller initiate an ICE restart.
4322 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
4323 caller()->CreateAndSetAndSignalOffer();
4324 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4325 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4326 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00004327 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07004328 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4329
4330 // Grab the ufrags/candidates again.
4331 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
4332 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
4333 ASSERT_GT(audio_candidates_caller->count(), 0u);
4334 ASSERT_GT(audio_candidates_callee->count(), 0u);
4335 std::string caller_candidate_post_restart;
4336 ASSERT_TRUE(
4337 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
4338 std::string callee_candidate_post_restart;
4339 ASSERT_TRUE(
4340 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
4341 desc = caller()->pc()->local_description()->description();
4342 std::string caller_ufrag_post_restart =
4343 desc->transport_infos()[0].description.ice_ufrag;
4344 desc = callee()->pc()->local_description()->description();
4345 std::string callee_ufrag_post_restart =
4346 desc->transport_infos()[0].description.ice_ufrag;
4347 // Sanity check that an ICE restart was actually negotiated in SDP.
4348 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
4349 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
4350 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
4351 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07004352 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07004353
4354 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004355 MediaExpectations media_expectations;
4356 media_expectations.ExpectBidirectionalAudioAndVideo();
4357 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004358}
4359
4360// Verify that audio/video can be received end-to-end when ICE renomination is
4361// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004362TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07004363 PeerConnectionInterface::RTCConfiguration config;
4364 config.enable_ice_renomination = true;
4365 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
4366 ConnectFakeSignaling();
4367 // Do normal offer/answer and wait for some frames to be received in each
4368 // direction.
Steve Anton15324772018-01-16 10:26:49 -08004369 caller()->AddAudioVideoTracks();
4370 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004371 caller()->CreateAndSetAndSignalOffer();
4372 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4373 // Sanity check that ICE renomination was actually negotiated.
4374 const cricket::SessionDescription* desc =
4375 caller()->pc()->local_description()->description();
4376 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08004377 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07004378 }
4379 desc = callee()->pc()->local_description()->description();
4380 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08004381 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07004382 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08004383 MediaExpectations media_expectations;
4384 media_expectations.ExpectBidirectionalAudioAndVideo();
4385 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004386}
4387
Steve Anton6f25b092017-10-23 09:39:20 -07004388// With a max bundle policy and RTCP muxing, adding a new media description to
4389// the connection should not affect ICE at all because the new media will use
4390// the existing connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004391TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08004392 AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07004393 PeerConnectionInterface::RTCConfiguration config;
4394 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
4395 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
4396 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
4397 config, PeerConnectionInterface::RTCConfiguration()));
4398 ConnectFakeSignaling();
4399
Steve Anton15324772018-01-16 10:26:49 -08004400 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07004401 caller()->CreateAndSetAndSignalOffer();
4402 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07004403 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4404 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07004405
4406 caller()->clear_ice_connection_state_history();
4407
Steve Anton15324772018-01-16 10:26:49 -08004408 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07004409 caller()->CreateAndSetAndSignalOffer();
4410 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4411
4412 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
4413}
4414
deadbeef1dcb1642017-03-29 21:08:16 -07004415// This test sets up a call between two parties with audio and video. It then
4416// renegotiates setting the video m-line to "port 0", then later renegotiates
4417// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004418TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07004419 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
4420 ASSERT_TRUE(CreatePeerConnectionWrappers());
4421 ConnectFakeSignaling();
4422
4423 // Do initial negotiation, only sending media from the caller. Will result in
4424 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08004425 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004426 caller()->CreateAndSetAndSignalOffer();
4427 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4428
4429 // Negotiate again, disabling the video "m=" section (the callee will set the
4430 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08004431 if (sdp_semantics_ == SdpSemantics::kPlanB) {
4432 PeerConnectionInterface::RTCOfferAnswerOptions options;
4433 options.offer_to_receive_video = 0;
4434 callee()->SetOfferAnswerOptions(options);
4435 } else {
4436 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02004437 callee()
4438 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
4439 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08004440 });
4441 }
deadbeef1dcb1642017-03-29 21:08:16 -07004442 caller()->CreateAndSetAndSignalOffer();
4443 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4444 // Sanity check that video "m=" section was actually rejected.
4445 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
4446 callee()->pc()->local_description()->description());
4447 ASSERT_NE(nullptr, answer_video_content);
4448 ASSERT_TRUE(answer_video_content->rejected);
4449
4450 // Enable video and do negotiation again, making sure video is received
4451 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004452 if (sdp_semantics_ == SdpSemantics::kPlanB) {
4453 PeerConnectionInterface::RTCOfferAnswerOptions options;
4454 options.offer_to_receive_video = 1;
4455 callee()->SetOfferAnswerOptions(options);
4456 } else {
4457 // The caller's transceiver is stopped, so we need to add another track.
4458 auto caller_transceiver =
4459 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02004460 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08004461 caller()->AddVideoTrack();
4462 }
4463 callee()->AddVideoTrack();
4464 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07004465 caller()->CreateAndSetAndSignalOffer();
4466 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004467
deadbeef1dcb1642017-03-29 21:08:16 -07004468 // Verify the caller receives frames from the newly added stream, and the
4469 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004470 MediaExpectations media_expectations;
4471 media_expectations.CalleeExpectsSomeAudio();
4472 media_expectations.ExpectBidirectionalVideo();
4473 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004474}
4475
deadbeef1dcb1642017-03-29 21:08:16 -07004476// This tests that if we negotiate after calling CreateSender but before we
4477// have a track, then set a track later, frames from the newly-set track are
4478// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004479TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07004480 MediaFlowsAfterEarlyWarmupWithCreateSender) {
4481 ASSERT_TRUE(CreatePeerConnectionWrappers());
4482 ConnectFakeSignaling();
4483 auto caller_audio_sender =
4484 caller()->pc()->CreateSender("audio", "caller_stream");
4485 auto caller_video_sender =
4486 caller()->pc()->CreateSender("video", "caller_stream");
4487 auto callee_audio_sender =
4488 callee()->pc()->CreateSender("audio", "callee_stream");
4489 auto callee_video_sender =
4490 callee()->pc()->CreateSender("video", "callee_stream");
4491 caller()->CreateAndSetAndSignalOffer();
4492 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4493 // Wait for ICE to complete, without any tracks being set.
4494 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4495 caller()->ice_connection_state(), kMaxWaitForFramesMs);
4496 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4497 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4498 // Now set the tracks, and expect frames to immediately start flowing.
4499 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
4500 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
4501 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
4502 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08004503 MediaExpectations media_expectations;
4504 media_expectations.ExpectBidirectionalAudioAndVideo();
4505 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4506}
4507
4508// This tests that if we negotiate after calling AddTransceiver but before we
4509// have a track, then set a track later, frames from the newly-set tracks are
4510// received end-to-end.
4511TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
4512 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
4513 ASSERT_TRUE(CreatePeerConnectionWrappers());
4514 ConnectFakeSignaling();
4515 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
4516 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
4517 auto caller_audio_sender = audio_result.MoveValue()->sender();
4518 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
4519 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
4520 auto caller_video_sender = video_result.MoveValue()->sender();
4521 callee()->SetRemoteOfferHandler([this] {
4522 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02004523 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004524 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02004525 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004526 RtpTransceiverDirection::kSendRecv);
4527 });
4528 caller()->CreateAndSetAndSignalOffer();
4529 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4530 // Wait for ICE to complete, without any tracks being set.
4531 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4532 caller()->ice_connection_state(), kMaxWaitForFramesMs);
4533 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4534 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4535 // Now set the tracks, and expect frames to immediately start flowing.
4536 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
4537 auto callee_video_sender = callee()->pc()->GetSenders()[1];
4538 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
4539 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
4540 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
4541 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
4542 MediaExpectations media_expectations;
4543 media_expectations.ExpectBidirectionalAudioAndVideo();
4544 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004545}
4546
4547// This test verifies that a remote video track can be added via AddStream,
4548// and sent end-to-end. For this particular test, it's simply echoed back
4549// from the caller to the callee, rather than being forwarded to a third
4550// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004551TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07004552 ASSERT_TRUE(CreatePeerConnectionWrappers());
4553 ConnectFakeSignaling();
4554 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08004555 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07004556 caller()->CreateAndSetAndSignalOffer();
4557 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02004558 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07004559
4560 // Echo the stream back, and do a new offer/anwer (initiated by callee this
4561 // time).
4562 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
4563 callee()->CreateAndSetAndSignalOffer();
4564 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4565
Seth Hampson2f0d7022018-02-20 11:54:42 -08004566 MediaExpectations media_expectations;
4567 media_expectations.ExpectBidirectionalVideo();
4568 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004569}
4570
4571// Test that we achieve the expected end-to-end connection time, using a
4572// fake clock and simulated latency on the media and signaling paths.
4573// We use a TURN<->TURN connection because this is usually the quickest to
4574// set up initially, especially when we're confident the connection will work
4575// and can start sending media before we get a STUN response.
4576//
4577// With various optimizations enabled, here are the network delays we expect to
4578// be on the critical path:
4579// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
4580// signaling answer (with DTLS fingerprint).
4581// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
4582// using TURN<->TURN pair, and DTLS exchange is 4 packets,
4583// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01004584TEST_P(PeerConnectionIntegrationTestWithFakeClock,
4585 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07004586 static constexpr int media_hop_delay_ms = 50;
4587 static constexpr int signaling_trip_delay_ms = 500;
4588 // For explanation of these values, see comment above.
4589 static constexpr int required_media_hops = 9;
4590 static constexpr int required_signaling_trips = 2;
4591 // For internal delays (such as posting an event asychronously).
4592 static constexpr int allowed_internal_delay_ms = 20;
4593 static constexpr int total_connection_time_ms =
4594 media_hop_delay_ms * required_media_hops +
4595 signaling_trip_delay_ms * required_signaling_trips +
4596 allowed_internal_delay_ms;
4597
4598 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4599 3478};
4600 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4601 0};
4602 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4603 3478};
4604 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4605 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004606 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
4607 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004608
Seth Hampsonaed71642018-06-11 07:41:32 -07004609 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
4610 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07004611 // Bypass permission check on received packets so media can be sent before
4612 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07004613 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
4614 turn_server_1->set_enable_permission_checks(false);
4615 });
4616 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
4617 turn_server_2->set_enable_permission_checks(false);
4618 });
deadbeef1dcb1642017-03-29 21:08:16 -07004619
4620 PeerConnectionInterface::RTCConfiguration client_1_config;
4621 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4622 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4623 ice_server_1.username = "test";
4624 ice_server_1.password = "test";
4625 client_1_config.servers.push_back(ice_server_1);
4626 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4627 client_1_config.presume_writable_when_fully_relayed = true;
4628
4629 PeerConnectionInterface::RTCConfiguration client_2_config;
4630 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4631 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4632 ice_server_2.username = "test";
4633 ice_server_2.password = "test";
4634 client_2_config.servers.push_back(ice_server_2);
4635 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4636 client_2_config.presume_writable_when_fully_relayed = true;
4637
4638 ASSERT_TRUE(
4639 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4640 // Set up the simulated delays.
4641 SetSignalingDelayMs(signaling_trip_delay_ms);
4642 ConnectFakeSignaling();
4643 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
4644 virtual_socket_server()->UpdateDelayDistribution();
4645
4646 // Set "offer to receive audio/video" without adding any tracks, so we just
4647 // set up ICE/DTLS with no media.
4648 PeerConnectionInterface::RTCOfferAnswerOptions options;
4649 options.offer_to_receive_audio = 1;
4650 options.offer_to_receive_video = 1;
4651 caller()->SetOfferAnswerOptions(options);
4652 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07004653 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01004654 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07004655 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
4656 // If this is not done a DCHECK can be hit in ports.cc, because a large
4657 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07004658 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07004659}
4660
Jonas Orelandbdcee282017-10-10 14:01:40 +02004661// Verify that a TurnCustomizer passed in through RTCConfiguration
4662// is actually used by the underlying TURN candidate pair.
4663// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004664TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02004665 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4666 3478};
4667 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4668 0};
4669 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4670 3478};
4671 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4672 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004673 CreateTurnServer(turn_server_1_internal_address,
4674 turn_server_1_external_address);
4675 CreateTurnServer(turn_server_2_internal_address,
4676 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004677
4678 PeerConnectionInterface::RTCConfiguration client_1_config;
4679 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4680 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4681 ice_server_1.username = "test";
4682 ice_server_1.password = "test";
4683 client_1_config.servers.push_back(ice_server_1);
4684 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004685 auto* customizer1 = CreateTurnCustomizer();
4686 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004687
4688 PeerConnectionInterface::RTCConfiguration client_2_config;
4689 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4690 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4691 ice_server_2.username = "test";
4692 ice_server_2.password = "test";
4693 client_2_config.servers.push_back(ice_server_2);
4694 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004695 auto* customizer2 = CreateTurnCustomizer();
4696 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004697
4698 ASSERT_TRUE(
4699 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4700 ConnectFakeSignaling();
4701
4702 // Set "offer to receive audio/video" without adding any tracks, so we just
4703 // set up ICE/DTLS with no media.
4704 PeerConnectionInterface::RTCOfferAnswerOptions options;
4705 options.offer_to_receive_audio = 1;
4706 options.offer_to_receive_video = 1;
4707 caller()->SetOfferAnswerOptions(options);
4708 caller()->CreateAndSetAndSignalOffer();
4709 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4710
Seth Hampsonaed71642018-06-11 07:41:32 -07004711 ExpectTurnCustomizerCountersIncremented(customizer1);
4712 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004713}
4714
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004715// Verifies that you can use TCP instead of UDP to connect to a TURN server and
4716// send media between the caller and the callee.
4717TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
4718 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4719 3478};
4720 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4721
4722 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07004723 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4724 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004725
4726 webrtc::PeerConnectionInterface::IceServer ice_server;
4727 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
4728 ice_server.username = "test";
4729 ice_server.password = "test";
4730
4731 PeerConnectionInterface::RTCConfiguration client_1_config;
4732 client_1_config.servers.push_back(ice_server);
4733 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4734
4735 PeerConnectionInterface::RTCConfiguration client_2_config;
4736 client_2_config.servers.push_back(ice_server);
4737 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4738
4739 ASSERT_TRUE(
4740 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4741
4742 // Do normal offer/answer and wait for ICE to complete.
4743 ConnectFakeSignaling();
4744 caller()->AddAudioVideoTracks();
4745 callee()->AddAudioVideoTracks();
4746 caller()->CreateAndSetAndSignalOffer();
4747 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4748 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4749 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4750
4751 MediaExpectations media_expectations;
4752 media_expectations.ExpectBidirectionalAudioAndVideo();
4753 EXPECT_TRUE(ExpectNewFrames(media_expectations));
4754}
4755
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004756// Verify that a SSLCertificateVerifier passed in through
4757// PeerConnectionDependencies is actually used by the underlying SSL
4758// implementation to determine whether a certificate presented by the TURN
4759// server is accepted by the client. Note that openssladapter_unittest.cc
4760// contains more detailed, lower-level tests.
4761TEST_P(PeerConnectionIntegrationTest,
4762 SSLCertificateVerifierUsedForTurnConnections) {
4763 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4764 3478};
4765 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4766
4767 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4768 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004769 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4770 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004771
4772 webrtc::PeerConnectionInterface::IceServer ice_server;
4773 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4774 ice_server.username = "test";
4775 ice_server.password = "test";
4776
4777 PeerConnectionInterface::RTCConfiguration client_1_config;
4778 client_1_config.servers.push_back(ice_server);
4779 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4780
4781 PeerConnectionInterface::RTCConfiguration client_2_config;
4782 client_2_config.servers.push_back(ice_server);
4783 // Setting the type to kRelay forces the connection to go through a TURN
4784 // server.
4785 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4786
4787 // Get a copy to the pointer so we can verify calls later.
4788 rtc::TestCertificateVerifier* client_1_cert_verifier =
4789 new rtc::TestCertificateVerifier();
4790 client_1_cert_verifier->verify_certificate_ = true;
4791 rtc::TestCertificateVerifier* client_2_cert_verifier =
4792 new rtc::TestCertificateVerifier();
4793 client_2_cert_verifier->verify_certificate_ = true;
4794
4795 // Create the dependencies with the test certificate verifier.
4796 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4797 client_1_deps.tls_cert_verifier =
4798 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4799 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4800 client_2_deps.tls_cert_verifier =
4801 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4802
4803 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4804 client_1_config, std::move(client_1_deps), client_2_config,
4805 std::move(client_2_deps)));
4806 ConnectFakeSignaling();
4807
4808 // Set "offer to receive audio/video" without adding any tracks, so we just
4809 // set up ICE/DTLS with no media.
4810 PeerConnectionInterface::RTCOfferAnswerOptions options;
4811 options.offer_to_receive_audio = 1;
4812 options.offer_to_receive_video = 1;
4813 caller()->SetOfferAnswerOptions(options);
4814 caller()->CreateAndSetAndSignalOffer();
4815 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4816
4817 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4818 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004819}
4820
4821TEST_P(PeerConnectionIntegrationTest,
4822 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
4823 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4824 3478};
4825 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4826
4827 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4828 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004829 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4830 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004831
4832 webrtc::PeerConnectionInterface::IceServer ice_server;
4833 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4834 ice_server.username = "test";
4835 ice_server.password = "test";
4836
4837 PeerConnectionInterface::RTCConfiguration client_1_config;
4838 client_1_config.servers.push_back(ice_server);
4839 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4840
4841 PeerConnectionInterface::RTCConfiguration client_2_config;
4842 client_2_config.servers.push_back(ice_server);
4843 // Setting the type to kRelay forces the connection to go through a TURN
4844 // server.
4845 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4846
4847 // Get a copy to the pointer so we can verify calls later.
4848 rtc::TestCertificateVerifier* client_1_cert_verifier =
4849 new rtc::TestCertificateVerifier();
4850 client_1_cert_verifier->verify_certificate_ = false;
4851 rtc::TestCertificateVerifier* client_2_cert_verifier =
4852 new rtc::TestCertificateVerifier();
4853 client_2_cert_verifier->verify_certificate_ = false;
4854
4855 // Create the dependencies with the test certificate verifier.
4856 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4857 client_1_deps.tls_cert_verifier =
4858 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4859 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4860 client_2_deps.tls_cert_verifier =
4861 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4862
4863 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4864 client_1_config, std::move(client_1_deps), client_2_config,
4865 std::move(client_2_deps)));
4866 ConnectFakeSignaling();
4867
4868 // Set "offer to receive audio/video" without adding any tracks, so we just
4869 // set up ICE/DTLS with no media.
4870 PeerConnectionInterface::RTCOfferAnswerOptions options;
4871 options.offer_to_receive_audio = 1;
4872 options.offer_to_receive_video = 1;
4873 caller()->SetOfferAnswerOptions(options);
4874 caller()->CreateAndSetAndSignalOffer();
4875 bool wait_res = true;
4876 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
4877 // properly, should be able to just wait for a state of "failed" instead of
4878 // waiting a fixed 10 seconds.
4879 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
4880 ASSERT_FALSE(wait_res);
4881
4882 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4883 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004884}
4885
Qingsi Wang25ec8882019-11-15 12:33:05 -08004886// Test that the injected ICE transport factory is used to create ICE transports
4887// for WebRTC connections.
4888TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
4889 PeerConnectionInterface::RTCConfiguration default_config;
4890 PeerConnectionDependencies dependencies(nullptr);
4891 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
4892 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
4893 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02004894 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
4895 std::move(dependencies), nullptr,
4896 /*reset_encoder_factory=*/false,
4897 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08004898 ASSERT_TRUE(wrapper);
4899 wrapper->CreateDataChannel();
4900 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
4901 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
4902 wrapper->pc()->SetLocalDescription(observer,
4903 wrapper->CreateOfferAndWait().release());
4904}
4905
deadbeefc964d0b2017-04-03 10:03:35 -07004906// Test that audio and video flow end-to-end when codec names don't use the
4907// expected casing, given that they're supposed to be case insensitive. To test
4908// this, all but one codec is removed from each media description, and its
4909// casing is changed.
4910//
4911// In the past, this has regressed and caused crashes/black video, due to the
4912// fact that code at some layers was doing case-insensitive comparisons and
4913// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004914TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07004915 ASSERT_TRUE(CreatePeerConnectionWrappers());
4916 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004917 caller()->AddAudioVideoTracks();
4918 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07004919
4920 // Remove all but one audio/video codec (opus and VP8), and change the
4921 // casing of the caller's generated offer.
4922 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
4923 cricket::AudioContentDescription* audio =
4924 GetFirstAudioContentDescription(description);
4925 ASSERT_NE(nullptr, audio);
4926 auto audio_codecs = audio->codecs();
4927 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
4928 [](const cricket::AudioCodec& codec) {
4929 return codec.name != "opus";
4930 }),
4931 audio_codecs.end());
4932 ASSERT_EQ(1u, audio_codecs.size());
4933 audio_codecs[0].name = "OpUs";
4934 audio->set_codecs(audio_codecs);
4935
4936 cricket::VideoContentDescription* video =
4937 GetFirstVideoContentDescription(description);
4938 ASSERT_NE(nullptr, video);
4939 auto video_codecs = video->codecs();
4940 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
4941 [](const cricket::VideoCodec& codec) {
4942 return codec.name != "VP8";
4943 }),
4944 video_codecs.end());
4945 ASSERT_EQ(1u, video_codecs.size());
4946 video_codecs[0].name = "vP8";
4947 video->set_codecs(video_codecs);
4948 });
4949
4950 caller()->CreateAndSetAndSignalOffer();
4951 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4952
4953 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004954 MediaExpectations media_expectations;
4955 media_expectations.ExpectBidirectionalAudioAndVideo();
4956 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07004957}
4958
Jonas Oreland49ac5952018-09-26 16:04:32 +02004959TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07004960 ASSERT_TRUE(CreatePeerConnectionWrappers());
4961 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004962 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07004963 caller()->CreateAndSetAndSignalOffer();
4964 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07004965 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004966 MediaExpectations media_expectations;
4967 media_expectations.CalleeExpectsSomeAudio(1);
4968 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02004969 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07004970 auto receiver = callee()->pc()->GetReceivers()[0];
4971 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02004972 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07004973 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4974 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02004975 sources[0].source_id());
4976 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
4977}
4978
4979TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
4980 ASSERT_TRUE(CreatePeerConnectionWrappers());
4981 ConnectFakeSignaling();
4982 caller()->AddVideoTrack();
4983 caller()->CreateAndSetAndSignalOffer();
4984 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4985 // Wait for one video frame to be received by the callee.
4986 MediaExpectations media_expectations;
4987 media_expectations.CalleeExpectsSomeVideo(1);
4988 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4989 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
4990 auto receiver = callee()->pc()->GetReceivers()[0];
4991 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
4992 auto sources = receiver->GetSources();
4993 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02004994 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02004995 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
4996 sources[0].source_id());
4997 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07004998}
4999
deadbeef2f425aa2017-04-14 10:41:32 -07005000// Test that if a track is removed and added again with a different stream ID,
5001// the new stream ID is successfully communicated in SDP and media continues to
5002// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005003// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
5004// it will not reuse a transceiver that has already been sending. After creating
5005// a new transceiver it tries to create an offer with two senders of the same
5006// track ids and it fails.
5007TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07005008 ASSERT_TRUE(CreatePeerConnectionWrappers());
5009 ConnectFakeSignaling();
5010
deadbeef2f425aa2017-04-14 10:41:32 -07005011 // Add track using stream 1, do offer/answer.
5012 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
5013 caller()->CreateLocalAudioTrack();
5014 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07005015 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07005016 caller()->CreateAndSetAndSignalOffer();
5017 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005018 {
5019 MediaExpectations media_expectations;
5020 media_expectations.CalleeExpectsSomeAudio(1);
5021 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5022 }
deadbeef2f425aa2017-04-14 10:41:32 -07005023 // Remove the sender, and create a new one with the new stream.
5024 caller()->pc()->RemoveTrack(sender);
Steve Antond78323f2018-07-11 11:13:44 -07005025 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07005026 caller()->CreateAndSetAndSignalOffer();
5027 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5028 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005029 {
5030 MediaExpectations media_expectations;
5031 media_expectations.CalleeExpectsSomeAudio();
5032 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5033 }
deadbeef2f425aa2017-04-14 10:41:32 -07005034}
5035
Seth Hampson2f0d7022018-02-20 11:54:42 -08005036TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02005037 ASSERT_TRUE(CreatePeerConnectionWrappers());
5038 ConnectFakeSignaling();
5039
Mirko Bonadei317a1f02019-09-17 17:06:18 +02005040 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02005041 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
5042 ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true));
Elad Alon99c3fe52017-10-13 16:29:40 +02005043 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01005044 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
5045 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02005046
Steve Anton15324772018-01-16 10:26:49 -08005047 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02005048 caller()->CreateAndSetAndSignalOffer();
5049 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5050}
5051
Steve Antonede9ca52017-10-16 13:04:27 -07005052// Test that if candidates are only signaled by applying full session
5053// descriptions (instead of using AddIceCandidate), the peers can connect to
5054// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005055TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07005056 ASSERT_TRUE(CreatePeerConnectionWrappers());
5057 // Each side will signal the session descriptions but not candidates.
5058 ConnectFakeSignalingForSdpOnly();
5059
5060 // Add audio video track and exchange the initial offer/answer with media
5061 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08005062 caller()->AddAudioVideoTracks();
5063 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07005064 caller()->CreateAndSetAndSignalOffer();
5065
5066 // Wait for all candidates to be gathered on both the caller and callee.
5067 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
5068 caller()->ice_gathering_state(), kDefaultTimeout);
5069 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
5070 callee()->ice_gathering_state(), kDefaultTimeout);
5071
5072 // The candidates will now be included in the session description, so
5073 // signaling them will start the ICE connection.
5074 caller()->CreateAndSetAndSignalOffer();
5075 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5076
5077 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005078 MediaExpectations media_expectations;
5079 media_expectations.ExpectBidirectionalAudioAndVideo();
5080 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07005081}
5082
henrika5f6bf242017-11-01 11:06:56 +01005083// Test that SetAudioPlayout can be used to disable audio playout from the
5084// start, then later enable it. This may be useful, for example, if the caller
5085// needs to play a local ringtone until some event occurs, after which it
5086// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005087TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01005088 ASSERT_TRUE(CreatePeerConnectionWrappers());
5089 ConnectFakeSignaling();
5090
5091 // Set up audio-only call where audio playout is disabled on caller's side.
5092 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08005093 caller()->AddAudioTrack();
5094 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01005095 caller()->CreateAndSetAndSignalOffer();
5096 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5097
5098 // Pump messages for a second.
5099 WAIT(false, 1000);
5100 // Since audio playout is disabled, the caller shouldn't have received
5101 // anything (at the playout level, at least).
5102 EXPECT_EQ(0, caller()->audio_frames_received());
5103 // As a sanity check, make sure the callee (for which playout isn't disabled)
5104 // did still see frames on its audio level.
5105 ASSERT_GT(callee()->audio_frames_received(), 0);
5106
5107 // Enable playout again, and ensure audio starts flowing.
5108 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005109 MediaExpectations media_expectations;
5110 media_expectations.ExpectBidirectionalAudio();
5111 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01005112}
5113
5114double GetAudioEnergyStat(PeerConnectionWrapper* pc) {
5115 auto report = pc->NewGetStats();
5116 auto track_stats_list =
5117 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
5118 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
5119 for (const auto* track_stats : track_stats_list) {
5120 if (track_stats->remote_source.is_defined() &&
5121 *track_stats->remote_source) {
5122 remote_track_stats = track_stats;
5123 break;
5124 }
5125 }
5126
5127 if (!remote_track_stats->total_audio_energy.is_defined()) {
5128 return 0.0;
5129 }
5130 return *remote_track_stats->total_audio_energy;
5131}
5132
5133// Test that if audio playout is disabled via the SetAudioPlayout() method, then
5134// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005135TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01005136 DisableAudioPlayoutStillGeneratesAudioStats) {
5137 ASSERT_TRUE(CreatePeerConnectionWrappers());
5138 ConnectFakeSignaling();
5139
5140 // Set up audio-only call where playout is disabled but audio-processing is
5141 // still active.
Steve Anton15324772018-01-16 10:26:49 -08005142 caller()->AddAudioTrack();
5143 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01005144 caller()->pc()->SetAudioPlayout(false);
5145
5146 caller()->CreateAndSetAndSignalOffer();
5147 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5148
5149 // Wait for the callee to receive audio stats.
5150 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
5151}
5152
henrika4f167df2017-11-01 14:45:55 +01005153// Test that SetAudioRecording can be used to disable audio recording from the
5154// start, then later enable it. This may be useful, for example, if the caller
5155// wants to ensure that no audio resources are active before a certain state
5156// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005157TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01005158 ASSERT_TRUE(CreatePeerConnectionWrappers());
5159 ConnectFakeSignaling();
5160
5161 // Set up audio-only call where audio recording is disabled on caller's side.
5162 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08005163 caller()->AddAudioTrack();
5164 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01005165 caller()->CreateAndSetAndSignalOffer();
5166 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5167
5168 // Pump messages for a second.
5169 WAIT(false, 1000);
5170 // Since caller has disabled audio recording, the callee shouldn't have
5171 // received anything.
5172 EXPECT_EQ(0, callee()->audio_frames_received());
5173 // As a sanity check, make sure the caller did still see frames on its
5174 // audio level since audio recording is enabled on the calle side.
5175 ASSERT_GT(caller()->audio_frames_received(), 0);
5176
5177 // Enable audio recording again, and ensure audio starts flowing.
5178 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005179 MediaExpectations media_expectations;
5180 media_expectations.ExpectBidirectionalAudio();
5181 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01005182}
5183
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005184// Test that after closing PeerConnections, they stop sending any packets (ICE,
5185// DTLS, RTP...).
Seth Hampson2f0d7022018-02-20 11:54:42 -08005186TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005187 // Set up audio/video/data, wait for some frames to be received.
5188 ASSERT_TRUE(CreatePeerConnectionWrappers());
5189 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08005190 caller()->AddAudioVideoTracks();
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005191#ifdef WEBRTC_HAVE_SCTP
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005192 caller()->CreateDataChannel();
5193#endif
5194 caller()->CreateAndSetAndSignalOffer();
5195 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005196 MediaExpectations media_expectations;
5197 media_expectations.CalleeExpectsSomeAudioAndVideo();
5198 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005199 // Close PeerConnections.
Steve Antond91969e2019-05-30 12:27:03 -07005200 ClosePeerConnections();
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005201 // Pump messages for a second, and ensure no new packets end up sent.
5202 uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
5203 WAIT(false, 1000);
5204 uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
5205 EXPECT_EQ(sent_packets_a, sent_packets_b);
5206}
5207
Steve Anton7eca0932018-03-30 15:18:41 -07005208// Test that transport stats are generated by the RTCStatsCollector for a
5209// connection that only involves data channels. This is a regression test for
5210// crbug.com/826972.
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005211#ifdef WEBRTC_HAVE_SCTP
Steve Anton7eca0932018-03-30 15:18:41 -07005212TEST_P(PeerConnectionIntegrationTest,
5213 TransportStatsReportedForDataChannelOnlyConnection) {
5214 ASSERT_TRUE(CreatePeerConnectionWrappers());
5215 ConnectFakeSignaling();
5216 caller()->CreateDataChannel();
5217
5218 caller()->CreateAndSetAndSignalOffer();
5219 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5220 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
5221
5222 auto caller_report = caller()->NewGetStats();
5223 EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
5224 auto callee_report = callee()->NewGetStats();
5225 EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
5226}
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005227#endif // WEBRTC_HAVE_SCTP
Steve Anton7eca0932018-03-30 15:18:41 -07005228
Qingsi Wang7685e862018-06-11 20:15:46 -07005229TEST_P(PeerConnectionIntegrationTest,
5230 IceEventsGeneratedAndLoggedInRtcEventLog) {
5231 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
5232 ConnectFakeSignaling();
5233 PeerConnectionInterface::RTCOfferAnswerOptions options;
5234 options.offer_to_receive_audio = 1;
5235 caller()->SetOfferAnswerOptions(options);
5236 caller()->CreateAndSetAndSignalOffer();
5237 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
5238 ASSERT_NE(nullptr, caller()->event_log_factory());
5239 ASSERT_NE(nullptr, callee()->event_log_factory());
5240 webrtc::FakeRtcEventLog* caller_event_log =
5241 static_cast<webrtc::FakeRtcEventLog*>(
5242 caller()->event_log_factory()->last_log_created());
5243 webrtc::FakeRtcEventLog* callee_event_log =
5244 static_cast<webrtc::FakeRtcEventLog*>(
5245 callee()->event_log_factory()->last_log_created());
5246 ASSERT_NE(nullptr, caller_event_log);
5247 ASSERT_NE(nullptr, callee_event_log);
5248 int caller_ice_config_count = caller_event_log->GetEventCount(
5249 webrtc::RtcEvent::Type::IceCandidatePairConfig);
5250 int caller_ice_event_count = caller_event_log->GetEventCount(
5251 webrtc::RtcEvent::Type::IceCandidatePairEvent);
5252 int callee_ice_config_count = callee_event_log->GetEventCount(
5253 webrtc::RtcEvent::Type::IceCandidatePairConfig);
5254 int callee_ice_event_count = callee_event_log->GetEventCount(
5255 webrtc::RtcEvent::Type::IceCandidatePairEvent);
5256 EXPECT_LT(0, caller_ice_config_count);
5257 EXPECT_LT(0, caller_ice_event_count);
5258 EXPECT_LT(0, callee_ice_config_count);
5259 EXPECT_LT(0, callee_ice_event_count);
5260}
5261
Qingsi Wangc129c352019-04-18 10:41:58 -07005262TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07005263 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
5264 3478};
5265 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
5266
5267 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
5268
5269 webrtc::PeerConnectionInterface::IceServer ice_server;
5270 ice_server.urls.push_back("turn:88.88.88.0:3478");
5271 ice_server.username = "test";
5272 ice_server.password = "test";
5273
5274 PeerConnectionInterface::RTCConfiguration caller_config;
5275 caller_config.servers.push_back(ice_server);
5276 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5277 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005278 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07005279
5280 PeerConnectionInterface::RTCConfiguration callee_config;
5281 callee_config.servers.push_back(ice_server);
5282 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5283 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005284 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07005285
5286 ASSERT_TRUE(
5287 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5288
5289 // Do normal offer/answer and wait for ICE to complete.
5290 ConnectFakeSignaling();
5291 caller()->AddAudioVideoTracks();
5292 callee()->AddAudioVideoTracks();
5293 caller()->CreateAndSetAndSignalOffer();
5294 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5295 // Since we are doing continual gathering, the ICE transport does not reach
5296 // kIceGatheringComplete (see
5297 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
5298 // kIceConnectionComplete.
5299 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
5300 caller()->ice_connection_state(), kDefaultTimeout);
5301 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
5302 callee()->ice_connection_state(), kDefaultTimeout);
5303 // Note that we cannot use the metric
5304 // |WebRTC.PeerConnection.CandidatePairType_UDP| in this test since this
5305 // metric is only populated when we reach kIceConnectionComplete in the
5306 // current implementation.
5307 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
5308 caller()->last_candidate_gathered().type());
5309 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
5310 callee()->last_candidate_gathered().type());
5311
5312 // Loosen the caller's candidate filter.
5313 caller_config = caller()->pc()->GetConfiguration();
5314 caller_config.type = webrtc::PeerConnectionInterface::kAll;
5315 caller()->pc()->SetConfiguration(caller_config);
5316 // We should have gathered a new host candidate.
5317 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
5318 caller()->last_candidate_gathered().type(), kDefaultTimeout);
5319
5320 // Loosen the callee's candidate filter.
5321 callee_config = callee()->pc()->GetConfiguration();
5322 callee_config.type = webrtc::PeerConnectionInterface::kAll;
5323 callee()->pc()->SetConfiguration(callee_config);
5324 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
5325 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02005326
5327 // Create an offer and verify that it does not contain an ICE restart (i.e new
5328 // ice credentials).
5329 std::string caller_ufrag_pre_offer = caller()
5330 ->pc()
5331 ->local_description()
5332 ->description()
5333 ->transport_infos()[0]
5334 .description.ice_ufrag;
5335 caller()->CreateAndSetAndSignalOffer();
5336 std::string caller_ufrag_post_offer = caller()
5337 ->pc()
5338 ->local_description()
5339 ->description()
5340 ->transport_infos()[0]
5341 .description.ice_ufrag;
5342 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07005343}
5344
Eldar Relloda13ea22019-06-01 12:23:43 +03005345TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03005346 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
5347 3478};
5348 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
5349
5350 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
5351
5352 webrtc::PeerConnectionInterface::IceServer ice_server;
5353 ice_server.urls.push_back("turn:88.88.88.0:3478");
5354 ice_server.username = "test";
5355 ice_server.password = "123";
5356
5357 PeerConnectionInterface::RTCConfiguration caller_config;
5358 caller_config.servers.push_back(ice_server);
5359 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5360 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5361
5362 PeerConnectionInterface::RTCConfiguration callee_config;
5363 callee_config.servers.push_back(ice_server);
5364 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5365 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5366
5367 ASSERT_TRUE(
5368 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5369
5370 // Do normal offer/answer and wait for ICE to complete.
5371 ConnectFakeSignaling();
5372 caller()->AddAudioVideoTracks();
5373 callee()->AddAudioVideoTracks();
5374 caller()->CreateAndSetAndSignalOffer();
5375 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5376 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
5377 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
5378 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02005379 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03005380}
5381
Eldar Rellofa8019c2020-05-14 11:59:33 +03005382TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
5383 webrtc::PeerConnectionInterface::IceServer ice_server;
5384 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
5385 ice_server.username = "test";
5386 ice_server.password = "test";
5387
5388 PeerConnectionInterface::RTCConfiguration caller_config;
5389 caller_config.servers.push_back(ice_server);
5390 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5391 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5392
5393 PeerConnectionInterface::RTCConfiguration callee_config;
5394 callee_config.servers.push_back(ice_server);
5395 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5396 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5397
5398 ASSERT_TRUE(
5399 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5400
5401 // Do normal offer/answer and wait for ICE to complete.
5402 ConnectFakeSignaling();
5403 caller()->AddAudioVideoTracks();
5404 callee()->AddAudioVideoTracks();
5405 caller()->CreateAndSetAndSignalOffer();
5406 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5407 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
5408 EXPECT_EQ(caller()->error_event().address, "");
5409}
5410
Eldar Rello5ab79e62019-10-09 18:29:44 +03005411TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5412 AudioKeepsFlowingAfterImplicitRollback) {
5413 PeerConnectionInterface::RTCConfiguration config;
5414 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5415 config.enable_implicit_rollback = true;
5416 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5417 ConnectFakeSignaling();
5418 caller()->AddAudioTrack();
5419 callee()->AddAudioTrack();
5420 caller()->CreateAndSetAndSignalOffer();
5421 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5422 MediaExpectations media_expectations;
5423 media_expectations.ExpectBidirectionalAudio();
5424 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5425 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
5426 caller()->AddVideoTrack();
5427 callee()->AddVideoTrack();
5428 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
5429 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5430 callee()->pc()->SetLocalDescription(observer,
5431 callee()->CreateOfferAndWait().release());
5432 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
5433 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
5434 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5435 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5436}
5437
5438TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5439 ImplicitRollbackVisitsStableState) {
5440 RTCConfiguration config;
5441 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5442 config.enable_implicit_rollback = true;
5443
5444 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5445
5446 rtc::scoped_refptr<MockSetSessionDescriptionObserver> sld_observer(
5447 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5448 callee()->pc()->SetLocalDescription(sld_observer,
5449 callee()->CreateOfferAndWait().release());
5450 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
5451 EXPECT_EQ(sld_observer->error(), "");
5452
5453 rtc::scoped_refptr<MockSetSessionDescriptionObserver> srd_observer(
5454 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
5455 callee()->pc()->SetRemoteDescription(
5456 srd_observer, caller()->CreateOfferAndWait().release());
5457 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
5458 EXPECT_EQ(srd_observer->error(), "");
5459
5460 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
5461 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
5462 PeerConnectionInterface::kStable,
5463 PeerConnectionInterface::kHaveRemoteOffer));
5464}
5465
Eldar Rellobd9c33a2020-10-01 17:52:45 +03005466TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5467 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
5468 ASSERT_TRUE(CreatePeerConnectionWrappers());
5469 ConnectFakeSignaling();
5470 caller()->AddVideoTrack();
5471 callee()->AddVideoTrack();
5472 auto munger = [](cricket::SessionDescription* desc) {
5473 cricket::VideoContentDescription* video =
5474 GetFirstVideoContentDescription(desc);
5475 auto codecs = video->codecs();
5476 for (auto&& codec : codecs) {
5477 if (codec.name == "H264") {
5478 std::string value;
5479 // The parameter is not supposed to be present in SDP by default.
5480 EXPECT_FALSE(
5481 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
5482 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
5483 std::string(""));
5484 }
5485 }
5486 video->set_codecs(codecs);
5487 };
5488 // Munge local offer for SLD.
5489 caller()->SetGeneratedSdpMunger(munger);
5490 // Munge remote answer for SRD.
5491 caller()->SetReceivedSdpMunger(munger);
5492 caller()->CreateAndSetAndSignalOffer();
5493 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5494 // Observe that after munging the parameter is present in generated SDP.
5495 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
5496 cricket::VideoContentDescription* video =
5497 GetFirstVideoContentDescription(desc);
5498 for (auto&& codec : video->codecs()) {
5499 if (codec.name == "H264") {
5500 std::string value;
5501 EXPECT_TRUE(
5502 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
5503 }
5504 }
5505 });
5506 caller()->CreateOfferAndWait();
5507}
5508
Harald Alvestrand1a9be302020-12-11 14:53:59 +00005509TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00005510 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00005511 PeerConnectionInterface::RTCConfiguration config;
5512 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5513 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5514 ConnectFakeSignaling();
5515 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
5516
5517 caller()->CreateAndSetAndSignalOffer();
5518 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5519 int current_size = caller()->pc()->GetTransceivers().size();
5520 // Add more tracks until we get close to having issues.
5521 // Issues have been seen at:
5522 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005523 // - 16 tracks on android_arm_dbg (flaky)
5524 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00005525 // Double the number of tracks
5526 for (int i = 0; i < current_size; i++) {
5527 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
5528 }
5529 current_size = caller()->pc()->GetTransceivers().size();
5530 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
5531 auto start_time_ms = rtc::TimeMillis();
5532 caller()->CreateAndSetAndSignalOffer();
5533 // We want to stop when the time exceeds one second.
5534 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5535 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
5536 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
5537 ASSERT_GT(1000, elapsed_time_ms)
5538 << "Audio transceivers: Negotiation took too long after "
5539 << current_size << " tracks added";
5540 }
5541}
5542
5543TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5544 RenegotiateManyVideoTransceivers) {
5545 PeerConnectionInterface::RTCConfiguration config;
5546 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5547 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5548 ConnectFakeSignaling();
5549 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
5550
5551 caller()->CreateAndSetAndSignalOffer();
5552 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5553 int current_size = caller()->pc()->GetTransceivers().size();
5554 // Add more tracks until we get close to having issues.
5555 // Issues have been seen at:
5556 // - 96 on a Linux workstation
5557 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
5558 // - 32 on android_arm64_rel and linux_dbg bots
5559 while (current_size < 16) {
5560 // Double the number of tracks
5561 for (int i = 0; i < current_size; i++) {
5562 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
5563 }
5564 current_size = caller()->pc()->GetTransceivers().size();
5565 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
5566 auto start_time_ms = rtc::TimeMillis();
5567 caller()->CreateAndSetAndSignalOffer();
5568 // We want to stop when the time exceeds one second.
5569 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5570 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
5571 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
5572 ASSERT_GT(1000, elapsed_time_ms)
5573 << "Video transceivers: Negotiation took too long after "
5574 << current_size << " tracks added";
5575 }
5576}
5577
Harald Alvestrand94324f22021-01-13 12:31:53 +00005578TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5579 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
5580 PeerConnectionInterface::RTCConfiguration config;
5581 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
5582 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5583 ConnectFakeSignaling();
5584 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005585 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00005586 caller()->CreateAndSetAndSignalOffer();
5587 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5588 // Wait until we can see the audio flowing.
5589 MediaExpectations media_expectations;
5590 media_expectations.CalleeExpectsSomeAudio();
5591 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5592
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005593 // Get the baseline numbers for audio_packets and audio_delay
5594 // in both directions.
5595 caller()->StartWatchingDelayStats();
5596 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00005597
5598 int current_size = caller()->pc()->GetTransceivers().size();
5599 // Add more tracks until we get close to having issues.
5600 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005601 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00005602 // Double the number of tracks
5603 for (int i = 0; i < current_size; i++) {
5604 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
5605 }
5606 current_size = caller()->pc()->GetTransceivers().size();
5607 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
5608 auto start_time_ms = rtc::TimeMillis();
5609 caller()->CreateAndSetAndSignalOffer();
5610 // We want to stop when the time exceeds one second.
5611 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5612 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
5613 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
5614 // This is a guard against the test using excessive amounts of time.
5615 ASSERT_GT(5000, elapsed_time_ms)
5616 << "Video transceivers: Negotiation took too long after "
5617 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00005618 caller()->UpdateDelayStats("caller reception", current_size);
5619 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00005620 }
5621}
5622
Mirko Bonadeic84f6612019-01-31 12:20:57 +01005623INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
5624 PeerConnectionIntegrationTest,
5625 Values(SdpSemantics::kPlanB,
5626 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-17 17:41:02 -08005627
Yves Gerey100fe632020-01-17 19:15:53 +01005628INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
5629 PeerConnectionIntegrationTestWithFakeClock,
5630 Values(SdpSemantics::kPlanB,
5631 SdpSemantics::kUnifiedPlan));
5632
Steve Anton74255ff2018-01-24 18:32:57 -08005633// Tests that verify interoperability between Plan B and Unified Plan
5634// PeerConnections.
5635class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08005636 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08005637 public ::testing::WithParamInterface<
5638 std::tuple<SdpSemantics, SdpSemantics>> {
5639 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08005640 // Setting the SdpSemantics for the base test to kDefault does not matter
5641 // because we specify not to use the test semantics when creating
5642 // PeerConnectionWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08005643 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07005644 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08005645 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08005646 callee_semantics_(std::get<1>(GetParam())) {}
5647
5648 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07005649 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
5650 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08005651 }
5652
5653 const SdpSemantics caller_semantics_;
5654 const SdpSemantics callee_semantics_;
5655};
5656
5657TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
5658 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5659 ConnectFakeSignaling();
5660
5661 caller()->CreateAndSetAndSignalOffer();
5662 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5663}
5664
5665TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
5666 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5667 ConnectFakeSignaling();
5668 auto audio_sender = caller()->AddAudioTrack();
5669
5670 caller()->CreateAndSetAndSignalOffer();
5671 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5672
5673 // Verify that one audio receiver has been created on the remote and that it
5674 // has the same track ID as the sending track.
5675 auto receivers = callee()->pc()->GetReceivers();
5676 ASSERT_EQ(1u, receivers.size());
5677 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
5678 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
5679
Seth Hampson2f0d7022018-02-20 11:54:42 -08005680 MediaExpectations media_expectations;
5681 media_expectations.CalleeExpectsSomeAudio();
5682 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005683}
5684
5685TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
5686 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5687 ConnectFakeSignaling();
5688 auto video_sender = caller()->AddVideoTrack();
5689 auto audio_sender = caller()->AddAudioTrack();
5690
5691 caller()->CreateAndSetAndSignalOffer();
5692 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5693
5694 // Verify that one audio and one video receiver have been created on the
5695 // remote and that they have the same track IDs as the sending tracks.
5696 auto audio_receivers =
5697 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
5698 ASSERT_EQ(1u, audio_receivers.size());
5699 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
5700 auto video_receivers =
5701 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
5702 ASSERT_EQ(1u, video_receivers.size());
5703 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
5704
Seth Hampson2f0d7022018-02-20 11:54:42 -08005705 MediaExpectations media_expectations;
5706 media_expectations.CalleeExpectsSomeAudioAndVideo();
5707 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005708}
5709
5710TEST_P(PeerConnectionIntegrationInteropTest,
5711 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
5712 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5713 ConnectFakeSignaling();
5714 caller()->AddAudioVideoTracks();
5715 callee()->AddAudioVideoTracks();
5716
5717 caller()->CreateAndSetAndSignalOffer();
5718 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5719
Seth Hampson2f0d7022018-02-20 11:54:42 -08005720 MediaExpectations media_expectations;
5721 media_expectations.ExpectBidirectionalAudioAndVideo();
5722 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005723}
5724
5725TEST_P(PeerConnectionIntegrationInteropTest,
5726 ReverseRolesOneAudioLocalToOneVideoRemote) {
5727 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5728 ConnectFakeSignaling();
5729 caller()->AddAudioTrack();
5730 callee()->AddVideoTrack();
5731
5732 caller()->CreateAndSetAndSignalOffer();
5733 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5734
5735 // Verify that only the audio track has been negotiated.
5736 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
5737 // Might also check that the callee's NegotiationNeeded flag is set.
5738
5739 // Reverse roles.
5740 callee()->CreateAndSetAndSignalOffer();
5741 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5742
Seth Hampson2f0d7022018-02-20 11:54:42 -08005743 MediaExpectations media_expectations;
5744 media_expectations.CallerExpectsSomeVideo();
5745 media_expectations.CalleeExpectsSomeAudio();
5746 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005747}
5748
Mirko Bonadeic84f6612019-01-31 12:20:57 +01005749INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07005750 PeerConnectionIntegrationTest,
5751 PeerConnectionIntegrationInteropTest,
5752 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
5753 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
5754
5755// Test that if the Unified Plan side offers two video tracks then the Plan B
5756// side will only see the first one and ignore the second.
5757TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07005758 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
5759 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08005760 ConnectFakeSignaling();
5761 auto first_sender = caller()->AddVideoTrack();
5762 caller()->AddVideoTrack();
5763
5764 caller()->CreateAndSetAndSignalOffer();
5765 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5766
5767 // Verify that there is only one receiver and it corresponds to the first
5768 // added track.
5769 auto receivers = callee()->pc()->GetReceivers();
5770 ASSERT_EQ(1u, receivers.size());
5771 EXPECT_TRUE(receivers[0]->track()->enabled());
5772 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
5773
Seth Hampson2f0d7022018-02-20 11:54:42 -08005774 MediaExpectations media_expectations;
5775 media_expectations.CalleeExpectsSomeVideo();
5776 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005777}
5778
Steve Anton2bed3972019-01-04 17:04:30 -08005779// Test that if the initial offer tagged BUNDLE section is rejected due to its
5780// associated RtpTransceiver being stopped and another transceiver is added,
5781// then renegotiation causes the callee to receive the new video track without
5782// error.
5783// This is a regression test for bugs.webrtc.org/9954
5784TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5785 ReOfferWithStoppedBundleTaggedTransceiver) {
5786 RTCConfiguration config;
5787 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
5788 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5789 ConnectFakeSignaling();
5790 auto audio_transceiver_or_error =
5791 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5792 ASSERT_TRUE(audio_transceiver_or_error.ok());
5793 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5794
5795 caller()->CreateAndSetAndSignalOffer();
5796 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5797 {
5798 MediaExpectations media_expectations;
5799 media_expectations.CalleeExpectsSomeAudio();
5800 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5801 }
5802
Harald Alvestrand6060df52020-08-11 09:54:02 +02005803 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08005804 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
5805
5806 caller()->CreateAndSetAndSignalOffer();
5807 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5808 {
5809 MediaExpectations media_expectations;
5810 media_expectations.CalleeExpectsSomeVideo();
5811 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5812 }
5813}
5814
Harald Alvestrandbedb6052020-08-20 14:50:10 +02005815TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5816 StopTransceiverRemovesDtlsTransports) {
5817 RTCConfiguration config;
5818 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5819 ConnectFakeSignaling();
5820 auto audio_transceiver_or_error =
5821 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5822 ASSERT_TRUE(audio_transceiver_or_error.ok());
5823 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5824
5825 caller()->CreateAndSetAndSignalOffer();
5826 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5827
5828 audio_transceiver->StopStandard();
5829 caller()->CreateAndSetAndSignalOffer();
5830 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5831 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
5832 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
5833 caller()->pc()->ice_gathering_state());
5834 EXPECT_THAT(caller()->ice_gathering_state_history(),
5835 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
5836 PeerConnectionInterface::kIceGatheringComplete,
5837 PeerConnectionInterface::kIceGatheringNew));
5838}
5839
Harald Alvestrand1ee33252020-09-24 13:31:15 +00005840TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00005841 StopTransceiverStopsAndRemovesTransceivers) {
5842 RTCConfiguration config;
5843 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5844 ConnectFakeSignaling();
5845 auto audio_transceiver_or_error =
5846 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5847 ASSERT_TRUE(audio_transceiver_or_error.ok());
5848 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
5849
5850 caller()->CreateAndSetAndSignalOffer();
5851 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5852 caller_transceiver->StopStandard();
5853
5854 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
5855 caller()->CreateAndSetAndSignalOffer();
5856 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5857 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
5858 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
5859 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
5860 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
5861 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
5862 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
5863 EXPECT_TRUE(caller_transceiver->stopped());
5864 EXPECT_TRUE(callee_transceiver->stopped());
5865}
5866
5867TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00005868 StopTransceiverEndsIncomingAudioTrack) {
5869 RTCConfiguration config;
5870 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5871 ConnectFakeSignaling();
5872 auto audio_transceiver_or_error =
5873 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5874 ASSERT_TRUE(audio_transceiver_or_error.ok());
5875 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5876
5877 caller()->CreateAndSetAndSignalOffer();
5878 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5879 auto caller_track = audio_transceiver->receiver()->track();
5880 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
5881 audio_transceiver->StopStandard();
5882 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
5883 caller_track->state());
5884 caller()->CreateAndSetAndSignalOffer();
5885 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5886 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
5887 callee_track->state());
5888}
5889
5890TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5891 StopTransceiverEndsIncomingVideoTrack) {
5892 RTCConfiguration config;
5893 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5894 ConnectFakeSignaling();
5895 auto audio_transceiver_or_error =
5896 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
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
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005913#ifdef WEBRTC_HAVE_SCTP
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02005914
5915TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5916 EndToEndCallWithBundledSctpDataChannel) {
5917 ASSERT_TRUE(CreatePeerConnectionWrappers());
5918 ConnectFakeSignaling();
5919 caller()->CreateDataChannel();
5920 caller()->AddAudioVideoTracks();
5921 callee()->AddAudioVideoTracks();
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02005922 caller()->CreateAndSetAndSignalOffer();
5923 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Harald Alvestrand17ea0682019-12-13 11:51:04 +01005924 ASSERT_EQ_WAIT(SctpTransportState::kConnected,
5925 caller()->pc()->GetSctpTransport()->Information().state(),
5926 kDefaultTimeout);
5927 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
5928 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5929}
5930
5931TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5932 EndToEndCallWithDataChannelOnlyConnects) {
5933 ASSERT_TRUE(CreatePeerConnectionWrappers());
5934 ConnectFakeSignaling();
5935 caller()->CreateDataChannel();
5936 caller()->CreateAndSetAndSignalOffer();
5937 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5938 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
5939 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5940 ASSERT_TRUE(caller()->data_observer()->IsOpen());
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02005941}
5942
Harald Alvestrand2697ac12019-12-16 10:37:04 +01005943TEST_F(PeerConnectionIntegrationTestUnifiedPlan, DataChannelClosesWhenClosed) {
5944 ASSERT_TRUE(CreatePeerConnectionWrappers());
5945 ConnectFakeSignaling();
5946 caller()->CreateDataChannel();
5947 caller()->CreateAndSetAndSignalOffer();
5948 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5949 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
5950 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5951 caller()->data_channel()->Close();
5952 ASSERT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
5953}
5954
5955TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5956 DataChannelClosesWhenClosedReverse) {
5957 ASSERT_TRUE(CreatePeerConnectionWrappers());
5958 ConnectFakeSignaling();
5959 caller()->CreateDataChannel();
5960 caller()->CreateAndSetAndSignalOffer();
5961 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5962 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
5963 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5964 callee()->data_channel()->Close();
5965 ASSERT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
5966}
5967
5968TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5969 DataChannelClosesWhenPeerConnectionClosed) {
5970 ASSERT_TRUE(CreatePeerConnectionWrappers());
5971 ConnectFakeSignaling();
5972 caller()->CreateDataChannel();
5973 caller()->CreateAndSetAndSignalOffer();
5974 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5975 ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout);
5976 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
5977 caller()->pc()->Close();
5978 ASSERT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
5979}
5980
Mirko Bonadei5eb43b42021-01-18 13:24:40 +01005981#endif // WEBRTC_HAVE_SCTP
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02005982
deadbeef1dcb1642017-03-29 21:08:16 -07005983} // namespace
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01005984} // namespace webrtc
deadbeef1dcb1642017-03-29 21:08:16 -07005985
5986#endif // if !defined(THREAD_SANITIZER)