blob: 9f406482140e2cbd31057c04d2eb906506c5ed08 [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
Harald Alvestrandf8f7b702022-05-05 13:21:19 +000011// Integration tests for PeerConnection.
12// These tests exercise a full stack over a simulated network.
13//
14// NOTE: If your test takes a while (guideline: more than 5 seconds),
15// do NOT add it here, but instead add it to the file
16// slow_peer_connection_integrationtest.cc
17
Harald Alvestrand39993842021-02-17 09:05:31 +000018#include <stdint.h>
deadbeef1dcb1642017-03-29 21:08:16 -070019
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -070020#include <algorithm>
deadbeef1dcb1642017-03-29 21:08:16 -070021#include <memory>
Harald Alvestrand39993842021-02-17 09:05:31 +000022#include <string>
23#include <tuple>
deadbeef1dcb1642017-03-29 21:08:16 -070024#include <utility>
25#include <vector>
26
Steve Anton64b626b2019-01-28 17:25:26 -080027#include "absl/algorithm/container.h"
Harald Alvestrandf8f7b702022-05-05 13:21:19 +000028#include "absl/strings/string_view.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000029#include "absl/types/optional.h"
30#include "api/async_resolver_factory.h"
31#include "api/candidate.h"
32#include "api/crypto/crypto_options.h"
33#include "api/dtmf_sender_interface.h"
34#include "api/ice_transport_interface.h"
35#include "api/jsep.h"
Steve Anton10542f22019-01-11 09:11:00 -080036#include "api/media_stream_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000037#include "api/media_types.h"
Steve Anton10542f22019-01-11 09:11:00 -080038#include "api/peer_connection_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000039#include "api/rtc_error.h"
40#include "api/rtc_event_log/rtc_event.h"
41#include "api/rtc_event_log/rtc_event_log.h"
42#include "api/rtc_event_log_output.h"
43#include "api/rtp_parameters.h"
Steve Anton10542f22019-01-11 09:11:00 -080044#include "api/rtp_receiver_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000045#include "api/rtp_sender_interface.h"
46#include "api/rtp_transceiver_direction.h"
47#include "api/rtp_transceiver_interface.h"
48#include "api/scoped_refptr.h"
49#include "api/stats/rtc_stats.h"
50#include "api/stats/rtc_stats_report.h"
51#include "api/stats/rtcstats_objects.h"
52#include "api/transport/rtp/rtp_source.h"
Steve Anton10542f22019-01-11 09:11:00 -080053#include "api/uma_metrics.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000054#include "api/units/time_delta.h"
55#include "api/video/video_rotation.h"
56#include "logging/rtc_event_log/fake_rtc_event_log.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070057#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000058#include "media/base/codec.h"
59#include "media/base/media_constants.h"
60#include "media/base/stream_params.h"
Steve Anton10542f22019-01-11 09:11:00 -080061#include "p2p/base/mock_async_resolver.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000062#include "p2p/base/port.h"
63#include "p2p/base/port_allocator.h"
Steve Anton10542f22019-01-11 09:11:00 -080064#include "p2p/base/port_interface.h"
65#include "p2p/base/test_stun_server.h"
66#include "p2p/base/test_turn_customizer.h"
67#include "p2p/base/test_turn_server.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000068#include "p2p/base/transport_description.h"
69#include "p2p/base/transport_info.h"
Steve Anton10542f22019-01-11 09:11:00 -080070#include "pc/media_session.h"
71#include "pc/peer_connection.h"
72#include "pc/peer_connection_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080073#include "pc/session_description.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000074#include "pc/test/fake_periodic_video_source.h"
75#include "pc/test/integration_test_helpers.h"
Steve Anton10542f22019-01-11 09:11:00 -080076#include "pc/test/mock_peer_connection_observers.h"
Jonas Olssonb75d9e92019-02-22 10:33:29 +010077#include "rtc_base/fake_clock.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070078#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080079#include "rtc_base/fake_network.h"
80#include "rtc_base/firewall_socket_server.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020081#include "rtc_base/gunit.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000082#include "rtc_base/helpers.h"
83#include "rtc_base/location.h"
84#include "rtc_base/logging.h"
85#include "rtc_base/ref_counted_object.h"
86#include "rtc_base/socket_address.h"
87#include "rtc_base/ssl_certificate.h"
88#include "rtc_base/ssl_fingerprint.h"
89#include "rtc_base/ssl_identity.h"
90#include "rtc_base/ssl_stream_adapter.h"
Steve Anton10542f22019-01-11 09:11:00 -080091#include "rtc_base/test_certificate_verifier.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000092#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080093#include "rtc_base/time_utils.h"
94#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020095#include "system_wrappers/include/metrics.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000096#include "test/gmock.h"
97#include "test/gtest.h"
deadbeef1dcb1642017-03-29 21:08:16 -070098
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010099namespace webrtc {
Harald Alvestrand39993842021-02-17 09:05:31 +0000100
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +0100101namespace {
102
Seth Hampson2f0d7022018-02-20 11:54:42 -0800103class PeerConnectionIntegrationTest
104 : public PeerConnectionIntegrationBaseTest,
Evan Shrubsole7619b7c2022-03-01 10:42:44 +0100105 public ::testing::WithParamInterface<
106 std::tuple<SdpSemantics, std::string>> {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800107 protected:
108 PeerConnectionIntegrationTest()
Evan Shrubsole7619b7c2022-03-01 10:42:44 +0100109 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam()),
110 std::get<1>(GetParam())) {}
Seth Hampson2f0d7022018-02-20 11:54:42 -0800111};
112
Yves Gerey100fe632020-01-17 19:15:53 +0100113// Fake clock must be set before threads are started to prevent race on
114// Set/GetClockForTesting().
115// To achieve that, multiple inheritance is used as a mixin pattern
116// where order of construction is finely controlled.
117// This also ensures peerconnection is closed before switching back to non-fake
118// clock, avoiding other races and DCHECK failures such as in rtp_sender.cc.
119class FakeClockForTest : public rtc::ScopedFakeClock {
120 protected:
121 FakeClockForTest() {
122 // Some things use a time of "0" as a special value, so we need to start out
123 // the fake clock at a nonzero time.
124 // TODO(deadbeef): Fix this.
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100125 AdvanceTime(webrtc::TimeDelta::Seconds(1));
Yves Gerey100fe632020-01-17 19:15:53 +0100126 }
127
128 // Explicit handle.
129 ScopedFakeClock& FakeClock() { return *this; }
130};
131
132// Ensure FakeClockForTest is constructed first (see class for rationale).
133class PeerConnectionIntegrationTestWithFakeClock
134 : public FakeClockForTest,
135 public PeerConnectionIntegrationTest {};
136
Seth Hampson2f0d7022018-02-20 11:54:42 -0800137class PeerConnectionIntegrationTestPlanB
138 : public PeerConnectionIntegrationBaseTest {
139 protected:
140 PeerConnectionIntegrationTestPlanB()
Florent Castelli15a38de2022-04-06 00:38:21 +0200141 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB_DEPRECATED) {}
Seth Hampson2f0d7022018-02-20 11:54:42 -0800142};
143
144class PeerConnectionIntegrationTestUnifiedPlan
145 : public PeerConnectionIntegrationBaseTest {
146 protected:
147 PeerConnectionIntegrationTestUnifiedPlan()
148 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
149};
150
deadbeef1dcb1642017-03-29 21:08:16 -0700151// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
152// includes testing that the callback is invoked if an observer is connected
153// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800154TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -0700155 RtpReceiverObserverOnFirstPacketReceived) {
156 ASSERT_TRUE(CreatePeerConnectionWrappers());
157 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800158 caller()->AddAudioVideoTracks();
159 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700160 // Start offer/answer exchange and wait for it to complete.
161 caller()->CreateAndSetAndSignalOffer();
162 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
163 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200164 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
165 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -0700166 // Wait for all "first packet received" callbacks to be fired.
167 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -0800168 absl::c_all_of(caller()->rtp_receiver_observers(),
169 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
170 return o->first_packet_received();
171 }),
deadbeef1dcb1642017-03-29 21:08:16 -0700172 kMaxWaitForFramesMs);
173 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -0800174 absl::c_all_of(callee()->rtp_receiver_observers(),
175 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
176 return o->first_packet_received();
177 }),
deadbeef1dcb1642017-03-29 21:08:16 -0700178 kMaxWaitForFramesMs);
179 // If new observers are set after the first packet was already received, the
180 // callback should still be invoked.
181 caller()->ResetRtpReceiverObservers();
182 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200183 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
184 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -0700185 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -0800186 absl::c_all_of(caller()->rtp_receiver_observers(),
187 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
188 return o->first_packet_received();
189 }));
deadbeef1dcb1642017-03-29 21:08:16 -0700190 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -0800191 absl::c_all_of(callee()->rtp_receiver_observers(),
192 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
193 return o->first_packet_received();
194 }));
deadbeef1dcb1642017-03-29 21:08:16 -0700195}
196
197class DummyDtmfObserver : public DtmfSenderObserverInterface {
198 public:
199 DummyDtmfObserver() : completed_(false) {}
200
201 // Implements DtmfSenderObserverInterface.
202 void OnToneChange(const std::string& tone) override {
203 tones_.push_back(tone);
204 if (tone.empty()) {
205 completed_ = true;
206 }
207 }
208
209 const std::vector<std::string>& tones() const { return tones_; }
210 bool completed() const { return completed_; }
211
212 private:
213 bool completed_;
214 std::vector<std::string> tones_;
215};
216
Artem Titov880fa812021-07-30 22:30:23 +0200217// Assumes `sender` already has an audio track added and the offer/answer
deadbeef1dcb1642017-03-29 21:08:16 -0700218// exchange is done.
Harald Alvestrand39993842021-02-17 09:05:31 +0000219void TestDtmfFromSenderToReceiver(PeerConnectionIntegrationWrapper* sender,
220 PeerConnectionIntegrationWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -0800221 // We should be able to get a DTMF sender from the local sender.
222 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
223 sender->pc()->GetSenders().at(0)->GetDtmfSender();
224 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -0700225 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -0700226 dtmf_sender->RegisterObserver(&observer);
227
228 // Test the DtmfSender object just created.
229 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
230 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
231
232 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
233 std::vector<std::string> tones = {"1", "a", ""};
234 EXPECT_EQ(tones, observer.tones());
235 dtmf_sender->UnregisterObserver();
236 // TODO(deadbeef): Verify the tones were actually received end-to-end.
237}
238
239// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
240// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800241TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -0700242 ASSERT_TRUE(CreatePeerConnectionWrappers());
243 ConnectFakeSignaling();
244 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -0800245 caller()->AddAudioTrack();
246 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700247 caller()->CreateAndSetAndSignalOffer();
248 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -0700249 // DTLS must finish before the DTMF sender can be used reliably.
250 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -0700251 TestDtmfFromSenderToReceiver(caller(), callee());
252 TestDtmfFromSenderToReceiver(callee(), caller());
253}
254
255// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
256// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800257TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -0700258 ASSERT_TRUE(CreatePeerConnectionWrappers());
259 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +0100260
deadbeef1dcb1642017-03-29 21:08:16 -0700261 // Do normal offer/answer and wait for some frames to be received in each
262 // direction.
Steve Anton15324772018-01-16 10:26:49 -0800263 caller()->AddAudioVideoTracks();
264 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700265 caller()->CreateAndSetAndSignalOffer();
266 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800267 MediaExpectations media_expectations;
268 media_expectations.ExpectBidirectionalAudioAndVideo();
269 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Ying Wangef3998f2019-12-09 13:06:53 +0100270 EXPECT_METRIC_LE(
271 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
272 webrtc::kEnumCounterKeyProtocolDtls));
273 EXPECT_METRIC_EQ(
274 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
275 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -0700276}
277
Harald Alvestrandca327932022-04-04 15:37:31 +0000278#if defined(WEBRTC_FUCHSIA)
Harald Alvestrand50b95522021-11-18 10:01:06 +0000279// Uses SDES instead of DTLS for key agreement.
280TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
281 PeerConnectionInterface::RTCConfiguration sdes_config;
282 sdes_config.enable_dtls_srtp.emplace(false);
283 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
284 ConnectFakeSignaling();
285
286 // Do normal offer/answer and wait for some frames to be received in each
287 // direction.
288 caller()->AddAudioVideoTracks();
289 callee()->AddAudioVideoTracks();
290 caller()->CreateAndSetAndSignalOffer();
291 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
292 MediaExpectations media_expectations;
293 media_expectations.ExpectBidirectionalAudioAndVideo();
294 ASSERT_TRUE(ExpectNewFrames(media_expectations));
295 EXPECT_METRIC_LE(
296 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
297 webrtc::kEnumCounterKeyProtocolSdes));
298 EXPECT_METRIC_EQ(
299 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
300 webrtc::kEnumCounterKeyProtocolDtls));
301}
Harald Alvestrandca327932022-04-04 15:37:31 +0000302#endif
Harald Alvestrand50b95522021-11-18 10:01:06 +0000303
Artem Titov880fa812021-07-30 22:30:23 +0200304// Basic end-to-end test specifying the `enable_encrypted_rtp_header_extensions`
Steve Anton9a44b2d2019-07-12 12:58:30 -0700305// option to offer encrypted versions of all header extensions alongside the
306// unencrypted versions.
307TEST_P(PeerConnectionIntegrationTest,
308 EndToEndCallWithEncryptedRtpHeaderExtensions) {
309 CryptoOptions crypto_options;
310 crypto_options.srtp.enable_encrypted_rtp_header_extensions = true;
311 PeerConnectionInterface::RTCConfiguration config;
312 config.crypto_options = crypto_options;
313 // Note: This allows offering >14 RTP header extensions.
314 config.offer_extmap_allow_mixed = true;
315 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
316 ConnectFakeSignaling();
317
318 // Do normal offer/answer and wait for some frames to be received in each
319 // direction.
320 caller()->AddAudioVideoTracks();
321 callee()->AddAudioVideoTracks();
322 caller()->CreateAndSetAndSignalOffer();
323 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
324 MediaExpectations media_expectations;
325 media_expectations.ExpectBidirectionalAudioAndVideo();
326 ASSERT_TRUE(ExpectNewFrames(media_expectations));
327}
328
deadbeef1dcb1642017-03-29 21:08:16 -0700329// This test sets up a call between two parties with a source resolution of
330// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800331TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -0700332 Send1280By720ResolutionAndReceive16To9AspectRatio) {
333 ASSERT_TRUE(CreatePeerConnectionWrappers());
334 ConnectFakeSignaling();
335
Niels Möller5c7efe72018-05-11 10:34:46 +0200336 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
337 webrtc::FakePeriodicVideoSource::Config config;
338 config.width = 1280;
339 config.height = 720;
Johannes Kron965e7942018-09-13 15:36:20 +0200340 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +0200341 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
342 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -0700343
344 // Do normal offer/answer and wait for at least one frame to be received in
345 // each direction.
346 caller()->CreateAndSetAndSignalOffer();
347 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
348 callee()->min_video_frames_received_per_track() > 0,
349 kMaxWaitForFramesMs);
350
351 // Check rendered aspect ratio.
352 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
353 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
354 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
355 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
356}
357
358// This test sets up an one-way call, with media only from caller to
359// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800360TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -0700361 ASSERT_TRUE(CreatePeerConnectionWrappers());
362 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800363 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700364 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800365 MediaExpectations media_expectations;
366 media_expectations.CalleeExpectsSomeAudioAndVideo();
367 media_expectations.CallerExpectsNoAudio();
368 media_expectations.CallerExpectsNoVideo();
369 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700370}
371
Johannes Kron3e983682020-03-29 22:17:00 +0200372// Tests that send only works without the caller having a decoder factory and
373// the callee having an encoder factory.
374TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSendOnlyVideo) {
375 ASSERT_TRUE(
376 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
377 ConnectFakeSignaling();
378 // Add one-directional video, from caller to callee.
379 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
380 caller()->CreateLocalVideoTrack();
381 caller()->AddTrack(caller_track);
382 PeerConnectionInterface::RTCOfferAnswerOptions options;
383 options.offer_to_receive_video = 0;
384 caller()->SetOfferAnswerOptions(options);
385 caller()->CreateAndSetAndSignalOffer();
386 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
387 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
388
389 // Expect video to be received in one direction.
390 MediaExpectations media_expectations;
391 media_expectations.CallerExpectsNoVideo();
392 media_expectations.CalleeExpectsSomeVideo();
393
394 EXPECT_TRUE(ExpectNewFrames(media_expectations));
395}
396
397// Tests that receive only works without the caller having an encoder factory
398// and the callee having a decoder factory.
399TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithReceiveOnlyVideo) {
400 ASSERT_TRUE(
401 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/false));
402 ConnectFakeSignaling();
403 // Add one-directional video, from callee to caller.
404 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
405 callee()->CreateLocalVideoTrack();
406 callee()->AddTrack(callee_track);
407 PeerConnectionInterface::RTCOfferAnswerOptions options;
408 options.offer_to_receive_video = 1;
409 caller()->SetOfferAnswerOptions(options);
410 caller()->CreateAndSetAndSignalOffer();
411 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
412 ASSERT_EQ(caller()->pc()->GetReceivers().size(), 1u);
413
414 // Expect video to be received in one direction.
415 MediaExpectations media_expectations;
416 media_expectations.CallerExpectsSomeVideo();
417 media_expectations.CalleeExpectsNoVideo();
418
419 EXPECT_TRUE(ExpectNewFrames(media_expectations));
420}
421
422TEST_P(PeerConnectionIntegrationTest,
423 EndToEndCallAddReceiveVideoToSendOnlyCall) {
424 ASSERT_TRUE(CreatePeerConnectionWrappers());
425 ConnectFakeSignaling();
426 // Add one-directional video, from caller to callee.
427 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
428 caller()->CreateLocalVideoTrack();
429 caller()->AddTrack(caller_track);
430 caller()->CreateAndSetAndSignalOffer();
431 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
432
433 // Add receive video.
434 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
435 callee()->CreateLocalVideoTrack();
436 callee()->AddTrack(callee_track);
437 caller()->CreateAndSetAndSignalOffer();
438 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
439
440 // Ensure that video frames are received end-to-end.
441 MediaExpectations media_expectations;
442 media_expectations.ExpectBidirectionalVideo();
443 ASSERT_TRUE(ExpectNewFrames(media_expectations));
444}
445
446TEST_P(PeerConnectionIntegrationTest,
447 EndToEndCallAddSendVideoToReceiveOnlyCall) {
448 ASSERT_TRUE(CreatePeerConnectionWrappers());
449 ConnectFakeSignaling();
450 // Add one-directional video, from callee to caller.
451 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
452 callee()->CreateLocalVideoTrack();
453 callee()->AddTrack(callee_track);
454 caller()->CreateAndSetAndSignalOffer();
455 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
456
457 // Add send video.
458 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
459 caller()->CreateLocalVideoTrack();
460 caller()->AddTrack(caller_track);
461 caller()->CreateAndSetAndSignalOffer();
462 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
463
464 // Expect video to be received in one direction.
465 MediaExpectations media_expectations;
466 media_expectations.ExpectBidirectionalVideo();
467 ASSERT_TRUE(ExpectNewFrames(media_expectations));
468}
469
470TEST_P(PeerConnectionIntegrationTest,
471 EndToEndCallRemoveReceiveVideoFromSendReceiveCall) {
472 ASSERT_TRUE(CreatePeerConnectionWrappers());
473 ConnectFakeSignaling();
474 // Add send video, from caller to callee.
475 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
476 caller()->CreateLocalVideoTrack();
477 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
478 caller()->AddTrack(caller_track);
479 // Add receive video, from callee to caller.
480 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
481 callee()->CreateLocalVideoTrack();
482
483 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
484 callee()->AddTrack(callee_track);
485 caller()->CreateAndSetAndSignalOffer();
486 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
487
488 // Remove receive video (i.e., callee sender track).
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000489 callee()->pc()->RemoveTrackOrError(callee_sender);
Johannes Kron3e983682020-03-29 22:17:00 +0200490
491 caller()->CreateAndSetAndSignalOffer();
492 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
493
494 // Expect one-directional video.
495 MediaExpectations media_expectations;
496 media_expectations.CallerExpectsNoVideo();
497 media_expectations.CalleeExpectsSomeVideo();
498
499 ASSERT_TRUE(ExpectNewFrames(media_expectations));
500}
501
502TEST_P(PeerConnectionIntegrationTest,
503 EndToEndCallRemoveSendVideoFromSendReceiveCall) {
504 ASSERT_TRUE(CreatePeerConnectionWrappers());
505 ConnectFakeSignaling();
506 // Add send video, from caller to callee.
507 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
508 caller()->CreateLocalVideoTrack();
509 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
510 caller()->AddTrack(caller_track);
511 // Add receive video, from callee to caller.
512 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
513 callee()->CreateLocalVideoTrack();
514
515 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
516 callee()->AddTrack(callee_track);
517 caller()->CreateAndSetAndSignalOffer();
518 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
519
520 // Remove send video (i.e., caller sender track).
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000521 caller()->pc()->RemoveTrackOrError(caller_sender);
Johannes Kron3e983682020-03-29 22:17:00 +0200522
523 caller()->CreateAndSetAndSignalOffer();
524 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
525
526 // Expect one-directional video.
527 MediaExpectations media_expectations;
528 media_expectations.CalleeExpectsNoVideo();
529 media_expectations.CallerExpectsSomeVideo();
530
531 ASSERT_TRUE(ExpectNewFrames(media_expectations));
532}
533
deadbeef1dcb1642017-03-29 21:08:16 -0700534// This test sets up a audio call initially, with the callee rejecting video
535// initially. Then later the callee decides to upgrade to audio/video, and
536// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800537TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -0700538 ASSERT_TRUE(CreatePeerConnectionWrappers());
539 ConnectFakeSignaling();
540 // Initially, offer an audio/video stream from the caller, but refuse to
541 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -0800542 caller()->AddAudioVideoTracks();
543 callee()->AddAudioTrack();
Florent Castelli15a38de2022-04-06 00:38:21 +0200544 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800545 PeerConnectionInterface::RTCOfferAnswerOptions options;
546 options.offer_to_receive_video = 0;
547 callee()->SetOfferAnswerOptions(options);
548 } else {
549 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200550 callee()
551 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
552 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800553 });
554 }
deadbeef1dcb1642017-03-29 21:08:16 -0700555 // Do offer/answer and make sure audio is still received end-to-end.
556 caller()->CreateAndSetAndSignalOffer();
557 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800558 {
559 MediaExpectations media_expectations;
560 media_expectations.ExpectBidirectionalAudio();
561 media_expectations.ExpectNoVideo();
562 ASSERT_TRUE(ExpectNewFrames(media_expectations));
563 }
deadbeef1dcb1642017-03-29 21:08:16 -0700564 // Sanity check that the callee's description has a rejected video section.
565 ASSERT_NE(nullptr, callee()->pc()->local_description());
566 const ContentInfo* callee_video_content =
567 GetFirstVideoContent(callee()->pc()->local_description()->description());
568 ASSERT_NE(nullptr, callee_video_content);
569 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800570
deadbeef1dcb1642017-03-29 21:08:16 -0700571 // Now negotiate with video and ensure negotiation succeeds, with video
572 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -0800573 callee()->AddVideoTrack();
Florent Castelli15a38de2022-04-06 00:38:21 +0200574 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800575 PeerConnectionInterface::RTCOfferAnswerOptions options;
576 options.offer_to_receive_video = 1;
577 callee()->SetOfferAnswerOptions(options);
578 } else {
579 callee()->SetRemoteOfferHandler(nullptr);
580 caller()->SetRemoteOfferHandler([this] {
581 // The caller creates a new transceiver to receive video on when receiving
582 // the offer, but by default it is send only.
583 auto transceivers = caller()->pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +0200584 ASSERT_EQ(2U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800585 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
Harald Alvestrand6060df52020-08-11 09:54:02 +0200586 transceivers[1]->receiver()->media_type());
Niels Möllerafb246b2022-04-20 14:26:50 +0200587 transceivers[1]->sender()->SetTrack(
588 caller()->CreateLocalVideoTrack().get());
Harald Alvestrand6060df52020-08-11 09:54:02 +0200589 transceivers[1]->SetDirectionWithError(
590 RtpTransceiverDirection::kSendRecv);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800591 });
592 }
deadbeef1dcb1642017-03-29 21:08:16 -0700593 callee()->CreateAndSetAndSignalOffer();
594 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800595 {
596 // Expect additional audio frames to be received after the upgrade.
597 MediaExpectations media_expectations;
598 media_expectations.ExpectBidirectionalAudioAndVideo();
599 ASSERT_TRUE(ExpectNewFrames(media_expectations));
600 }
deadbeef1dcb1642017-03-29 21:08:16 -0700601}
602
deadbeef4389b4d2017-09-07 09:07:36 -0700603// Simpler than the above test; just add an audio track to an established
604// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800605TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -0700606 ASSERT_TRUE(CreatePeerConnectionWrappers());
607 ConnectFakeSignaling();
608 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -0800609 caller()->AddVideoTrack();
610 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700611 caller()->CreateAndSetAndSignalOffer();
612 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
613 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -0800614 caller()->AddAudioTrack();
615 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700616 caller()->CreateAndSetAndSignalOffer();
617 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
618 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800619 MediaExpectations media_expectations;
620 media_expectations.ExpectBidirectionalAudioAndVideo();
621 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -0700622}
623
deadbeef1dcb1642017-03-29 21:08:16 -0700624// This test sets up a non-bundled call and negotiates bundling at the same
625// time as starting an ICE restart. When bundling is in effect in the restart,
626// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800627TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -0700628 ASSERT_TRUE(CreatePeerConnectionWrappers());
629 ConnectFakeSignaling();
630
Steve Anton15324772018-01-16 10:26:49 -0800631 caller()->AddAudioVideoTracks();
632 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700633 // Remove the bundle group from the SDP received by the callee.
634 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
635 desc->RemoveGroupByName("BUNDLE");
636 });
637 caller()->CreateAndSetAndSignalOffer();
638 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800639 {
640 MediaExpectations media_expectations;
641 media_expectations.ExpectBidirectionalAudioAndVideo();
642 ASSERT_TRUE(ExpectNewFrames(media_expectations));
643 }
deadbeef1dcb1642017-03-29 21:08:16 -0700644 // Now stop removing the BUNDLE group, and trigger an ICE restart.
645 callee()->SetReceivedSdpMunger(nullptr);
646 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
647 caller()->CreateAndSetAndSignalOffer();
648 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
649
650 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800651 {
652 MediaExpectations media_expectations;
653 media_expectations.ExpectBidirectionalAudioAndVideo();
654 ASSERT_TRUE(ExpectNewFrames(media_expectations));
655 }
deadbeef1dcb1642017-03-29 21:08:16 -0700656}
657
658// Test CVO (Coordination of Video Orientation). If a video source is rotated
659// and both peers support the CVO RTP header extension, the actual video frames
660// don't need to be encoded in different resolutions, since the rotation is
661// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800662TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700663 ASSERT_TRUE(CreatePeerConnectionWrappers());
664 ConnectFakeSignaling();
665 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800666 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700667 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800668 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700669 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
670
671 // Wait for video frames to be received by both sides.
672 caller()->CreateAndSetAndSignalOffer();
673 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
674 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
675 callee()->min_video_frames_received_per_track() > 0,
676 kMaxWaitForFramesMs);
677
678 // Ensure that the aspect ratio is unmodified.
679 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
680 // not just assumed.
681 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
682 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
683 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
684 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
685 // Ensure that the CVO bits were surfaced to the renderer.
686 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
687 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
688}
689
690// Test that when the CVO extension isn't supported, video is rotated the
691// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800692TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700693 ASSERT_TRUE(CreatePeerConnectionWrappers());
694 ConnectFakeSignaling();
695 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800696 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700697 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800698 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700699 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
700
701 // Remove the CVO extension from the offered SDP.
702 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
703 cricket::VideoContentDescription* video =
704 GetFirstVideoContentDescription(desc);
705 video->ClearRtpHeaderExtensions();
706 });
707 // Wait for video frames to be received by both sides.
708 caller()->CreateAndSetAndSignalOffer();
709 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
710 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
711 callee()->min_video_frames_received_per_track() > 0,
712 kMaxWaitForFramesMs);
713
714 // Expect that the aspect ratio is inversed to account for the 90/270 degree
715 // rotation.
716 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
717 // not just assumed.
718 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
719 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
720 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
721 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
722 // Expect that each endpoint is unaware of the rotation of the other endpoint.
723 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
724 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
725}
726
deadbeef1dcb1642017-03-29 21:08:16 -0700727// Test that if the answerer rejects the audio m= section, no audio is sent or
728// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800729TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700730 ASSERT_TRUE(CreatePeerConnectionWrappers());
731 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800732 caller()->AddAudioVideoTracks();
Florent Castelli15a38de2022-04-06 00:38:21 +0200733 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800734 // Only add video track for callee, and set offer_to_receive_audio to 0, so
735 // it will reject the audio m= section completely.
736 PeerConnectionInterface::RTCOfferAnswerOptions options;
737 options.offer_to_receive_audio = 0;
738 callee()->SetOfferAnswerOptions(options);
739 } else {
740 // Stopping the audio RtpTransceiver will cause the media section to be
741 // rejected in the answer.
742 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200743 callee()
744 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
745 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800746 });
747 }
Steve Anton15324772018-01-16 10:26:49 -0800748 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700749 // Do offer/answer and wait for successful end-to-end video frames.
750 caller()->CreateAndSetAndSignalOffer();
751 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800752 MediaExpectations media_expectations;
753 media_expectations.ExpectBidirectionalVideo();
754 media_expectations.ExpectNoAudio();
755 ASSERT_TRUE(ExpectNewFrames(media_expectations));
756
deadbeef1dcb1642017-03-29 21:08:16 -0700757 // Sanity check that the callee's description has a rejected audio section.
758 ASSERT_NE(nullptr, callee()->pc()->local_description());
759 const ContentInfo* callee_audio_content =
760 GetFirstAudioContent(callee()->pc()->local_description()->description());
761 ASSERT_NE(nullptr, callee_audio_content);
762 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800763 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200764 // The caller's transceiver should have stopped after receiving the answer,
765 // and thus no longer listed in transceivers.
766 EXPECT_EQ(nullptr,
767 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800768 }
deadbeef1dcb1642017-03-29 21:08:16 -0700769}
770
771// Test that if the answerer rejects the video m= section, no video is sent or
772// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800773TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700774 ASSERT_TRUE(CreatePeerConnectionWrappers());
775 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800776 caller()->AddAudioVideoTracks();
Florent Castelli15a38de2022-04-06 00:38:21 +0200777 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800778 // Only add audio track for callee, and set offer_to_receive_video to 0, so
779 // it will reject the video m= section completely.
780 PeerConnectionInterface::RTCOfferAnswerOptions options;
781 options.offer_to_receive_video = 0;
782 callee()->SetOfferAnswerOptions(options);
783 } else {
784 // Stopping the video RtpTransceiver will cause the media section to be
785 // rejected in the answer.
786 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200787 callee()
788 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
789 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800790 });
791 }
Steve Anton15324772018-01-16 10:26:49 -0800792 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700793 // Do offer/answer and wait for successful end-to-end audio frames.
794 caller()->CreateAndSetAndSignalOffer();
795 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800796 MediaExpectations media_expectations;
797 media_expectations.ExpectBidirectionalAudio();
798 media_expectations.ExpectNoVideo();
799 ASSERT_TRUE(ExpectNewFrames(media_expectations));
800
deadbeef1dcb1642017-03-29 21:08:16 -0700801 // Sanity check that the callee's description has a rejected video section.
802 ASSERT_NE(nullptr, callee()->pc()->local_description());
803 const ContentInfo* callee_video_content =
804 GetFirstVideoContent(callee()->pc()->local_description()->description());
805 ASSERT_NE(nullptr, callee_video_content);
806 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800807 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200808 // The caller's transceiver should have stopped after receiving the answer,
809 // and thus is no longer present.
810 EXPECT_EQ(nullptr,
811 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800812 }
deadbeef1dcb1642017-03-29 21:08:16 -0700813}
814
815// Test that if the answerer rejects both audio and video m= sections, nothing
816// bad happens.
817// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
818// test anything but the fact that negotiation succeeds, which doesn't mean
819// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800820TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -0700821 ASSERT_TRUE(CreatePeerConnectionWrappers());
822 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800823 caller()->AddAudioVideoTracks();
Florent Castelli15a38de2022-04-06 00:38:21 +0200824 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800825 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
826 // will reject both audio and video m= sections.
827 PeerConnectionInterface::RTCOfferAnswerOptions options;
828 options.offer_to_receive_audio = 0;
829 options.offer_to_receive_video = 0;
830 callee()->SetOfferAnswerOptions(options);
831 } else {
832 callee()->SetRemoteOfferHandler([this] {
833 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +0100834 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200835 transceiver->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800836 }
837 });
838 }
deadbeef1dcb1642017-03-29 21:08:16 -0700839 // Do offer/answer and wait for stable signaling state.
840 caller()->CreateAndSetAndSignalOffer();
841 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800842
deadbeef1dcb1642017-03-29 21:08:16 -0700843 // Sanity check that the callee's description has rejected m= sections.
844 ASSERT_NE(nullptr, callee()->pc()->local_description());
845 const ContentInfo* callee_audio_content =
846 GetFirstAudioContent(callee()->pc()->local_description()->description());
847 ASSERT_NE(nullptr, callee_audio_content);
848 EXPECT_TRUE(callee_audio_content->rejected);
849 const ContentInfo* callee_video_content =
850 GetFirstVideoContent(callee()->pc()->local_description()->description());
851 ASSERT_NE(nullptr, callee_video_content);
852 EXPECT_TRUE(callee_video_content->rejected);
853}
854
855// This test sets up an audio and video call between two parties. After the
856// call runs for a while, the caller sends an updated offer with video being
857// rejected. Once the re-negotiation is done, the video flow should stop and
858// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800859TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700860 ASSERT_TRUE(CreatePeerConnectionWrappers());
861 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800862 caller()->AddAudioVideoTracks();
863 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700864 caller()->CreateAndSetAndSignalOffer();
865 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800866 {
867 MediaExpectations media_expectations;
868 media_expectations.ExpectBidirectionalAudioAndVideo();
869 ASSERT_TRUE(ExpectNewFrames(media_expectations));
870 }
deadbeef1dcb1642017-03-29 21:08:16 -0700871 // Renegotiate, rejecting the video m= section.
Florent Castelli15a38de2022-04-06 00:38:21 +0200872 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800873 caller()->SetGeneratedSdpMunger(
874 [](cricket::SessionDescription* description) {
875 for (cricket::ContentInfo& content : description->contents()) {
876 if (cricket::IsVideoContent(&content)) {
877 content.rejected = true;
878 }
879 }
880 });
881 } else {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200882 caller()
883 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
884 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800885 }
deadbeef1dcb1642017-03-29 21:08:16 -0700886 caller()->CreateAndSetAndSignalOffer();
887 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
888
889 // Sanity check that the caller's description has a rejected video section.
890 ASSERT_NE(nullptr, caller()->pc()->local_description());
891 const ContentInfo* caller_video_content =
892 GetFirstVideoContent(caller()->pc()->local_description()->description());
893 ASSERT_NE(nullptr, caller_video_content);
894 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -0700895 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800896 {
897 MediaExpectations media_expectations;
898 media_expectations.ExpectBidirectionalAudio();
899 media_expectations.ExpectNoVideo();
900 ASSERT_TRUE(ExpectNewFrames(media_expectations));
901 }
deadbeef1dcb1642017-03-29 21:08:16 -0700902}
903
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700904// Do one offer/answer with audio, another that disables it (rejecting the m=
905// section), and another that re-enables it. Regression test for:
906// bugs.webrtc.org/6023
907TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
908 ASSERT_TRUE(CreatePeerConnectionWrappers());
909 ConnectFakeSignaling();
910
911 // Add audio track, do normal offer/answer.
912 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
913 caller()->CreateLocalAudioTrack();
914 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
915 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
916 caller()->CreateAndSetAndSignalOffer();
917 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
918
919 // Remove audio track, and set offer_to_receive_audio to false to cause the
920 // m= section to be completely disabled, not just "recvonly".
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000921 caller()->pc()->RemoveTrackOrError(sender);
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700922 PeerConnectionInterface::RTCOfferAnswerOptions options;
923 options.offer_to_receive_audio = 0;
924 caller()->SetOfferAnswerOptions(options);
925 caller()->CreateAndSetAndSignalOffer();
926 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
927
928 // Add the audio track again, expecting negotiation to succeed and frames to
929 // flow.
930 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
931 options.offer_to_receive_audio = 1;
932 caller()->SetOfferAnswerOptions(options);
933 caller()->CreateAndSetAndSignalOffer();
934 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
935
936 MediaExpectations media_expectations;
937 media_expectations.CalleeExpectsSomeAudio();
938 EXPECT_TRUE(ExpectNewFrames(media_expectations));
939}
940
deadbeef1dcb1642017-03-29 21:08:16 -0700941// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
942// is needed to support legacy endpoints.
943// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
944// add a test for an end-to-end test without MID signaling either (basically,
945// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800946TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -0700947 ASSERT_TRUE(CreatePeerConnectionWrappers());
948 ConnectFakeSignaling();
949 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -0800950 caller()->AddAudioVideoTracks();
951 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -0700952 // Remove SSRCs and MSIDs from the received offer SDP.
953 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -0700954 caller()->CreateAndSetAndSignalOffer();
955 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800956 MediaExpectations media_expectations;
957 media_expectations.ExpectBidirectionalAudioAndVideo();
958 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700959}
960
Seth Hampson5897a6e2018-04-03 11:16:33 -0700961// Basic end-to-end test, without SSRC signaling. This means that the track
962// was created properly and frames are delivered when the MSIDs are communicated
963// with a=msid lines and no a=ssrc lines.
964TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
965 EndToEndCallWithoutSsrcSignaling) {
966 const char kStreamId[] = "streamId";
967 ASSERT_TRUE(CreatePeerConnectionWrappers());
968 ConnectFakeSignaling();
969 // Add just audio tracks.
970 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
971 callee()->AddAudioTrack();
972
973 // Remove SSRCs from the received offer SDP.
974 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
975 caller()->CreateAndSetAndSignalOffer();
976 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
977 MediaExpectations media_expectations;
978 media_expectations.ExpectBidirectionalAudio();
979 ASSERT_TRUE(ExpectNewFrames(media_expectations));
980}
981
Johannes Kron3e983682020-03-29 22:17:00 +0200982TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
983 EndToEndCallAddReceiveVideoToSendOnlyCall) {
984 ASSERT_TRUE(CreatePeerConnectionWrappers());
985 ConnectFakeSignaling();
986 // Add one-directional video, from caller to callee.
987 rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
988 caller()->CreateLocalVideoTrack();
989
990 RtpTransceiverInit video_transceiver_init;
991 video_transceiver_init.stream_ids = {"video1"};
992 video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly;
993 auto video_sender =
994 caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue();
995 caller()->CreateAndSetAndSignalOffer();
996 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
997
998 // Add receive direction.
Harald Alvestrand6060df52020-08-11 09:54:02 +0200999 video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);
Johannes Kron3e983682020-03-29 22:17:00 +02001000
1001 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
1002 callee()->CreateLocalVideoTrack();
1003
1004 callee()->AddTrack(callee_track);
1005 caller()->CreateAndSetAndSignalOffer();
1006 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1007 // Ensure that video frames are received end-to-end.
1008 MediaExpectations media_expectations;
1009 media_expectations.ExpectBidirectionalVideo();
1010 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1011}
1012
Steve Antondf527fd2018-04-27 15:52:03 -07001013// Tests that video flows between multiple video tracks when SSRCs are not
1014// signaled. This exercises the MID RTP header extension which is needed to
1015// demux the incoming video tracks.
1016TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1017 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
1018 ASSERT_TRUE(CreatePeerConnectionWrappers());
1019 ConnectFakeSignaling();
1020 caller()->AddVideoTrack();
1021 caller()->AddVideoTrack();
1022 callee()->AddVideoTrack();
1023 callee()->AddVideoTrack();
1024
1025 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1026 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1027 caller()->CreateAndSetAndSignalOffer();
1028 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1029 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1030 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1031
1032 // Expect video to be received in both directions on both tracks.
1033 MediaExpectations media_expectations;
1034 media_expectations.ExpectBidirectionalVideo();
1035 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1036}
1037
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -07001038// Used for the test below.
1039void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
1040 RemoveSsrcsAndKeepMsids(desc);
1041 desc->RemoveGroupByName("BUNDLE");
1042 for (ContentInfo& content : desc->contents()) {
1043 cricket::MediaContentDescription* media = content.media_description();
1044 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1045 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1046 [](const RtpExtension& extension) {
1047 return extension.uri ==
1048 RtpExtension::kMidUri;
1049 }),
1050 extensions.end());
1051 media->set_rtp_header_extensions(extensions);
1052 }
1053}
1054
1055// Tests that video flows between multiple video tracks when BUNDLE is not used,
1056// SSRCs are not signaled and the MID RTP header extension is not used. This
1057// relies on demuxing by payload type, which normally doesn't work if you have
1058// multiple media sections using the same payload type, but which should work as
1059// long as the media sections aren't bundled.
1060// Regression test for: http://crbug.com/webrtc/12023
1061TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1062 EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid) {
1063 ASSERT_TRUE(CreatePeerConnectionWrappers());
1064 ConnectFakeSignaling();
1065 caller()->AddVideoTrack();
1066 caller()->AddVideoTrack();
1067 callee()->AddVideoTrack();
1068 callee()->AddVideoTrack();
1069 caller()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1070 callee()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1071 caller()->CreateAndSetAndSignalOffer();
1072 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1073 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1074 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1075 // Make sure we are not bundled.
1076 ASSERT_NE(caller()->pc()->GetSenders()[0]->dtls_transport(),
1077 caller()->pc()->GetSenders()[1]->dtls_transport());
1078
1079 // Expect video to be received in both directions on both tracks.
1080 MediaExpectations media_expectations;
1081 media_expectations.ExpectBidirectionalVideo();
1082 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1083}
1084
1085// Used for the test below.
1086void ModifyPayloadTypesAndRemoveMidExtension(
1087 cricket::SessionDescription* desc) {
1088 int pt = 96;
1089 for (ContentInfo& content : desc->contents()) {
1090 cricket::MediaContentDescription* media = content.media_description();
1091 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1092 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1093 [](const RtpExtension& extension) {
1094 return extension.uri ==
1095 RtpExtension::kMidUri;
1096 }),
1097 extensions.end());
1098 media->set_rtp_header_extensions(extensions);
1099 cricket::VideoContentDescription* video = media->as_video();
1100 ASSERT_TRUE(video != nullptr);
1101 std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
1102 video->set_codecs(codecs);
1103 }
1104}
1105
1106// Tests that two video tracks can be demultiplexed by payload type alone, by
1107// using different payload types for the same codec in different m= sections.
1108// This practice is discouraged but historically has been supported.
1109// Regression test for: http://crbug.com/webrtc/12029
1110TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1111 EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType) {
1112 ASSERT_TRUE(CreatePeerConnectionWrappers());
1113 ConnectFakeSignaling();
1114 caller()->AddVideoTrack();
1115 caller()->AddVideoTrack();
1116 callee()->AddVideoTrack();
1117 callee()->AddVideoTrack();
1118 caller()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1119 callee()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1120 // We can't remove SSRCs from the generated SDP because then no send streams
1121 // would be created.
1122 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1123 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1124 caller()->CreateAndSetAndSignalOffer();
1125 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1126 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1127 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1128 // Make sure we are bundled.
1129 ASSERT_EQ(caller()->pc()->GetSenders()[0]->dtls_transport(),
1130 caller()->pc()->GetSenders()[1]->dtls_transport());
1131
1132 // Expect video to be received in both directions on both tracks.
1133 MediaExpectations media_expectations;
1134 media_expectations.ExpectBidirectionalVideo();
1135 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1136}
1137
Henrik Boström5b147782018-12-04 11:25:05 +01001138TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
1139 ASSERT_TRUE(CreatePeerConnectionWrappers());
1140 ConnectFakeSignaling();
1141 caller()->AddAudioTrack();
1142 caller()->AddVideoTrack();
1143 caller()->CreateAndSetAndSignalOffer();
1144 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1145 auto callee_receivers = callee()->pc()->GetReceivers();
1146 ASSERT_EQ(2u, callee_receivers.size());
1147 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
1148 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
1149}
1150
1151TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
1152 ASSERT_TRUE(CreatePeerConnectionWrappers());
1153 ConnectFakeSignaling();
1154 caller()->AddAudioTrack();
1155 caller()->AddVideoTrack();
1156 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1157 caller()->CreateAndSetAndSignalOffer();
1158 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1159 auto callee_receivers = callee()->pc()->GetReceivers();
1160 ASSERT_EQ(2u, callee_receivers.size());
1161 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
1162 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
1163 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
1164 callee_receivers[1]->stream_ids()[0]);
1165 EXPECT_EQ(callee_receivers[0]->streams()[0],
1166 callee_receivers[1]->streams()[0]);
1167}
1168
deadbeef1dcb1642017-03-29 21:08:16 -07001169// Test that if two video tracks are sent (from caller to callee, in this test),
1170// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001171TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07001172 ASSERT_TRUE(CreatePeerConnectionWrappers());
1173 ConnectFakeSignaling();
1174 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08001175 caller()->AddAudioVideoTracks();
1176 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001177 caller()->CreateAndSetAndSignalOffer();
1178 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08001179 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08001180
1181 MediaExpectations media_expectations;
1182 media_expectations.CalleeExpectsSomeAudioAndVideo();
1183 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001184}
1185
1186static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
1187 bool first = true;
1188 for (cricket::ContentInfo& content : desc->contents()) {
1189 if (first) {
1190 first = false;
1191 continue;
1192 }
1193 content.bundle_only = true;
1194 }
1195 first = true;
1196 for (cricket::TransportInfo& transport : desc->transport_infos()) {
1197 if (first) {
1198 first = false;
1199 continue;
1200 }
1201 transport.description.ice_ufrag.clear();
1202 transport.description.ice_pwd.clear();
1203 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
1204 transport.description.identity_fingerprint.reset(nullptr);
1205 }
1206}
1207
1208// Test that if applying a true "max bundle" offer, which uses ports of 0,
1209// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
1210// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
1211// successfully and media flows.
1212// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
1213// TODO(deadbeef): Won't need this test once we start generating actual
1214// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001215TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001216 EndToEndCallWithSpecCompliantMaxBundleOffer) {
1217 ASSERT_TRUE(CreatePeerConnectionWrappers());
1218 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001219 caller()->AddAudioVideoTracks();
1220 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001221 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
1222 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
1223 // but the first m= section.
1224 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
1225 caller()->CreateAndSetAndSignalOffer();
1226 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001227 MediaExpectations media_expectations;
1228 media_expectations.ExpectBidirectionalAudioAndVideo();
1229 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001230}
1231
1232// Test that we can receive the audio output level from a remote audio track.
1233// TODO(deadbeef): Use a fake audio source and verify that the output level is
1234// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001235TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001236 ASSERT_TRUE(CreatePeerConnectionWrappers());
1237 ConnectFakeSignaling();
1238 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001239 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001240 caller()->CreateAndSetAndSignalOffer();
1241 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1242
1243 // Get the audio output level stats. Note that the level is not available
1244 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07001245 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001246 kMaxWaitForFramesMs);
1247}
1248
1249// Test that an audio input level is reported.
1250// TODO(deadbeef): Use a fake audio source and verify that the input level is
1251// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001252TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001253 ASSERT_TRUE(CreatePeerConnectionWrappers());
1254 ConnectFakeSignaling();
1255 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001256 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001257 caller()->CreateAndSetAndSignalOffer();
1258 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1259
1260 // Get the audio input level stats. The level should be available very
1261 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07001262 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001263 kMaxWaitForStatsMs);
1264}
1265
1266// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001267TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001268 ASSERT_TRUE(CreatePeerConnectionWrappers());
1269 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001270 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001271 // Do offer/answer, wait for the callee to receive some frames.
1272 caller()->CreateAndSetAndSignalOffer();
1273 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001274
1275 MediaExpectations media_expectations;
1276 media_expectations.CalleeExpectsSomeAudioAndVideo();
1277 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001278
1279 // Get a handle to the remote tracks created, so they can be used as GetStats
1280 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01001281 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08001282 // We received frames, so we definitely should have nonzero "received bytes"
1283 // stats at this point.
Niels Möllerafb246b2022-04-20 14:26:50 +02001284 EXPECT_GT(
1285 callee()->OldGetStatsForTrack(receiver->track().get())->BytesReceived(),
1286 0);
Steve Anton15324772018-01-16 10:26:49 -08001287 }
deadbeef1dcb1642017-03-29 21:08:16 -07001288}
1289
1290// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001291TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001292 ASSERT_TRUE(CreatePeerConnectionWrappers());
1293 ConnectFakeSignaling();
1294 auto audio_track = caller()->CreateLocalAudioTrack();
1295 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08001296 caller()->AddTrack(audio_track);
1297 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07001298 // Do offer/answer, wait for the callee to receive some frames.
1299 caller()->CreateAndSetAndSignalOffer();
1300 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001301 MediaExpectations media_expectations;
1302 media_expectations.CalleeExpectsSomeAudioAndVideo();
1303 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001304
1305 // The callee received frames, so we definitely should have nonzero "sent
1306 // bytes" stats at this point.
Niels Möllerafb246b2022-04-20 14:26:50 +02001307 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track.get())->BytesSent(), 0);
1308 EXPECT_GT(caller()->OldGetStatsForTrack(video_track.get())->BytesSent(), 0);
deadbeefd8ad7882017-04-18 16:01:17 -07001309}
1310
Steve Antona41959e2018-11-28 11:15:33 -08001311// Test that the track ID is associated with all local and remote SSRC stats
1312// using the old GetStats() and more than 1 audio and more than 1 video track.
1313// This is a regression test for crbug.com/906988
1314TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1315 OldGetStatsAssociatesTrackIdForManyMediaSections) {
1316 ASSERT_TRUE(CreatePeerConnectionWrappers());
1317 ConnectFakeSignaling();
1318 auto audio_sender_1 = caller()->AddAudioTrack();
1319 auto video_sender_1 = caller()->AddVideoTrack();
1320 auto audio_sender_2 = caller()->AddAudioTrack();
1321 auto video_sender_2 = caller()->AddVideoTrack();
1322 caller()->CreateAndSetAndSignalOffer();
1323 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1324
1325 MediaExpectations media_expectations;
1326 media_expectations.CalleeExpectsSomeAudioAndVideo();
1327 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1328
1329 std::vector<std::string> track_ids = {
1330 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1331 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1332
1333 auto caller_stats = caller()->OldGetStats();
1334 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1335 auto callee_stats = callee()->OldGetStats();
1336 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1337}
1338
Steve Antonffa6ce42018-11-30 09:26:08 -08001339// Test that the new GetStats() returns stats for all outgoing/incoming streams
1340// with the correct track IDs if there are more than one audio and more than one
1341// video senders/receivers.
1342TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
1343 ASSERT_TRUE(CreatePeerConnectionWrappers());
1344 ConnectFakeSignaling();
1345 auto audio_sender_1 = caller()->AddAudioTrack();
1346 auto video_sender_1 = caller()->AddVideoTrack();
1347 auto audio_sender_2 = caller()->AddAudioTrack();
1348 auto video_sender_2 = caller()->AddVideoTrack();
1349 caller()->CreateAndSetAndSignalOffer();
1350 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1351
1352 MediaExpectations media_expectations;
1353 media_expectations.CalleeExpectsSomeAudioAndVideo();
1354 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1355
1356 std::vector<std::string> track_ids = {
1357 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1358 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1359
1360 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
1361 caller()->NewGetStats();
1362 ASSERT_TRUE(caller_report);
1363 auto outbound_stream_stats =
1364 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
Henrik Boströma0ff50c2020-05-05 15:54:46 +02001365 ASSERT_EQ(outbound_stream_stats.size(), 4u);
Steve Antonffa6ce42018-11-30 09:26:08 -08001366 std::vector<std::string> outbound_track_ids;
1367 for (const auto& stat : outbound_stream_stats) {
1368 ASSERT_TRUE(stat->bytes_sent.is_defined());
1369 EXPECT_LT(0u, *stat->bytes_sent);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001370 if (*stat->kind == "video") {
1371 ASSERT_TRUE(stat->key_frames_encoded.is_defined());
1372 EXPECT_GT(*stat->key_frames_encoded, 0u);
1373 ASSERT_TRUE(stat->frames_encoded.is_defined());
1374 EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
1375 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001376 ASSERT_TRUE(stat->track_id.is_defined());
1377 const auto* track_stat =
1378 caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1379 ASSERT_TRUE(track_stat);
1380 outbound_track_ids.push_back(*track_stat->track_identifier);
1381 }
1382 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
1383
1384 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
1385 callee()->NewGetStats();
1386 ASSERT_TRUE(callee_report);
1387 auto inbound_stream_stats =
1388 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1389 ASSERT_EQ(4u, inbound_stream_stats.size());
1390 std::vector<std::string> inbound_track_ids;
1391 for (const auto& stat : inbound_stream_stats) {
1392 ASSERT_TRUE(stat->bytes_received.is_defined());
1393 EXPECT_LT(0u, *stat->bytes_received);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001394 if (*stat->kind == "video") {
1395 ASSERT_TRUE(stat->key_frames_decoded.is_defined());
1396 EXPECT_GT(*stat->key_frames_decoded, 0u);
1397 ASSERT_TRUE(stat->frames_decoded.is_defined());
1398 EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
1399 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001400 ASSERT_TRUE(stat->track_id.is_defined());
1401 const auto* track_stat =
1402 callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1403 ASSERT_TRUE(track_stat);
1404 inbound_track_ids.push_back(*track_stat->track_identifier);
1405 }
1406 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
1407}
1408
1409// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07001410// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
1411// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001412TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07001413 GetStatsForUnsignaledStreamWithNewStatsApi) {
1414 ASSERT_TRUE(CreatePeerConnectionWrappers());
1415 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001416 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07001417 // Remove SSRCs and MSIDs from the received offer SDP.
1418 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1419 caller()->CreateAndSetAndSignalOffer();
1420 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001421 MediaExpectations media_expectations;
1422 media_expectations.CalleeExpectsSomeAudio(1);
1423 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07001424
1425 // We received a frame, so we should have nonzero "bytes received" stats for
1426 // the unsignaled stream, if stats are working for it.
1427 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1428 callee()->NewGetStats();
1429 ASSERT_NE(nullptr, report);
1430 auto inbound_stream_stats =
1431 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1432 ASSERT_EQ(1U, inbound_stream_stats.size());
1433 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
1434 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07001435 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
1436}
1437
Taylor Brandstettera4653442018-06-19 09:44:26 -07001438// Same as above but for the legacy stats implementation.
1439TEST_P(PeerConnectionIntegrationTest,
1440 GetStatsForUnsignaledStreamWithOldStatsApi) {
1441 ASSERT_TRUE(CreatePeerConnectionWrappers());
1442 ConnectFakeSignaling();
1443 caller()->AddAudioTrack();
1444 // Remove SSRCs and MSIDs from the received offer SDP.
1445 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1446 caller()->CreateAndSetAndSignalOffer();
1447 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1448
1449 // Note that, since the old stats implementation associates SSRCs with tracks
1450 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
1451 // associated track ID. So we can't use the track "selector" argument.
1452 //
1453 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
1454 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001455 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07001456 kDefaultTimeout);
1457}
1458
zhihuangf8164932017-05-19 13:09:47 -07001459// Test that we can successfully get the media related stats (audio level
1460// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001461TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07001462 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
1463 ASSERT_TRUE(CreatePeerConnectionWrappers());
1464 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001465 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07001466 // Remove SSRCs and MSIDs from the received offer SDP.
1467 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1468 caller()->CreateAndSetAndSignalOffer();
1469 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001470 MediaExpectations media_expectations;
1471 media_expectations.CalleeExpectsSomeAudio(1);
1472 media_expectations.CalleeExpectsSomeVideo(1);
1473 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07001474
1475 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1476 callee()->NewGetStats();
1477 ASSERT_NE(nullptr, report);
1478
1479 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1480 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
1481 ASSERT_GE(audio_index, 0);
1482 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07001483}
1484
deadbeef4e2deab2017-09-20 13:56:21 -07001485// Helper for test below.
1486void ModifySsrcs(cricket::SessionDescription* desc) {
1487 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07001488 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08001489 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07001490 for (uint32_t& ssrc : stream.ssrcs) {
1491 ssrc = rtc::CreateRandomId();
1492 }
1493 }
1494 }
1495}
1496
1497// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
1498// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
1499// This should result in two "RTCInboundRTPStreamStats", but only one
1500// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
1501// being reset to 0 once the SSRC change occurs.
1502//
1503// Regression test for this bug:
1504// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
1505//
1506// The bug causes the track stats to only represent one of the two streams:
1507// whichever one has the higher SSRC. So with this bug, there was a 50% chance
1508// that the track stat counters would reset to 0 when the new stream is
1509// received, and a 50% chance that they'll stop updating (while
1510// "concealed_samples" continues increasing, due to silence being generated for
1511// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001512TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08001513 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07001514 ASSERT_TRUE(CreatePeerConnectionWrappers());
1515 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001516 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07001517 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
1518 // that doesn't signal SSRCs (from the callee's perspective).
1519 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1520 caller()->CreateAndSetAndSignalOffer();
1521 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1522 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001523 {
1524 MediaExpectations media_expectations;
1525 media_expectations.CalleeExpectsSomeAudio(50);
1526 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1527 }
deadbeef4e2deab2017-09-20 13:56:21 -07001528 // Some audio frames were received, so we should have nonzero "samples
1529 // received" for the track.
1530 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1531 callee()->NewGetStats();
1532 ASSERT_NE(nullptr, report);
1533 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1534 ASSERT_EQ(1U, track_stats.size());
1535 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1536 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
1537 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
1538
1539 // Create a new offer and munge it to cause the caller to use a new SSRC.
1540 caller()->SetGeneratedSdpMunger(ModifySsrcs);
1541 caller()->CreateAndSetAndSignalOffer();
1542 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1543 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
1544 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001545 {
1546 MediaExpectations media_expectations;
1547 media_expectations.CalleeExpectsSomeAudio(25);
1548 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1549 }
deadbeef4e2deab2017-09-20 13:56:21 -07001550
1551 report = callee()->NewGetStats();
1552 ASSERT_NE(nullptr, report);
1553 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1554 ASSERT_EQ(1U, track_stats.size());
1555 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1556 // The "total samples received" stat should only be greater than it was
1557 // before.
1558 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
1559 // Right now, the new SSRC will cause the counters to reset to 0.
1560 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
1561
1562 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08001563 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07001564 // good sign that we're seeing stats from the old stream that's no longer
1565 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08001566 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07001567 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
1568 EXPECT_LT(*track_stats[0]->concealed_samples,
1569 *track_stats[0]->total_samples_received *
1570 kAcceptableConcealedSamplesPercentage);
1571
1572 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
1573 // sanity check that the SSRC really changed.
1574 // TODO(deadbeef): This isn't working right now, because we're not returning
1575 // *any* stats for the inactive stream. Uncomment when the bug is completely
1576 // fixed.
1577 // auto inbound_stream_stats =
1578 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1579 // ASSERT_EQ(2U, inbound_stream_stats.size());
1580}
1581
deadbeef1dcb1642017-03-29 21:08:16 -07001582// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001583TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001584 PeerConnectionFactory::Options dtls_10_options;
1585 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1586 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1587 dtls_10_options));
1588 ConnectFakeSignaling();
1589 // Do normal offer/answer and wait for some frames to be received in each
1590 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001591 caller()->AddAudioVideoTracks();
1592 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001593 caller()->CreateAndSetAndSignalOffer();
1594 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001595 MediaExpectations media_expectations;
1596 media_expectations.ExpectBidirectionalAudioAndVideo();
1597 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001598}
1599
1600// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001601TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001602 PeerConnectionFactory::Options dtls_10_options;
1603 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1604 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1605 dtls_10_options));
1606 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001607 caller()->AddAudioVideoTracks();
1608 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001609 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001610 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001611 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001612 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001613 kDefaultTimeout);
1614 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001615 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001616 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001617 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1618 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1619 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001620}
1621
1622// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001623TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001624 PeerConnectionFactory::Options dtls_12_options;
1625 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1626 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
1627 dtls_12_options));
1628 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001629 caller()->AddAudioVideoTracks();
1630 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001631 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001632 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001633 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001634 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001635 kDefaultTimeout);
1636 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001637 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001638 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001639 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1640 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1641 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001642}
1643
1644// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
1645// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001646TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001647 PeerConnectionFactory::Options caller_options;
1648 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1649 PeerConnectionFactory::Options callee_options;
1650 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1651 ASSERT_TRUE(
1652 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1653 ConnectFakeSignaling();
1654 // Do normal offer/answer and wait for some frames to be received in each
1655 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001656 caller()->AddAudioVideoTracks();
1657 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001658 caller()->CreateAndSetAndSignalOffer();
1659 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001660 MediaExpectations media_expectations;
1661 media_expectations.ExpectBidirectionalAudioAndVideo();
1662 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001663}
1664
1665// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
1666// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001667TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07001668 PeerConnectionFactory::Options caller_options;
1669 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1670 PeerConnectionFactory::Options callee_options;
1671 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1672 ASSERT_TRUE(
1673 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1674 ConnectFakeSignaling();
1675 // Do normal offer/answer and wait for some frames to be received in each
1676 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001677 caller()->AddAudioVideoTracks();
1678 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001679 caller()->CreateAndSetAndSignalOffer();
1680 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001681 MediaExpectations media_expectations;
1682 media_expectations.ExpectBidirectionalAudioAndVideo();
1683 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001684}
1685
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001686// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
1687// works as expected; the cipher should only be used if enabled by both sides.
1688TEST_P(PeerConnectionIntegrationTest,
1689 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
1690 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001691 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001692 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001693 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1694 false;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001695 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001696 TestNegotiatedCipherSuite(caller_options, callee_options,
1697 expected_cipher_suite);
1698}
1699
1700TEST_P(PeerConnectionIntegrationTest,
1701 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
1702 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001703 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1704 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001705 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001706 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001707 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001708 TestNegotiatedCipherSuite(caller_options, callee_options,
1709 expected_cipher_suite);
1710}
1711
1712TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
1713 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001714 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001715 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001716 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001717 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_32;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001718 TestNegotiatedCipherSuite(caller_options, callee_options,
1719 expected_cipher_suite);
1720}
1721
deadbeef1dcb1642017-03-29 21:08:16 -07001722// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001723TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001724 bool local_gcm_enabled = false;
1725 bool remote_gcm_enabled = false;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001726 bool aes_ctr_enabled = true;
deadbeef1dcb1642017-03-29 21:08:16 -07001727 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
1728 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001729 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001730}
1731
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001732// Test that a GCM cipher is used if both ends support it and non-GCM is
1733// disabled.
1734TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001735 bool local_gcm_enabled = true;
1736 bool remote_gcm_enabled = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001737 bool aes_ctr_enabled = false;
deadbeef1dcb1642017-03-29 21:08:16 -07001738 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
1739 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001740 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001741}
1742
deadbeef7914b8c2017-04-21 03:23:33 -07001743// Verify that media can be transmitted end-to-end when GCM crypto suites are
1744// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
1745// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
1746// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001747TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07001748 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001749 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001750 gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false;
deadbeef7914b8c2017-04-21 03:23:33 -07001751 ASSERT_TRUE(
1752 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
1753 ConnectFakeSignaling();
1754 // Do normal offer/answer and wait for some frames to be received in each
1755 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001756 caller()->AddAudioVideoTracks();
1757 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07001758 caller()->CreateAndSetAndSignalOffer();
1759 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001760 MediaExpectations media_expectations;
1761 media_expectations.ExpectBidirectionalAudioAndVideo();
1762 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07001763}
1764
deadbeef1dcb1642017-03-29 21:08:16 -07001765// Test that the ICE connection and gathering states eventually reach
1766// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08001767TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07001768 ASSERT_TRUE(CreatePeerConnectionWrappers());
1769 ConnectFakeSignaling();
1770 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001771 caller()->AddAudioVideoTracks();
1772 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001773 caller()->CreateAndSetAndSignalOffer();
1774 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1775 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1776 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
1777 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1778 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
1779 // After the best candidate pair is selected and all candidates are signaled,
1780 // the ICE connection state should reach "complete".
1781 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
1782 // answerer/"callee" by default) only reaches "connected". When this is
1783 // fixed, this test should be updated.
1784 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1785 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00001786 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1787 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001788}
1789
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001790constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
1791 cricket::PORTALLOCATOR_DISABLE_RELAY |
1792 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001793
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001794// Use a mock resolver to resolve the hostname back to the original IP on both
1795// sides and check that the ICE connection connects.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001796TEST_P(PeerConnectionIntegrationTest,
Harald Alvestrand099ff622022-06-02 13:24:32 +00001797 IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001798 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001799 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001800 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001801 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001802 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
1803 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001804
1805 // This also verifies that the injected AsyncResolverFactory is used by
1806 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001807 EXPECT_CALL(*caller_resolver_factory, Create())
1808 .WillOnce(Return(&caller_async_resolver));
1809 webrtc::PeerConnectionDependencies caller_deps(nullptr);
1810 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
1811
1812 EXPECT_CALL(*callee_resolver_factory, Create())
1813 .WillOnce(Return(&callee_async_resolver));
1814 webrtc::PeerConnectionDependencies callee_deps(nullptr);
1815 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
1816
1817 PeerConnectionInterface::RTCConfiguration config;
1818 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
1819 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
1820
1821 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
1822 config, std::move(caller_deps), config, std::move(callee_deps)));
1823
1824 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
1825 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
1826
1827 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07001828 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001829 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07001830 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001831 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001832
1833 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001834
1835 ConnectFakeSignaling();
1836 caller()->AddAudioVideoTracks();
1837 callee()->AddAudioVideoTracks();
1838 caller()->CreateAndSetAndSignalOffer();
1839 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1840 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1841 caller()->ice_connection_state(), kDefaultTimeout);
1842 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1843 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08001844
Ying Wangef3998f2019-12-09 13:06:53 +01001845 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1846 "WebRTC.PeerConnection.CandidatePairType_UDP",
1847 webrtc::kIceCandidatePairHostNameHostName));
Harald Alvestrand4f7486a2022-06-02 11:35:49 +00001848 DestroyPeerConnections();
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001849}
1850
Steve Antonede9ca52017-10-16 13:04:27 -07001851// Test that firewalling the ICE connection causes the clients to identify the
1852// disconnected state and then removing the firewall causes them to reconnect.
1853class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08001854 : public PeerConnectionIntegrationBaseTest,
1855 public ::testing::WithParamInterface<
1856 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07001857 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001858 PeerConnectionIntegrationIceStatesTest()
1859 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
1860 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07001861 }
1862
1863 void StartStunServer(const SocketAddress& server_address) {
1864 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01001865 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07001866 }
1867
1868 bool TestIPv6() {
1869 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
1870 }
1871
1872 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001873 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
1874 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07001875 }
1876
1877 std::vector<SocketAddress> CallerAddresses() {
1878 std::vector<SocketAddress> addresses;
1879 addresses.push_back(SocketAddress("1.1.1.1", 0));
1880 if (TestIPv6()) {
1881 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
1882 }
1883 return addresses;
1884 }
1885
1886 std::vector<SocketAddress> CalleeAddresses() {
1887 std::vector<SocketAddress> addresses;
1888 addresses.push_back(SocketAddress("2.2.2.2", 0));
1889 if (TestIPv6()) {
1890 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
1891 }
1892 return addresses;
1893 }
1894
1895 void SetUpNetworkInterfaces() {
1896 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07001897 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
1898 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07001899
1900 // Add network addresses for test.
1901 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001902 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001903 }
1904 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001905 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001906 }
1907 }
1908
1909 private:
1910 uint32_t port_allocator_flags_;
1911 std::unique_ptr<cricket::TestStunServer> stun_server_;
1912};
1913
Yves Gerey100fe632020-01-17 19:15:53 +01001914// Ensure FakeClockForTest is constructed first (see class for rationale).
1915class PeerConnectionIntegrationIceStatesTestWithFakeClock
1916 : public FakeClockForTest,
1917 public PeerConnectionIntegrationIceStatesTest {};
1918
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001919#if !defined(THREAD_SANITIZER)
1920// This test provokes TSAN errors. bugs.webrtc.org/11282
1921
Jonas Olssonb75d9e92019-02-22 10:33:29 +01001922// Tests that if the connection doesn't get set up properly we eventually reach
1923// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01001924TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
1925 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01001926 // Block connections to/from the caller and wait for ICE to become
1927 // disconnected.
1928 for (const auto& caller_address : CallerAddresses()) {
1929 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
1930 }
1931
1932 ASSERT_TRUE(CreatePeerConnectionWrappers());
1933 ConnectFakeSignaling();
1934 SetPortAllocatorFlags();
1935 SetUpNetworkInterfaces();
1936 caller()->AddAudioVideoTracks();
1937 caller()->CreateAndSetAndSignalOffer();
1938
1939 // According to RFC7675, if there is no response within 30 seconds then the
1940 // peer should consider the other side to have rejected the connection. This
1941 // is signaled by the state transitioning to "failed".
1942 constexpr int kConsentTimeout = 30000;
1943 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
1944 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01001945 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07001946}
1947
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001948#endif // !defined(THREAD_SANITIZER)
1949
Steve Antonede9ca52017-10-16 13:04:27 -07001950// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
1951// and that the statistics in the metric observers are updated correctly.
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001952// TODO(bugs.webrtc.org/12591): Flaky on Windows.
1953#if defined(WEBRTC_WIN)
1954#define MAYBE_VerifyBestConnection DISABLED_VerifyBestConnection
1955#else
1956#define MAYBE_VerifyBestConnection VerifyBestConnection
1957#endif
1958TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
Steve Antonede9ca52017-10-16 13:04:27 -07001959 ASSERT_TRUE(CreatePeerConnectionWrappers());
1960 ConnectFakeSignaling();
1961 SetPortAllocatorFlags();
1962 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08001963 caller()->AddAudioVideoTracks();
1964 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07001965 caller()->CreateAndSetAndSignalOffer();
1966
1967 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08001968 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1969 caller()->ice_connection_state(), kDefaultTimeout);
1970 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1971 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07001972
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001973 // TODO(bugs.webrtc.org/9456): Fix it.
1974 const int num_best_ipv4 = webrtc::metrics::NumEvents(
1975 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
1976 const int num_best_ipv6 = webrtc::metrics::NumEvents(
1977 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001978 if (TestIPv6()) {
1979 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
1980 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01001981 EXPECT_METRIC_EQ(0, num_best_ipv4);
1982 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001983 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01001984 EXPECT_METRIC_EQ(1, num_best_ipv4);
1985 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001986 }
1987
Ying Wangef3998f2019-12-09 13:06:53 +01001988 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
1989 "WebRTC.PeerConnection.CandidatePairType_UDP",
1990 webrtc::kIceCandidatePairHostHost));
1991 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1992 "WebRTC.PeerConnection.CandidatePairType_UDP",
1993 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07001994}
1995
1996constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
1997 cricket::PORTALLOCATOR_DISABLE_STUN |
1998 cricket::PORTALLOCATOR_DISABLE_RELAY;
1999constexpr uint32_t kFlagsIPv6NoStun =
2000 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
2001 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
2002constexpr uint32_t kFlagsIPv4Stun =
2003 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
2004
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002005INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002006 PeerConnectionIntegrationTest,
2007 PeerConnectionIntegrationIceStatesTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02002008 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Seth Hampson2f0d7022018-02-20 11:54:42 -08002009 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2010 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2011 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07002012
Yves Gerey100fe632020-01-17 19:15:53 +01002013INSTANTIATE_TEST_SUITE_P(
2014 PeerConnectionIntegrationTest,
2015 PeerConnectionIntegrationIceStatesTestWithFakeClock,
Florent Castelli15a38de2022-04-06 00:38:21 +02002016 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Yves Gerey100fe632020-01-17 19:15:53 +01002017 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2018 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2019 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
2020
deadbeef1dcb1642017-03-29 21:08:16 -07002021// This test sets up a call between two parties with audio and video.
2022// During the call, the caller restarts ICE and the test verifies that
2023// new ICE candidates are generated and audio and video still can flow, and the
2024// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002025TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07002026 ASSERT_TRUE(CreatePeerConnectionWrappers());
2027 ConnectFakeSignaling();
2028 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08002029 caller()->AddAudioVideoTracks();
2030 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002031 caller()->CreateAndSetAndSignalOffer();
2032 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2033 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2034 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002035 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2036 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07002037
2038 // To verify that the ICE restart actually occurs, get
2039 // ufrag/password/candidates before and after restart.
2040 // Create an SDP string of the first audio candidate for both clients.
2041 const webrtc::IceCandidateCollection* audio_candidates_caller =
2042 caller()->pc()->local_description()->candidates(0);
2043 const webrtc::IceCandidateCollection* audio_candidates_callee =
2044 callee()->pc()->local_description()->candidates(0);
2045 ASSERT_GT(audio_candidates_caller->count(), 0u);
2046 ASSERT_GT(audio_candidates_callee->count(), 0u);
2047 std::string caller_candidate_pre_restart;
2048 ASSERT_TRUE(
2049 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
2050 std::string callee_candidate_pre_restart;
2051 ASSERT_TRUE(
2052 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
2053 const cricket::SessionDescription* desc =
2054 caller()->pc()->local_description()->description();
2055 std::string caller_ufrag_pre_restart =
2056 desc->transport_infos()[0].description.ice_ufrag;
2057 desc = callee()->pc()->local_description()->description();
2058 std::string callee_ufrag_pre_restart =
2059 desc->transport_infos()[0].description.ice_ufrag;
2060
Alex Drake00c7ecf2019-08-06 10:54:47 -07002061 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002062 // Have the caller initiate an ICE restart.
2063 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2064 caller()->CreateAndSetAndSignalOffer();
2065 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2066 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2067 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002068 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07002069 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2070
2071 // Grab the ufrags/candidates again.
2072 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
2073 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
2074 ASSERT_GT(audio_candidates_caller->count(), 0u);
2075 ASSERT_GT(audio_candidates_callee->count(), 0u);
2076 std::string caller_candidate_post_restart;
2077 ASSERT_TRUE(
2078 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
2079 std::string callee_candidate_post_restart;
2080 ASSERT_TRUE(
2081 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
2082 desc = caller()->pc()->local_description()->description();
2083 std::string caller_ufrag_post_restart =
2084 desc->transport_infos()[0].description.ice_ufrag;
2085 desc = callee()->pc()->local_description()->description();
2086 std::string callee_ufrag_post_restart =
2087 desc->transport_infos()[0].description.ice_ufrag;
2088 // Sanity check that an ICE restart was actually negotiated in SDP.
2089 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
2090 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
2091 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
2092 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07002093 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002094
2095 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002096 MediaExpectations media_expectations;
2097 media_expectations.ExpectBidirectionalAudioAndVideo();
2098 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002099}
2100
2101// Verify that audio/video can be received end-to-end when ICE renomination is
2102// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002103TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07002104 PeerConnectionInterface::RTCConfiguration config;
2105 config.enable_ice_renomination = true;
2106 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2107 ConnectFakeSignaling();
2108 // Do normal offer/answer and wait for some frames to be received in each
2109 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002110 caller()->AddAudioVideoTracks();
2111 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002112 caller()->CreateAndSetAndSignalOffer();
2113 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2114 // Sanity check that ICE renomination was actually negotiated.
2115 const cricket::SessionDescription* desc =
2116 caller()->pc()->local_description()->description();
2117 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002118 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002119 }
2120 desc = callee()->pc()->local_description()->description();
2121 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002122 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002123 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08002124 MediaExpectations media_expectations;
2125 media_expectations.ExpectBidirectionalAudioAndVideo();
2126 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002127}
2128
Steve Anton6f25b092017-10-23 09:39:20 -07002129// With a max bundle policy and RTCP muxing, adding a new media description to
2130// the connection should not affect ICE at all because the new media will use
2131// the existing connection.
Rasmus Brandt685be142021-03-15 14:03:38 +01002132// TODO(bugs.webrtc.org/12538): Fails on tsan.
2133#if defined(THREAD_SANITIZER)
2134#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2135 DISABLED_AddMediaToConnectedBundleDoesNotRestartIce
2136#else
2137#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2138 AddMediaToConnectedBundleDoesNotRestartIce
2139#endif
Seth Hampson2f0d7022018-02-20 11:54:42 -08002140TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt685be142021-03-15 14:03:38 +01002141 MAYBE_AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07002142 PeerConnectionInterface::RTCConfiguration config;
2143 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
2144 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
2145 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
2146 config, PeerConnectionInterface::RTCConfiguration()));
2147 ConnectFakeSignaling();
2148
Steve Anton15324772018-01-16 10:26:49 -08002149 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002150 caller()->CreateAndSetAndSignalOffer();
2151 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07002152 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2153 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07002154
2155 caller()->clear_ice_connection_state_history();
2156
Steve Anton15324772018-01-16 10:26:49 -08002157 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002158 caller()->CreateAndSetAndSignalOffer();
2159 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2160
2161 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
2162}
2163
deadbeef1dcb1642017-03-29 21:08:16 -07002164// This test sets up a call between two parties with audio and video. It then
2165// renegotiates setting the video m-line to "port 0", then later renegotiates
2166// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002167TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002168 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
2169 ASSERT_TRUE(CreatePeerConnectionWrappers());
2170 ConnectFakeSignaling();
2171
2172 // Do initial negotiation, only sending media from the caller. Will result in
2173 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08002174 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002175 caller()->CreateAndSetAndSignalOffer();
2176 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2177
2178 // Negotiate again, disabling the video "m=" section (the callee will set the
2179 // port to 0 due to offer_to_receive_video = 0).
Florent Castelli15a38de2022-04-06 00:38:21 +02002180 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002181 PeerConnectionInterface::RTCOfferAnswerOptions options;
2182 options.offer_to_receive_video = 0;
2183 callee()->SetOfferAnswerOptions(options);
2184 } else {
2185 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002186 callee()
2187 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2188 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002189 });
2190 }
deadbeef1dcb1642017-03-29 21:08:16 -07002191 caller()->CreateAndSetAndSignalOffer();
2192 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2193 // Sanity check that video "m=" section was actually rejected.
2194 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
2195 callee()->pc()->local_description()->description());
2196 ASSERT_NE(nullptr, answer_video_content);
2197 ASSERT_TRUE(answer_video_content->rejected);
2198
2199 // Enable video and do negotiation again, making sure video is received
2200 // end-to-end, also adding media stream to callee.
Florent Castelli15a38de2022-04-06 00:38:21 +02002201 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002202 PeerConnectionInterface::RTCOfferAnswerOptions options;
2203 options.offer_to_receive_video = 1;
2204 callee()->SetOfferAnswerOptions(options);
2205 } else {
2206 // The caller's transceiver is stopped, so we need to add another track.
2207 auto caller_transceiver =
2208 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002209 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002210 caller()->AddVideoTrack();
2211 }
2212 callee()->AddVideoTrack();
2213 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07002214 caller()->CreateAndSetAndSignalOffer();
2215 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002216
deadbeef1dcb1642017-03-29 21:08:16 -07002217 // Verify the caller receives frames from the newly added stream, and the
2218 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002219 MediaExpectations media_expectations;
2220 media_expectations.CalleeExpectsSomeAudio();
2221 media_expectations.ExpectBidirectionalVideo();
2222 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002223}
2224
deadbeef1dcb1642017-03-29 21:08:16 -07002225// This tests that if we negotiate after calling CreateSender but before we
2226// have a track, then set a track later, frames from the newly-set track are
2227// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002228TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07002229 MediaFlowsAfterEarlyWarmupWithCreateSender) {
2230 ASSERT_TRUE(CreatePeerConnectionWrappers());
2231 ConnectFakeSignaling();
2232 auto caller_audio_sender =
2233 caller()->pc()->CreateSender("audio", "caller_stream");
2234 auto caller_video_sender =
2235 caller()->pc()->CreateSender("video", "caller_stream");
2236 auto callee_audio_sender =
2237 callee()->pc()->CreateSender("audio", "callee_stream");
2238 auto callee_video_sender =
2239 callee()->pc()->CreateSender("video", "callee_stream");
2240 caller()->CreateAndSetAndSignalOffer();
2241 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2242 // Wait for ICE to complete, without any tracks being set.
2243 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2244 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2245 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2246 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2247 // Now set the tracks, and expect frames to immediately start flowing.
Niels Möllerafb246b2022-04-20 14:26:50 +02002248 EXPECT_TRUE(
2249 caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2250 EXPECT_TRUE(
2251 caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2252 EXPECT_TRUE(
2253 callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2254 EXPECT_TRUE(
2255 callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002256 MediaExpectations media_expectations;
2257 media_expectations.ExpectBidirectionalAudioAndVideo();
2258 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2259}
2260
2261// This tests that if we negotiate after calling AddTransceiver but before we
2262// have a track, then set a track later, frames from the newly-set tracks are
2263// received end-to-end.
2264TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2265 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
2266 ASSERT_TRUE(CreatePeerConnectionWrappers());
2267 ConnectFakeSignaling();
2268 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
2269 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
2270 auto caller_audio_sender = audio_result.MoveValue()->sender();
2271 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
2272 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
2273 auto caller_video_sender = video_result.MoveValue()->sender();
2274 callee()->SetRemoteOfferHandler([this] {
2275 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02002276 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002277 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002278 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002279 RtpTransceiverDirection::kSendRecv);
2280 });
2281 caller()->CreateAndSetAndSignalOffer();
2282 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2283 // Wait for ICE to complete, without any tracks being set.
2284 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2285 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2286 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2287 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2288 // Now set the tracks, and expect frames to immediately start flowing.
2289 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
2290 auto callee_video_sender = callee()->pc()->GetSenders()[1];
Niels Möllerafb246b2022-04-20 14:26:50 +02002291 ASSERT_TRUE(
2292 caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2293 ASSERT_TRUE(
2294 caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2295 ASSERT_TRUE(
2296 callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2297 ASSERT_TRUE(
2298 callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002299 MediaExpectations media_expectations;
2300 media_expectations.ExpectBidirectionalAudioAndVideo();
2301 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002302}
2303
2304// This test verifies that a remote video track can be added via AddStream,
2305// and sent end-to-end. For this particular test, it's simply echoed back
2306// from the caller to the callee, rather than being forwarded to a third
2307// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002308TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07002309 ASSERT_TRUE(CreatePeerConnectionWrappers());
2310 ConnectFakeSignaling();
2311 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08002312 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002313 caller()->CreateAndSetAndSignalOffer();
2314 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002315 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07002316
2317 // Echo the stream back, and do a new offer/anwer (initiated by callee this
2318 // time).
2319 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
2320 callee()->CreateAndSetAndSignalOffer();
2321 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2322
Seth Hampson2f0d7022018-02-20 11:54:42 -08002323 MediaExpectations media_expectations;
2324 media_expectations.ExpectBidirectionalVideo();
2325 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002326}
2327
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002328#if !defined(THREAD_SANITIZER)
2329// This test provokes TSAN errors. bugs.webrtc.org/11282
2330
deadbeef1dcb1642017-03-29 21:08:16 -07002331// Test that we achieve the expected end-to-end connection time, using a
2332// fake clock and simulated latency on the media and signaling paths.
2333// We use a TURN<->TURN connection because this is usually the quickest to
2334// set up initially, especially when we're confident the connection will work
2335// and can start sending media before we get a STUN response.
2336//
2337// With various optimizations enabled, here are the network delays we expect to
2338// be on the critical path:
2339// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
2340// signaling answer (with DTLS fingerprint).
2341// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
2342// using TURN<->TURN pair, and DTLS exchange is 4 packets,
2343// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01002344TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2345 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07002346 static constexpr int media_hop_delay_ms = 50;
2347 static constexpr int signaling_trip_delay_ms = 500;
2348 // For explanation of these values, see comment above.
2349 static constexpr int required_media_hops = 9;
2350 static constexpr int required_signaling_trips = 2;
2351 // For internal delays (such as posting an event asychronously).
2352 static constexpr int allowed_internal_delay_ms = 20;
2353 static constexpr int total_connection_time_ms =
2354 media_hop_delay_ms * required_media_hops +
2355 signaling_trip_delay_ms * required_signaling_trips +
2356 allowed_internal_delay_ms;
2357
2358 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2359 3478};
2360 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2361 0};
2362 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2363 3478};
2364 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2365 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002366 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
2367 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002368
Seth Hampsonaed71642018-06-11 07:41:32 -07002369 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
2370 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07002371 // Bypass permission check on received packets so media can be sent before
2372 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07002373 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
2374 turn_server_1->set_enable_permission_checks(false);
2375 });
2376 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
2377 turn_server_2->set_enable_permission_checks(false);
2378 });
deadbeef1dcb1642017-03-29 21:08:16 -07002379
2380 PeerConnectionInterface::RTCConfiguration client_1_config;
2381 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2382 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2383 ice_server_1.username = "test";
2384 ice_server_1.password = "test";
2385 client_1_config.servers.push_back(ice_server_1);
2386 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2387 client_1_config.presume_writable_when_fully_relayed = true;
2388
2389 PeerConnectionInterface::RTCConfiguration client_2_config;
2390 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2391 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2392 ice_server_2.username = "test";
2393 ice_server_2.password = "test";
2394 client_2_config.servers.push_back(ice_server_2);
2395 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2396 client_2_config.presume_writable_when_fully_relayed = true;
2397
2398 ASSERT_TRUE(
2399 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2400 // Set up the simulated delays.
2401 SetSignalingDelayMs(signaling_trip_delay_ms);
2402 ConnectFakeSignaling();
2403 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
2404 virtual_socket_server()->UpdateDelayDistribution();
2405
2406 // Set "offer to receive audio/video" without adding any tracks, so we just
2407 // set up ICE/DTLS with no media.
2408 PeerConnectionInterface::RTCOfferAnswerOptions options;
2409 options.offer_to_receive_audio = 1;
2410 options.offer_to_receive_video = 1;
2411 caller()->SetOfferAnswerOptions(options);
2412 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07002413 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01002414 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07002415 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
2416 // If this is not done a DCHECK can be hit in ports.cc, because a large
2417 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07002418 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07002419}
2420
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002421#endif // !defined(THREAD_SANITIZER)
2422
Jonas Orelandbdcee282017-10-10 14:01:40 +02002423// Verify that a TurnCustomizer passed in through RTCConfiguration
2424// is actually used by the underlying TURN candidate pair.
2425// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002426TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02002427 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2428 3478};
2429 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2430 0};
2431 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2432 3478};
2433 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2434 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002435 CreateTurnServer(turn_server_1_internal_address,
2436 turn_server_1_external_address);
2437 CreateTurnServer(turn_server_2_internal_address,
2438 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002439
2440 PeerConnectionInterface::RTCConfiguration client_1_config;
2441 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2442 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2443 ice_server_1.username = "test";
2444 ice_server_1.password = "test";
2445 client_1_config.servers.push_back(ice_server_1);
2446 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002447 auto* customizer1 = CreateTurnCustomizer();
2448 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002449
2450 PeerConnectionInterface::RTCConfiguration client_2_config;
2451 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2452 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2453 ice_server_2.username = "test";
2454 ice_server_2.password = "test";
2455 client_2_config.servers.push_back(ice_server_2);
2456 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002457 auto* customizer2 = CreateTurnCustomizer();
2458 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002459
2460 ASSERT_TRUE(
2461 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2462 ConnectFakeSignaling();
2463
2464 // Set "offer to receive audio/video" without adding any tracks, so we just
2465 // set up ICE/DTLS with no media.
2466 PeerConnectionInterface::RTCOfferAnswerOptions options;
2467 options.offer_to_receive_audio = 1;
2468 options.offer_to_receive_video = 1;
2469 caller()->SetOfferAnswerOptions(options);
2470 caller()->CreateAndSetAndSignalOffer();
2471 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2472
Seth Hampsonaed71642018-06-11 07:41:32 -07002473 ExpectTurnCustomizerCountersIncremented(customizer1);
2474 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002475}
2476
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002477// Verifies that you can use TCP instead of UDP to connect to a TURN server and
2478// send media between the caller and the callee.
2479TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
2480 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2481 3478};
2482 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2483
2484 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07002485 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2486 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002487
2488 webrtc::PeerConnectionInterface::IceServer ice_server;
2489 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
2490 ice_server.username = "test";
2491 ice_server.password = "test";
2492
2493 PeerConnectionInterface::RTCConfiguration client_1_config;
2494 client_1_config.servers.push_back(ice_server);
2495 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2496
2497 PeerConnectionInterface::RTCConfiguration client_2_config;
2498 client_2_config.servers.push_back(ice_server);
2499 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2500
2501 ASSERT_TRUE(
2502 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2503
2504 // Do normal offer/answer and wait for ICE to complete.
2505 ConnectFakeSignaling();
2506 caller()->AddAudioVideoTracks();
2507 callee()->AddAudioVideoTracks();
2508 caller()->CreateAndSetAndSignalOffer();
2509 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2510 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2511 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2512
2513 MediaExpectations media_expectations;
2514 media_expectations.ExpectBidirectionalAudioAndVideo();
2515 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2516}
2517
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002518// Verify that a SSLCertificateVerifier passed in through
2519// PeerConnectionDependencies is actually used by the underlying SSL
2520// implementation to determine whether a certificate presented by the TURN
2521// server is accepted by the client. Note that openssladapter_unittest.cc
2522// contains more detailed, lower-level tests.
2523TEST_P(PeerConnectionIntegrationTest,
2524 SSLCertificateVerifierUsedForTurnConnections) {
2525 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2526 3478};
2527 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2528
2529 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2530 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002531 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2532 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002533
2534 webrtc::PeerConnectionInterface::IceServer ice_server;
2535 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2536 ice_server.username = "test";
2537 ice_server.password = "test";
2538
2539 PeerConnectionInterface::RTCConfiguration client_1_config;
2540 client_1_config.servers.push_back(ice_server);
2541 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2542
2543 PeerConnectionInterface::RTCConfiguration client_2_config;
2544 client_2_config.servers.push_back(ice_server);
2545 // Setting the type to kRelay forces the connection to go through a TURN
2546 // server.
2547 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2548
2549 // Get a copy to the pointer so we can verify calls later.
2550 rtc::TestCertificateVerifier* client_1_cert_verifier =
2551 new rtc::TestCertificateVerifier();
2552 client_1_cert_verifier->verify_certificate_ = true;
2553 rtc::TestCertificateVerifier* client_2_cert_verifier =
2554 new rtc::TestCertificateVerifier();
2555 client_2_cert_verifier->verify_certificate_ = true;
2556
2557 // Create the dependencies with the test certificate verifier.
2558 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2559 client_1_deps.tls_cert_verifier =
2560 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2561 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2562 client_2_deps.tls_cert_verifier =
2563 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2564
2565 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2566 client_1_config, std::move(client_1_deps), client_2_config,
2567 std::move(client_2_deps)));
2568 ConnectFakeSignaling();
2569
2570 // Set "offer to receive audio/video" without adding any tracks, so we just
2571 // set up ICE/DTLS with no media.
2572 PeerConnectionInterface::RTCOfferAnswerOptions options;
2573 options.offer_to_receive_audio = 1;
2574 options.offer_to_receive_video = 1;
2575 caller()->SetOfferAnswerOptions(options);
2576 caller()->CreateAndSetAndSignalOffer();
2577 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2578
2579 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2580 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002581}
2582
Qingsi Wang25ec8882019-11-15 12:33:05 -08002583// Test that the injected ICE transport factory is used to create ICE transports
2584// for WebRTC connections.
2585TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
2586 PeerConnectionInterface::RTCConfiguration default_config;
2587 PeerConnectionDependencies dependencies(nullptr);
2588 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
2589 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
2590 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02002591 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
2592 std::move(dependencies), nullptr,
2593 /*reset_encoder_factory=*/false,
2594 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08002595 ASSERT_TRUE(wrapper);
2596 wrapper->CreateDataChannel();
Tommi87f70902021-04-27 14:43:08 +02002597 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02002598 wrapper->pc()->SetLocalDescription(observer.get(),
Qingsi Wang25ec8882019-11-15 12:33:05 -08002599 wrapper->CreateOfferAndWait().release());
2600}
2601
deadbeefc964d0b2017-04-03 10:03:35 -07002602// Test that audio and video flow end-to-end when codec names don't use the
2603// expected casing, given that they're supposed to be case insensitive. To test
2604// this, all but one codec is removed from each media description, and its
2605// casing is changed.
2606//
2607// In the past, this has regressed and caused crashes/black video, due to the
2608// fact that code at some layers was doing case-insensitive comparisons and
2609// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002610TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07002611 ASSERT_TRUE(CreatePeerConnectionWrappers());
2612 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002613 caller()->AddAudioVideoTracks();
2614 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07002615
2616 // Remove all but one audio/video codec (opus and VP8), and change the
2617 // casing of the caller's generated offer.
2618 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
2619 cricket::AudioContentDescription* audio =
2620 GetFirstAudioContentDescription(description);
2621 ASSERT_NE(nullptr, audio);
2622 auto audio_codecs = audio->codecs();
2623 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
2624 [](const cricket::AudioCodec& codec) {
2625 return codec.name != "opus";
2626 }),
2627 audio_codecs.end());
2628 ASSERT_EQ(1u, audio_codecs.size());
2629 audio_codecs[0].name = "OpUs";
2630 audio->set_codecs(audio_codecs);
2631
2632 cricket::VideoContentDescription* video =
2633 GetFirstVideoContentDescription(description);
2634 ASSERT_NE(nullptr, video);
2635 auto video_codecs = video->codecs();
2636 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
2637 [](const cricket::VideoCodec& codec) {
2638 return codec.name != "VP8";
2639 }),
2640 video_codecs.end());
2641 ASSERT_EQ(1u, video_codecs.size());
2642 video_codecs[0].name = "vP8";
2643 video->set_codecs(video_codecs);
2644 });
2645
2646 caller()->CreateAndSetAndSignalOffer();
2647 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2648
2649 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002650 MediaExpectations media_expectations;
2651 media_expectations.ExpectBidirectionalAudioAndVideo();
2652 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07002653}
2654
Jonas Oreland49ac5952018-09-26 16:04:32 +02002655TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07002656 ASSERT_TRUE(CreatePeerConnectionWrappers());
2657 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002658 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07002659 caller()->CreateAndSetAndSignalOffer();
2660 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07002661 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002662 MediaExpectations media_expectations;
2663 media_expectations.CalleeExpectsSomeAudio(1);
2664 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02002665 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07002666 auto receiver = callee()->pc()->GetReceivers()[0];
2667 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002668 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07002669 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
2670 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02002671 sources[0].source_id());
2672 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
2673}
2674
2675TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
2676 ASSERT_TRUE(CreatePeerConnectionWrappers());
2677 ConnectFakeSignaling();
2678 caller()->AddVideoTrack();
2679 caller()->CreateAndSetAndSignalOffer();
2680 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2681 // Wait for one video frame to be received by the callee.
2682 MediaExpectations media_expectations;
2683 media_expectations.CalleeExpectsSomeVideo(1);
2684 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2685 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2686 auto receiver = callee()->pc()->GetReceivers()[0];
2687 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
2688 auto sources = receiver->GetSources();
2689 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02002690 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002691 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
2692 sources[0].source_id());
2693 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07002694}
2695
deadbeef2f425aa2017-04-14 10:41:32 -07002696// Test that if a track is removed and added again with a different stream ID,
2697// the new stream ID is successfully communicated in SDP and media continues to
2698// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002699// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
2700// it will not reuse a transceiver that has already been sending. After creating
2701// a new transceiver it tries to create an offer with two senders of the same
2702// track ids and it fails.
2703TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07002704 ASSERT_TRUE(CreatePeerConnectionWrappers());
2705 ConnectFakeSignaling();
2706
deadbeef2f425aa2017-04-14 10:41:32 -07002707 // Add track using stream 1, do offer/answer.
2708 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2709 caller()->CreateLocalAudioTrack();
2710 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07002711 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07002712 caller()->CreateAndSetAndSignalOffer();
2713 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002714 {
2715 MediaExpectations media_expectations;
2716 media_expectations.CalleeExpectsSomeAudio(1);
2717 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2718 }
deadbeef2f425aa2017-04-14 10:41:32 -07002719 // Remove the sender, and create a new one with the new stream.
Harald Alvestrand93dd7632022-01-19 12:28:45 +00002720 caller()->pc()->RemoveTrackOrError(sender);
Steve Antond78323f2018-07-11 11:13:44 -07002721 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07002722 caller()->CreateAndSetAndSignalOffer();
2723 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2724 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002725 {
2726 MediaExpectations media_expectations;
2727 media_expectations.CalleeExpectsSomeAudio();
2728 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2729 }
deadbeef2f425aa2017-04-14 10:41:32 -07002730}
2731
Seth Hampson2f0d7022018-02-20 11:54:42 -08002732TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02002733 ASSERT_TRUE(CreatePeerConnectionWrappers());
2734 ConnectFakeSignaling();
2735
Mirko Bonadei317a1f02019-09-17 17:06:18 +02002736 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002737 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
2738 ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true));
Elad Alon99c3fe52017-10-13 16:29:40 +02002739 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01002740 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
2741 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02002742
Steve Anton15324772018-01-16 10:26:49 -08002743 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02002744 caller()->CreateAndSetAndSignalOffer();
2745 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2746}
2747
Steve Antonede9ca52017-10-16 13:04:27 -07002748// Test that if candidates are only signaled by applying full session
2749// descriptions (instead of using AddIceCandidate), the peers can connect to
2750// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002751TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07002752 ASSERT_TRUE(CreatePeerConnectionWrappers());
2753 // Each side will signal the session descriptions but not candidates.
2754 ConnectFakeSignalingForSdpOnly();
2755
2756 // Add audio video track and exchange the initial offer/answer with media
2757 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08002758 caller()->AddAudioVideoTracks();
2759 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002760 caller()->CreateAndSetAndSignalOffer();
2761
2762 // Wait for all candidates to be gathered on both the caller and callee.
2763 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2764 caller()->ice_gathering_state(), kDefaultTimeout);
2765 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2766 callee()->ice_gathering_state(), kDefaultTimeout);
2767
2768 // The candidates will now be included in the session description, so
2769 // signaling them will start the ICE connection.
2770 caller()->CreateAndSetAndSignalOffer();
2771 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2772
2773 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002774 MediaExpectations media_expectations;
2775 media_expectations.ExpectBidirectionalAudioAndVideo();
2776 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07002777}
2778
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002779#if !defined(THREAD_SANITIZER)
2780// These tests provokes TSAN errors. See bugs.webrtc.org/11305.
2781
henrika5f6bf242017-11-01 11:06:56 +01002782// Test that SetAudioPlayout can be used to disable audio playout from the
2783// start, then later enable it. This may be useful, for example, if the caller
2784// needs to play a local ringtone until some event occurs, after which it
2785// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002786TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01002787 ASSERT_TRUE(CreatePeerConnectionWrappers());
2788 ConnectFakeSignaling();
2789
2790 // Set up audio-only call where audio playout is disabled on caller's side.
2791 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08002792 caller()->AddAudioTrack();
2793 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01002794 caller()->CreateAndSetAndSignalOffer();
2795 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2796
2797 // Pump messages for a second.
2798 WAIT(false, 1000);
2799 // Since audio playout is disabled, the caller shouldn't have received
2800 // anything (at the playout level, at least).
2801 EXPECT_EQ(0, caller()->audio_frames_received());
2802 // As a sanity check, make sure the callee (for which playout isn't disabled)
2803 // did still see frames on its audio level.
2804 ASSERT_GT(callee()->audio_frames_received(), 0);
2805
2806 // Enable playout again, and ensure audio starts flowing.
2807 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002808 MediaExpectations media_expectations;
2809 media_expectations.ExpectBidirectionalAudio();
2810 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01002811}
2812
Harald Alvestrand39993842021-02-17 09:05:31 +00002813double GetAudioEnergyStat(PeerConnectionIntegrationWrapper* pc) {
henrika5f6bf242017-11-01 11:06:56 +01002814 auto report = pc->NewGetStats();
2815 auto track_stats_list =
2816 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2817 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
2818 for (const auto* track_stats : track_stats_list) {
2819 if (track_stats->remote_source.is_defined() &&
2820 *track_stats->remote_source) {
2821 remote_track_stats = track_stats;
2822 break;
2823 }
2824 }
2825
2826 if (!remote_track_stats->total_audio_energy.is_defined()) {
2827 return 0.0;
2828 }
2829 return *remote_track_stats->total_audio_energy;
2830}
2831
2832// Test that if audio playout is disabled via the SetAudioPlayout() method, then
2833// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002834TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01002835 DisableAudioPlayoutStillGeneratesAudioStats) {
2836 ASSERT_TRUE(CreatePeerConnectionWrappers());
2837 ConnectFakeSignaling();
2838
2839 // Set up audio-only call where playout is disabled but audio-processing is
2840 // still active.
Steve Anton15324772018-01-16 10:26:49 -08002841 caller()->AddAudioTrack();
2842 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01002843 caller()->pc()->SetAudioPlayout(false);
2844
2845 caller()->CreateAndSetAndSignalOffer();
2846 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2847
2848 // Wait for the callee to receive audio stats.
2849 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
2850}
2851
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002852#endif // !defined(THREAD_SANITIZER)
2853
henrika4f167df2017-11-01 14:45:55 +01002854// Test that SetAudioRecording can be used to disable audio recording from the
2855// start, then later enable it. This may be useful, for example, if the caller
2856// wants to ensure that no audio resources are active before a certain state
2857// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002858TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01002859 ASSERT_TRUE(CreatePeerConnectionWrappers());
2860 ConnectFakeSignaling();
2861
2862 // Set up audio-only call where audio recording is disabled on caller's side.
2863 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08002864 caller()->AddAudioTrack();
2865 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01002866 caller()->CreateAndSetAndSignalOffer();
2867 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2868
2869 // Pump messages for a second.
2870 WAIT(false, 1000);
2871 // Since caller has disabled audio recording, the callee shouldn't have
2872 // received anything.
2873 EXPECT_EQ(0, callee()->audio_frames_received());
2874 // As a sanity check, make sure the caller did still see frames on its
2875 // audio level since audio recording is enabled on the calle side.
2876 ASSERT_GT(caller()->audio_frames_received(), 0);
2877
2878 // Enable audio recording again, and ensure audio starts flowing.
2879 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002880 MediaExpectations media_expectations;
2881 media_expectations.ExpectBidirectionalAudio();
2882 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01002883}
2884
Qingsi Wang7685e862018-06-11 20:15:46 -07002885TEST_P(PeerConnectionIntegrationTest,
2886 IceEventsGeneratedAndLoggedInRtcEventLog) {
2887 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
2888 ConnectFakeSignaling();
2889 PeerConnectionInterface::RTCOfferAnswerOptions options;
2890 options.offer_to_receive_audio = 1;
2891 caller()->SetOfferAnswerOptions(options);
2892 caller()->CreateAndSetAndSignalOffer();
2893 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2894 ASSERT_NE(nullptr, caller()->event_log_factory());
2895 ASSERT_NE(nullptr, callee()->event_log_factory());
2896 webrtc::FakeRtcEventLog* caller_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01002897 caller()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07002898 webrtc::FakeRtcEventLog* callee_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01002899 callee()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07002900 ASSERT_NE(nullptr, caller_event_log);
2901 ASSERT_NE(nullptr, callee_event_log);
2902 int caller_ice_config_count = caller_event_log->GetEventCount(
2903 webrtc::RtcEvent::Type::IceCandidatePairConfig);
2904 int caller_ice_event_count = caller_event_log->GetEventCount(
2905 webrtc::RtcEvent::Type::IceCandidatePairEvent);
2906 int callee_ice_config_count = callee_event_log->GetEventCount(
2907 webrtc::RtcEvent::Type::IceCandidatePairConfig);
2908 int callee_ice_event_count = callee_event_log->GetEventCount(
2909 webrtc::RtcEvent::Type::IceCandidatePairEvent);
2910 EXPECT_LT(0, caller_ice_config_count);
2911 EXPECT_LT(0, caller_ice_event_count);
2912 EXPECT_LT(0, callee_ice_config_count);
2913 EXPECT_LT(0, callee_ice_event_count);
2914}
2915
Qingsi Wangc129c352019-04-18 10:41:58 -07002916TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07002917 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2918 3478};
2919 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2920
2921 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
2922
2923 webrtc::PeerConnectionInterface::IceServer ice_server;
2924 ice_server.urls.push_back("turn:88.88.88.0:3478");
2925 ice_server.username = "test";
2926 ice_server.password = "test";
2927
2928 PeerConnectionInterface::RTCConfiguration caller_config;
2929 caller_config.servers.push_back(ice_server);
2930 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
2931 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07002932 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07002933
2934 PeerConnectionInterface::RTCConfiguration callee_config;
2935 callee_config.servers.push_back(ice_server);
2936 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
2937 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07002938 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07002939
2940 ASSERT_TRUE(
2941 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
2942
2943 // Do normal offer/answer and wait for ICE to complete.
2944 ConnectFakeSignaling();
2945 caller()->AddAudioVideoTracks();
2946 callee()->AddAudioVideoTracks();
2947 caller()->CreateAndSetAndSignalOffer();
2948 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2949 // Since we are doing continual gathering, the ICE transport does not reach
2950 // kIceGatheringComplete (see
2951 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
2952 // kIceConnectionComplete.
2953 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2954 caller()->ice_connection_state(), kDefaultTimeout);
2955 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2956 callee()->ice_connection_state(), kDefaultTimeout);
2957 // Note that we cannot use the metric
Artem Titovcfea2182021-08-10 01:22:31 +02002958 // `WebRTC.PeerConnection.CandidatePairType_UDP` in this test since this
Qingsi Wangc129c352019-04-18 10:41:58 -07002959 // metric is only populated when we reach kIceConnectionComplete in the
2960 // current implementation.
2961 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
2962 caller()->last_candidate_gathered().type());
2963 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
2964 callee()->last_candidate_gathered().type());
2965
2966 // Loosen the caller's candidate filter.
2967 caller_config = caller()->pc()->GetConfiguration();
2968 caller_config.type = webrtc::PeerConnectionInterface::kAll;
2969 caller()->pc()->SetConfiguration(caller_config);
2970 // We should have gathered a new host candidate.
2971 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
2972 caller()->last_candidate_gathered().type(), kDefaultTimeout);
2973
2974 // Loosen the callee's candidate filter.
2975 callee_config = callee()->pc()->GetConfiguration();
2976 callee_config.type = webrtc::PeerConnectionInterface::kAll;
2977 callee()->pc()->SetConfiguration(callee_config);
2978 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
2979 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02002980
2981 // Create an offer and verify that it does not contain an ICE restart (i.e new
2982 // ice credentials).
2983 std::string caller_ufrag_pre_offer = caller()
2984 ->pc()
2985 ->local_description()
2986 ->description()
2987 ->transport_infos()[0]
2988 .description.ice_ufrag;
2989 caller()->CreateAndSetAndSignalOffer();
2990 std::string caller_ufrag_post_offer = caller()
2991 ->pc()
2992 ->local_description()
2993 ->description()
2994 ->transport_infos()[0]
2995 .description.ice_ufrag;
2996 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07002997}
2998
Eldar Relloda13ea22019-06-01 12:23:43 +03002999TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03003000 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3001 3478};
3002 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3003
3004 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3005
3006 webrtc::PeerConnectionInterface::IceServer ice_server;
3007 ice_server.urls.push_back("turn:88.88.88.0:3478");
3008 ice_server.username = "test";
3009 ice_server.password = "123";
3010
3011 PeerConnectionInterface::RTCConfiguration caller_config;
3012 caller_config.servers.push_back(ice_server);
3013 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3014 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3015
3016 PeerConnectionInterface::RTCConfiguration callee_config;
3017 callee_config.servers.push_back(ice_server);
3018 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3019 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3020
3021 ASSERT_TRUE(
3022 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3023
3024 // Do normal offer/answer and wait for ICE to complete.
3025 ConnectFakeSignaling();
3026 caller()->AddAudioVideoTracks();
3027 callee()->AddAudioVideoTracks();
3028 caller()->CreateAndSetAndSignalOffer();
3029 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3030 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
3031 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
3032 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02003033 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03003034}
3035
Eldar Rellofa8019c2020-05-14 11:59:33 +03003036TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
3037 webrtc::PeerConnectionInterface::IceServer ice_server;
3038 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
3039 ice_server.username = "test";
3040 ice_server.password = "test";
3041
3042 PeerConnectionInterface::RTCConfiguration caller_config;
3043 caller_config.servers.push_back(ice_server);
3044 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3045 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3046
3047 PeerConnectionInterface::RTCConfiguration callee_config;
3048 callee_config.servers.push_back(ice_server);
3049 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3050 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3051
3052 ASSERT_TRUE(
3053 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3054
3055 // Do normal offer/answer and wait for ICE to complete.
3056 ConnectFakeSignaling();
3057 caller()->AddAudioVideoTracks();
3058 callee()->AddAudioVideoTracks();
3059 caller()->CreateAndSetAndSignalOffer();
3060 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3061 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
3062 EXPECT_EQ(caller()->error_event().address, "");
3063}
3064
Eldar Rello5ab79e62019-10-09 18:29:44 +03003065TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3066 AudioKeepsFlowingAfterImplicitRollback) {
3067 PeerConnectionInterface::RTCConfiguration config;
3068 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3069 config.enable_implicit_rollback = true;
3070 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3071 ConnectFakeSignaling();
3072 caller()->AddAudioTrack();
3073 callee()->AddAudioTrack();
3074 caller()->CreateAndSetAndSignalOffer();
3075 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3076 MediaExpectations media_expectations;
3077 media_expectations.ExpectBidirectionalAudio();
3078 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3079 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
3080 caller()->AddVideoTrack();
3081 callee()->AddVideoTrack();
Tommi87f70902021-04-27 14:43:08 +02003082 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02003083 callee()->pc()->SetLocalDescription(observer.get(),
Eldar Rello5ab79e62019-10-09 18:29:44 +03003084 callee()->CreateOfferAndWait().release());
3085 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3086 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
3087 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3088 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3089}
3090
3091TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3092 ImplicitRollbackVisitsStableState) {
3093 RTCConfiguration config;
3094 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3095 config.enable_implicit_rollback = true;
3096
3097 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3098
Tommi87f70902021-04-27 14:43:08 +02003099 auto sld_observer =
3100 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02003101 callee()->pc()->SetLocalDescription(sld_observer.get(),
Eldar Rello5ab79e62019-10-09 18:29:44 +03003102 callee()->CreateOfferAndWait().release());
3103 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
3104 EXPECT_EQ(sld_observer->error(), "");
3105
Tommi87f70902021-04-27 14:43:08 +02003106 auto srd_observer =
3107 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003108 callee()->pc()->SetRemoteDescription(
Niels Möllerafb246b2022-04-20 14:26:50 +02003109 srd_observer.get(), caller()->CreateOfferAndWait().release());
Eldar Rello5ab79e62019-10-09 18:29:44 +03003110 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
3111 EXPECT_EQ(srd_observer->error(), "");
3112
3113 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
3114 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
3115 PeerConnectionInterface::kStable,
3116 PeerConnectionInterface::kHaveRemoteOffer));
3117}
3118
Eldar Rellobd9c33a2020-10-01 17:52:45 +03003119TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3120 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
3121 ASSERT_TRUE(CreatePeerConnectionWrappers());
3122 ConnectFakeSignaling();
3123 caller()->AddVideoTrack();
3124 callee()->AddVideoTrack();
3125 auto munger = [](cricket::SessionDescription* desc) {
3126 cricket::VideoContentDescription* video =
3127 GetFirstVideoContentDescription(desc);
3128 auto codecs = video->codecs();
3129 for (auto&& codec : codecs) {
3130 if (codec.name == "H264") {
3131 std::string value;
3132 // The parameter is not supposed to be present in SDP by default.
3133 EXPECT_FALSE(
3134 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3135 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
3136 std::string(""));
3137 }
3138 }
3139 video->set_codecs(codecs);
3140 };
3141 // Munge local offer for SLD.
3142 caller()->SetGeneratedSdpMunger(munger);
3143 // Munge remote answer for SRD.
3144 caller()->SetReceivedSdpMunger(munger);
3145 caller()->CreateAndSetAndSignalOffer();
3146 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3147 // Observe that after munging the parameter is present in generated SDP.
3148 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
3149 cricket::VideoContentDescription* video =
3150 GetFirstVideoContentDescription(desc);
3151 for (auto&& codec : video->codecs()) {
3152 if (codec.name == "H264") {
3153 std::string value;
3154 EXPECT_TRUE(
3155 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3156 }
3157 }
3158 });
3159 caller()->CreateOfferAndWait();
3160}
3161
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003162TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00003163 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003164 PeerConnectionInterface::RTCConfiguration config;
3165 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3166 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3167 ConnectFakeSignaling();
3168 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3169
3170 caller()->CreateAndSetAndSignalOffer();
3171 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3172 int current_size = caller()->pc()->GetTransceivers().size();
3173 // Add more tracks until we get close to having issues.
3174 // Issues have been seen at:
3175 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003176 // - 16 tracks on android_arm_dbg (flaky)
3177 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003178 // Double the number of tracks
3179 for (int i = 0; i < current_size; i++) {
3180 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3181 }
3182 current_size = caller()->pc()->GetTransceivers().size();
3183 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3184 auto start_time_ms = rtc::TimeMillis();
3185 caller()->CreateAndSetAndSignalOffer();
3186 // We want to stop when the time exceeds one second.
3187 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3188 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3189 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3190 ASSERT_GT(1000, elapsed_time_ms)
3191 << "Audio transceivers: Negotiation took too long after "
3192 << current_size << " tracks added";
3193 }
3194}
3195
3196TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3197 RenegotiateManyVideoTransceivers) {
3198 PeerConnectionInterface::RTCConfiguration config;
3199 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3200 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3201 ConnectFakeSignaling();
3202 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3203
3204 caller()->CreateAndSetAndSignalOffer();
3205 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3206 int current_size = caller()->pc()->GetTransceivers().size();
3207 // Add more tracks until we get close to having issues.
3208 // Issues have been seen at:
3209 // - 96 on a Linux workstation
3210 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
3211 // - 32 on android_arm64_rel and linux_dbg bots
Harald Alvestrand785e23b2021-03-15 21:26:27 +00003212 // - 16 on Android 64 (Nexus 5x)
3213 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003214 // Double the number of tracks
3215 for (int i = 0; i < current_size; i++) {
3216 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3217 }
3218 current_size = caller()->pc()->GetTransceivers().size();
3219 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3220 auto start_time_ms = rtc::TimeMillis();
3221 caller()->CreateAndSetAndSignalOffer();
3222 // We want to stop when the time exceeds one second.
3223 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3224 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3225 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3226 ASSERT_GT(1000, elapsed_time_ms)
3227 << "Video transceivers: Negotiation took too long after "
3228 << current_size << " tracks added";
3229 }
3230}
3231
Harald Alvestrand94324f22021-01-13 12:31:53 +00003232TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3233 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
3234 PeerConnectionInterface::RTCConfiguration config;
3235 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3236 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3237 ConnectFakeSignaling();
3238 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003239 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003240 caller()->CreateAndSetAndSignalOffer();
3241 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3242 // Wait until we can see the audio flowing.
3243 MediaExpectations media_expectations;
3244 media_expectations.CalleeExpectsSomeAudio();
3245 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3246
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003247 // Get the baseline numbers for audio_packets and audio_delay
3248 // in both directions.
3249 caller()->StartWatchingDelayStats();
3250 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003251
3252 int current_size = caller()->pc()->GetTransceivers().size();
3253 // Add more tracks until we get close to having issues.
3254 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003255 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00003256 // Double the number of tracks
3257 for (int i = 0; i < current_size; i++) {
3258 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3259 }
3260 current_size = caller()->pc()->GetTransceivers().size();
3261 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3262 auto start_time_ms = rtc::TimeMillis();
3263 caller()->CreateAndSetAndSignalOffer();
3264 // We want to stop when the time exceeds one second.
3265 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3266 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3267 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3268 // This is a guard against the test using excessive amounts of time.
3269 ASSERT_GT(5000, elapsed_time_ms)
3270 << "Video transceivers: Negotiation took too long after "
3271 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003272 caller()->UpdateDelayStats("caller reception", current_size);
3273 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00003274 }
3275}
3276
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003277INSTANTIATE_TEST_SUITE_P(
3278 PeerConnectionIntegrationTest,
3279 PeerConnectionIntegrationTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02003280 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003281 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3282 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3283 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Steve Antond3679212018-01-17 17:41:02 -08003284
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003285INSTANTIATE_TEST_SUITE_P(
3286 PeerConnectionIntegrationTest,
3287 PeerConnectionIntegrationTestWithFakeClock,
Florent Castelli15a38de2022-04-06 00:38:21 +02003288 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003289 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3290 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3291 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Yves Gerey100fe632020-01-17 19:15:53 +01003292
Steve Anton74255ff2018-01-24 18:32:57 -08003293// Tests that verify interoperability between Plan B and Unified Plan
3294// PeerConnections.
3295class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003296 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08003297 public ::testing::WithParamInterface<
3298 std::tuple<SdpSemantics, SdpSemantics>> {
3299 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003300 // Setting the SdpSemantics for the base test to kDefault does not matter
3301 // because we specify not to use the test semantics when creating
Harald Alvestrand39993842021-02-17 09:05:31 +00003302 // PeerConnectionIntegrationWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08003303 PeerConnectionIntegrationInteropTest()
Florent Castelli15a38de2022-04-06 00:38:21 +02003304 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB_DEPRECATED),
Seth Hampson2f0d7022018-02-20 11:54:42 -08003305 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08003306 callee_semantics_(std::get<1>(GetParam())) {}
3307
3308 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07003309 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
3310 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08003311 }
3312
3313 const SdpSemantics caller_semantics_;
3314 const SdpSemantics callee_semantics_;
3315};
3316
3317TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
3318 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3319 ConnectFakeSignaling();
3320
3321 caller()->CreateAndSetAndSignalOffer();
3322 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3323}
3324
3325TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
3326 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3327 ConnectFakeSignaling();
3328 auto audio_sender = caller()->AddAudioTrack();
3329
3330 caller()->CreateAndSetAndSignalOffer();
3331 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3332
3333 // Verify that one audio receiver has been created on the remote and that it
3334 // has the same track ID as the sending track.
3335 auto receivers = callee()->pc()->GetReceivers();
3336 ASSERT_EQ(1u, receivers.size());
3337 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
3338 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
3339
Seth Hampson2f0d7022018-02-20 11:54:42 -08003340 MediaExpectations media_expectations;
3341 media_expectations.CalleeExpectsSomeAudio();
3342 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003343}
3344
3345TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
3346 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3347 ConnectFakeSignaling();
3348 auto video_sender = caller()->AddVideoTrack();
3349 auto audio_sender = caller()->AddAudioTrack();
3350
3351 caller()->CreateAndSetAndSignalOffer();
3352 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3353
3354 // Verify that one audio and one video receiver have been created on the
3355 // remote and that they have the same track IDs as the sending tracks.
3356 auto audio_receivers =
3357 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
3358 ASSERT_EQ(1u, audio_receivers.size());
3359 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
3360 auto video_receivers =
3361 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
3362 ASSERT_EQ(1u, video_receivers.size());
3363 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
3364
Seth Hampson2f0d7022018-02-20 11:54:42 -08003365 MediaExpectations media_expectations;
3366 media_expectations.CalleeExpectsSomeAudioAndVideo();
3367 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003368}
3369
3370TEST_P(PeerConnectionIntegrationInteropTest,
3371 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
3372 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3373 ConnectFakeSignaling();
3374 caller()->AddAudioVideoTracks();
3375 callee()->AddAudioVideoTracks();
3376
3377 caller()->CreateAndSetAndSignalOffer();
3378 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3379
Seth Hampson2f0d7022018-02-20 11:54:42 -08003380 MediaExpectations media_expectations;
3381 media_expectations.ExpectBidirectionalAudioAndVideo();
3382 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003383}
3384
3385TEST_P(PeerConnectionIntegrationInteropTest,
3386 ReverseRolesOneAudioLocalToOneVideoRemote) {
3387 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3388 ConnectFakeSignaling();
3389 caller()->AddAudioTrack();
3390 callee()->AddVideoTrack();
3391
3392 caller()->CreateAndSetAndSignalOffer();
3393 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3394
3395 // Verify that only the audio track has been negotiated.
3396 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
3397 // Might also check that the callee's NegotiationNeeded flag is set.
3398
3399 // Reverse roles.
3400 callee()->CreateAndSetAndSignalOffer();
3401 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3402
Seth Hampson2f0d7022018-02-20 11:54:42 -08003403 MediaExpectations media_expectations;
3404 media_expectations.CallerExpectsSomeVideo();
3405 media_expectations.CalleeExpectsSomeAudio();
3406 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003407}
3408
Taylor Brandstetter1c7ecef2021-08-11 12:38:35 -07003409TEST_P(PeerConnectionIntegrationTest, NewTracksDoNotCauseNewCandidates) {
3410 ASSERT_TRUE(CreatePeerConnectionWrappers());
3411 ConnectFakeSignaling();
3412 caller()->AddAudioVideoTracks();
3413 caller()->CreateAndSetAndSignalOffer();
3414 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3415 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3416 caller()->ExpectCandidates(0);
3417 callee()->ExpectCandidates(0);
3418 caller()->AddAudioTrack();
3419 caller()->CreateAndSetAndSignalOffer();
3420 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3421}
3422
Harald Alvestrand35ba0c52022-05-05 07:37:41 +00003423TEST_P(PeerConnectionIntegrationTest, MediaCallWithoutMediaEngineFails) {
3424 ASSERT_TRUE(CreatePeerConnectionWrappersWithoutMediaEngine());
3425 // AddTrack should fail.
3426 EXPECT_FALSE(
3427 caller()->pc()->AddTrack(caller()->CreateLocalAudioTrack(), {}).ok());
3428}
3429
Mirko Bonadeic84f6612019-01-31 12:20:57 +01003430INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07003431 PeerConnectionIntegrationTest,
3432 PeerConnectionIntegrationInteropTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02003433 Values(std::make_tuple(SdpSemantics::kPlanB_DEPRECATED,
3434 SdpSemantics::kUnifiedPlan),
3435 std::make_tuple(SdpSemantics::kUnifiedPlan,
3436 SdpSemantics::kPlanB_DEPRECATED)));
Steve Antonba42e992018-04-09 14:10:01 -07003437
3438// Test that if the Unified Plan side offers two video tracks then the Plan B
3439// side will only see the first one and ignore the second.
3440TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07003441 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
Florent Castelli15a38de2022-04-06 00:38:21 +02003442 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB_DEPRECATED));
Steve Anton74255ff2018-01-24 18:32:57 -08003443 ConnectFakeSignaling();
3444 auto first_sender = caller()->AddVideoTrack();
3445 caller()->AddVideoTrack();
3446
3447 caller()->CreateAndSetAndSignalOffer();
3448 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3449
3450 // Verify that there is only one receiver and it corresponds to the first
3451 // added track.
3452 auto receivers = callee()->pc()->GetReceivers();
3453 ASSERT_EQ(1u, receivers.size());
3454 EXPECT_TRUE(receivers[0]->track()->enabled());
3455 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
3456
Seth Hampson2f0d7022018-02-20 11:54:42 -08003457 MediaExpectations media_expectations;
3458 media_expectations.CalleeExpectsSomeVideo();
3459 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003460}
3461
Steve Anton2bed3972019-01-04 17:04:30 -08003462// Test that if the initial offer tagged BUNDLE section is rejected due to its
3463// associated RtpTransceiver being stopped and another transceiver is added,
3464// then renegotiation causes the callee to receive the new video track without
3465// error.
3466// This is a regression test for bugs.webrtc.org/9954
3467TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3468 ReOfferWithStoppedBundleTaggedTransceiver) {
3469 RTCConfiguration config;
3470 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3471 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3472 ConnectFakeSignaling();
3473 auto audio_transceiver_or_error =
3474 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3475 ASSERT_TRUE(audio_transceiver_or_error.ok());
3476 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3477
3478 caller()->CreateAndSetAndSignalOffer();
3479 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3480 {
3481 MediaExpectations media_expectations;
3482 media_expectations.CalleeExpectsSomeAudio();
3483 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3484 }
3485
Harald Alvestrand6060df52020-08-11 09:54:02 +02003486 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08003487 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3488
3489 caller()->CreateAndSetAndSignalOffer();
3490 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3491 {
3492 MediaExpectations media_expectations;
3493 media_expectations.CalleeExpectsSomeVideo();
3494 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3495 }
3496}
3497
Harald Alvestrandbedb6052020-08-20 14:50:10 +02003498TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3499 StopTransceiverRemovesDtlsTransports) {
3500 RTCConfiguration config;
3501 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3502 ConnectFakeSignaling();
3503 auto audio_transceiver_or_error =
3504 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3505 ASSERT_TRUE(audio_transceiver_or_error.ok());
3506 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3507
3508 caller()->CreateAndSetAndSignalOffer();
3509 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3510
3511 audio_transceiver->StopStandard();
3512 caller()->CreateAndSetAndSignalOffer();
3513 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3514 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
3515 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
3516 caller()->pc()->ice_gathering_state());
3517 EXPECT_THAT(caller()->ice_gathering_state_history(),
3518 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3519 PeerConnectionInterface::kIceGatheringComplete,
3520 PeerConnectionInterface::kIceGatheringNew));
3521}
3522
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003523TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00003524 StopTransceiverStopsAndRemovesTransceivers) {
3525 RTCConfiguration config;
3526 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3527 ConnectFakeSignaling();
3528 auto audio_transceiver_or_error =
3529 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3530 ASSERT_TRUE(audio_transceiver_or_error.ok());
3531 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
3532
3533 caller()->CreateAndSetAndSignalOffer();
3534 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3535 caller_transceiver->StopStandard();
3536
3537 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
3538 caller()->CreateAndSetAndSignalOffer();
3539 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3540 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
3541 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
3542 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
3543 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
3544 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
3545 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
3546 EXPECT_TRUE(caller_transceiver->stopped());
3547 EXPECT_TRUE(callee_transceiver->stopped());
3548}
3549
3550TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003551 StopTransceiverEndsIncomingAudioTrack) {
3552 RTCConfiguration config;
3553 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3554 ConnectFakeSignaling();
3555 auto audio_transceiver_or_error =
3556 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3557 ASSERT_TRUE(audio_transceiver_or_error.ok());
3558 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3559
3560 caller()->CreateAndSetAndSignalOffer();
3561 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3562 auto caller_track = audio_transceiver->receiver()->track();
3563 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3564 audio_transceiver->StopStandard();
3565 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3566 caller_track->state());
3567 caller()->CreateAndSetAndSignalOffer();
3568 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3569 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3570 callee_track->state());
3571}
3572
3573TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3574 StopTransceiverEndsIncomingVideoTrack) {
3575 RTCConfiguration config;
3576 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3577 ConnectFakeSignaling();
3578 auto audio_transceiver_or_error =
3579 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3580 ASSERT_TRUE(audio_transceiver_or_error.ok());
3581 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3582
3583 caller()->CreateAndSetAndSignalOffer();
3584 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3585 auto caller_track = audio_transceiver->receiver()->track();
3586 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3587 audio_transceiver->StopStandard();
3588 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3589 caller_track->state());
3590 caller()->CreateAndSetAndSignalOffer();
3591 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3592 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3593 callee_track->state());
3594}
3595
Harald Alvestrand89c40e22021-02-17 08:58:35 +00003596} // namespace
Harald Alvestrand39993842021-02-17 09:05:31 +00003597
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01003598} // namespace webrtc