blob: 940d7fdc74e31628b78a01b0691a23be1b179ab3 [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
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001790#if !defined(THREAD_SANITIZER)
1791// This test provokes TSAN errors. See bugs.webrtc.org/3608
1792
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001793constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
1794 cricket::PORTALLOCATOR_DISABLE_RELAY |
1795 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001796
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001797// Use a mock resolver to resolve the hostname back to the original IP on both
1798// sides and check that the ICE connection connects.
Markus Handell56910532021-04-10 11:23:14 +00001799// TODO(bugs.webrtc.org/12590): Flaky on Windows and on Linux MSAN.
1800#if defined(WEBRTC_WIN) || defined(WEBRTC_LINUX)
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001801#define MAYBE_IceStatesReachCompletionWithRemoteHostname \
1802 DISABLED_IceStatesReachCompletionWithRemoteHostname
1803#else
1804#define MAYBE_IceStatesReachCompletionWithRemoteHostname \
1805 IceStatesReachCompletionWithRemoteHostname
1806#endif
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001807TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001808 MAYBE_IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001809 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001810 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001811 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001812 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001813 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
1814 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001815
1816 // This also verifies that the injected AsyncResolverFactory is used by
1817 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001818 EXPECT_CALL(*caller_resolver_factory, Create())
1819 .WillOnce(Return(&caller_async_resolver));
1820 webrtc::PeerConnectionDependencies caller_deps(nullptr);
1821 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
1822
1823 EXPECT_CALL(*callee_resolver_factory, Create())
1824 .WillOnce(Return(&callee_async_resolver));
1825 webrtc::PeerConnectionDependencies callee_deps(nullptr);
1826 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
1827
1828 PeerConnectionInterface::RTCConfiguration config;
1829 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
1830 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
1831
1832 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
1833 config, std::move(caller_deps), config, std::move(callee_deps)));
1834
1835 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
1836 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
1837
1838 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07001839 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001840 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07001841 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001842 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001843
1844 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001845
1846 ConnectFakeSignaling();
1847 caller()->AddAudioVideoTracks();
1848 callee()->AddAudioVideoTracks();
1849 caller()->CreateAndSetAndSignalOffer();
1850 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1851 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1852 caller()->ice_connection_state(), kDefaultTimeout);
1853 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1854 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08001855
Ying Wangef3998f2019-12-09 13:06:53 +01001856 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1857 "WebRTC.PeerConnection.CandidatePairType_UDP",
1858 webrtc::kIceCandidatePairHostNameHostName));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001859}
1860
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001861#endif // !defined(THREAD_SANITIZER)
1862
Steve Antonede9ca52017-10-16 13:04:27 -07001863// Test that firewalling the ICE connection causes the clients to identify the
1864// disconnected state and then removing the firewall causes them to reconnect.
1865class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08001866 : public PeerConnectionIntegrationBaseTest,
1867 public ::testing::WithParamInterface<
1868 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07001869 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001870 PeerConnectionIntegrationIceStatesTest()
1871 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
1872 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07001873 }
1874
1875 void StartStunServer(const SocketAddress& server_address) {
1876 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01001877 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07001878 }
1879
1880 bool TestIPv6() {
1881 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
1882 }
1883
1884 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001885 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
1886 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07001887 }
1888
1889 std::vector<SocketAddress> CallerAddresses() {
1890 std::vector<SocketAddress> addresses;
1891 addresses.push_back(SocketAddress("1.1.1.1", 0));
1892 if (TestIPv6()) {
1893 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
1894 }
1895 return addresses;
1896 }
1897
1898 std::vector<SocketAddress> CalleeAddresses() {
1899 std::vector<SocketAddress> addresses;
1900 addresses.push_back(SocketAddress("2.2.2.2", 0));
1901 if (TestIPv6()) {
1902 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
1903 }
1904 return addresses;
1905 }
1906
1907 void SetUpNetworkInterfaces() {
1908 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07001909 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
1910 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07001911
1912 // Add network addresses for test.
1913 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001914 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001915 }
1916 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001917 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001918 }
1919 }
1920
1921 private:
1922 uint32_t port_allocator_flags_;
1923 std::unique_ptr<cricket::TestStunServer> stun_server_;
1924};
1925
Yves Gerey100fe632020-01-17 19:15:53 +01001926// Ensure FakeClockForTest is constructed first (see class for rationale).
1927class PeerConnectionIntegrationIceStatesTestWithFakeClock
1928 : public FakeClockForTest,
1929 public PeerConnectionIntegrationIceStatesTest {};
1930
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001931#if !defined(THREAD_SANITIZER)
1932// This test provokes TSAN errors. bugs.webrtc.org/11282
1933
Jonas Olssonb75d9e92019-02-22 10:33:29 +01001934// Tests that if the connection doesn't get set up properly we eventually reach
1935// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01001936TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
1937 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01001938 // Block connections to/from the caller and wait for ICE to become
1939 // disconnected.
1940 for (const auto& caller_address : CallerAddresses()) {
1941 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
1942 }
1943
1944 ASSERT_TRUE(CreatePeerConnectionWrappers());
1945 ConnectFakeSignaling();
1946 SetPortAllocatorFlags();
1947 SetUpNetworkInterfaces();
1948 caller()->AddAudioVideoTracks();
1949 caller()->CreateAndSetAndSignalOffer();
1950
1951 // According to RFC7675, if there is no response within 30 seconds then the
1952 // peer should consider the other side to have rejected the connection. This
1953 // is signaled by the state transitioning to "failed".
1954 constexpr int kConsentTimeout = 30000;
1955 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
1956 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01001957 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07001958}
1959
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001960#endif // !defined(THREAD_SANITIZER)
1961
Steve Antonede9ca52017-10-16 13:04:27 -07001962// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
1963// and that the statistics in the metric observers are updated correctly.
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001964// TODO(bugs.webrtc.org/12591): Flaky on Windows.
1965#if defined(WEBRTC_WIN)
1966#define MAYBE_VerifyBestConnection DISABLED_VerifyBestConnection
1967#else
1968#define MAYBE_VerifyBestConnection VerifyBestConnection
1969#endif
1970TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
Steve Antonede9ca52017-10-16 13:04:27 -07001971 ASSERT_TRUE(CreatePeerConnectionWrappers());
1972 ConnectFakeSignaling();
1973 SetPortAllocatorFlags();
1974 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08001975 caller()->AddAudioVideoTracks();
1976 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07001977 caller()->CreateAndSetAndSignalOffer();
1978
1979 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08001980 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1981 caller()->ice_connection_state(), kDefaultTimeout);
1982 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1983 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07001984
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001985 // TODO(bugs.webrtc.org/9456): Fix it.
1986 const int num_best_ipv4 = webrtc::metrics::NumEvents(
1987 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
1988 const int num_best_ipv6 = webrtc::metrics::NumEvents(
1989 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001990 if (TestIPv6()) {
1991 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
1992 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01001993 EXPECT_METRIC_EQ(0, num_best_ipv4);
1994 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001995 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01001996 EXPECT_METRIC_EQ(1, num_best_ipv4);
1997 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001998 }
1999
Ying Wangef3998f2019-12-09 13:06:53 +01002000 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
2001 "WebRTC.PeerConnection.CandidatePairType_UDP",
2002 webrtc::kIceCandidatePairHostHost));
2003 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
2004 "WebRTC.PeerConnection.CandidatePairType_UDP",
2005 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07002006}
2007
2008constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
2009 cricket::PORTALLOCATOR_DISABLE_STUN |
2010 cricket::PORTALLOCATOR_DISABLE_RELAY;
2011constexpr uint32_t kFlagsIPv6NoStun =
2012 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
2013 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
2014constexpr uint32_t kFlagsIPv4Stun =
2015 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
2016
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002017INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002018 PeerConnectionIntegrationTest,
2019 PeerConnectionIntegrationIceStatesTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02002020 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Seth Hampson2f0d7022018-02-20 11:54:42 -08002021 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2022 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2023 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07002024
Yves Gerey100fe632020-01-17 19:15:53 +01002025INSTANTIATE_TEST_SUITE_P(
2026 PeerConnectionIntegrationTest,
2027 PeerConnectionIntegrationIceStatesTestWithFakeClock,
Florent Castelli15a38de2022-04-06 00:38:21 +02002028 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Yves Gerey100fe632020-01-17 19:15:53 +01002029 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2030 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2031 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
2032
deadbeef1dcb1642017-03-29 21:08:16 -07002033// This test sets up a call between two parties with audio and video.
2034// During the call, the caller restarts ICE and the test verifies that
2035// new ICE candidates are generated and audio and video still can flow, and the
2036// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002037TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07002038 ASSERT_TRUE(CreatePeerConnectionWrappers());
2039 ConnectFakeSignaling();
2040 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08002041 caller()->AddAudioVideoTracks();
2042 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002043 caller()->CreateAndSetAndSignalOffer();
2044 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2045 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2046 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002047 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2048 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07002049
2050 // To verify that the ICE restart actually occurs, get
2051 // ufrag/password/candidates before and after restart.
2052 // Create an SDP string of the first audio candidate for both clients.
2053 const webrtc::IceCandidateCollection* audio_candidates_caller =
2054 caller()->pc()->local_description()->candidates(0);
2055 const webrtc::IceCandidateCollection* audio_candidates_callee =
2056 callee()->pc()->local_description()->candidates(0);
2057 ASSERT_GT(audio_candidates_caller->count(), 0u);
2058 ASSERT_GT(audio_candidates_callee->count(), 0u);
2059 std::string caller_candidate_pre_restart;
2060 ASSERT_TRUE(
2061 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
2062 std::string callee_candidate_pre_restart;
2063 ASSERT_TRUE(
2064 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
2065 const cricket::SessionDescription* desc =
2066 caller()->pc()->local_description()->description();
2067 std::string caller_ufrag_pre_restart =
2068 desc->transport_infos()[0].description.ice_ufrag;
2069 desc = callee()->pc()->local_description()->description();
2070 std::string callee_ufrag_pre_restart =
2071 desc->transport_infos()[0].description.ice_ufrag;
2072
Alex Drake00c7ecf2019-08-06 10:54:47 -07002073 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002074 // Have the caller initiate an ICE restart.
2075 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2076 caller()->CreateAndSetAndSignalOffer();
2077 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2078 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2079 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002080 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07002081 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2082
2083 // Grab the ufrags/candidates again.
2084 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
2085 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
2086 ASSERT_GT(audio_candidates_caller->count(), 0u);
2087 ASSERT_GT(audio_candidates_callee->count(), 0u);
2088 std::string caller_candidate_post_restart;
2089 ASSERT_TRUE(
2090 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
2091 std::string callee_candidate_post_restart;
2092 ASSERT_TRUE(
2093 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
2094 desc = caller()->pc()->local_description()->description();
2095 std::string caller_ufrag_post_restart =
2096 desc->transport_infos()[0].description.ice_ufrag;
2097 desc = callee()->pc()->local_description()->description();
2098 std::string callee_ufrag_post_restart =
2099 desc->transport_infos()[0].description.ice_ufrag;
2100 // Sanity check that an ICE restart was actually negotiated in SDP.
2101 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
2102 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
2103 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
2104 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07002105 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002106
2107 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002108 MediaExpectations media_expectations;
2109 media_expectations.ExpectBidirectionalAudioAndVideo();
2110 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002111}
2112
2113// Verify that audio/video can be received end-to-end when ICE renomination is
2114// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002115TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07002116 PeerConnectionInterface::RTCConfiguration config;
2117 config.enable_ice_renomination = true;
2118 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2119 ConnectFakeSignaling();
2120 // Do normal offer/answer and wait for some frames to be received in each
2121 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002122 caller()->AddAudioVideoTracks();
2123 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002124 caller()->CreateAndSetAndSignalOffer();
2125 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2126 // Sanity check that ICE renomination was actually negotiated.
2127 const cricket::SessionDescription* desc =
2128 caller()->pc()->local_description()->description();
2129 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002130 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002131 }
2132 desc = callee()->pc()->local_description()->description();
2133 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002134 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002135 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08002136 MediaExpectations media_expectations;
2137 media_expectations.ExpectBidirectionalAudioAndVideo();
2138 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002139}
2140
Steve Anton6f25b092017-10-23 09:39:20 -07002141// With a max bundle policy and RTCP muxing, adding a new media description to
2142// the connection should not affect ICE at all because the new media will use
2143// the existing connection.
Rasmus Brandt685be142021-03-15 14:03:38 +01002144// TODO(bugs.webrtc.org/12538): Fails on tsan.
2145#if defined(THREAD_SANITIZER)
2146#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2147 DISABLED_AddMediaToConnectedBundleDoesNotRestartIce
2148#else
2149#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2150 AddMediaToConnectedBundleDoesNotRestartIce
2151#endif
Seth Hampson2f0d7022018-02-20 11:54:42 -08002152TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt685be142021-03-15 14:03:38 +01002153 MAYBE_AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07002154 PeerConnectionInterface::RTCConfiguration config;
2155 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
2156 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
2157 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
2158 config, PeerConnectionInterface::RTCConfiguration()));
2159 ConnectFakeSignaling();
2160
Steve Anton15324772018-01-16 10:26:49 -08002161 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002162 caller()->CreateAndSetAndSignalOffer();
2163 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07002164 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2165 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07002166
2167 caller()->clear_ice_connection_state_history();
2168
Steve Anton15324772018-01-16 10:26:49 -08002169 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002170 caller()->CreateAndSetAndSignalOffer();
2171 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2172
2173 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
2174}
2175
deadbeef1dcb1642017-03-29 21:08:16 -07002176// This test sets up a call between two parties with audio and video. It then
2177// renegotiates setting the video m-line to "port 0", then later renegotiates
2178// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002179TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002180 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
2181 ASSERT_TRUE(CreatePeerConnectionWrappers());
2182 ConnectFakeSignaling();
2183
2184 // Do initial negotiation, only sending media from the caller. Will result in
2185 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08002186 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002187 caller()->CreateAndSetAndSignalOffer();
2188 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2189
2190 // Negotiate again, disabling the video "m=" section (the callee will set the
2191 // port to 0 due to offer_to_receive_video = 0).
Florent Castelli15a38de2022-04-06 00:38:21 +02002192 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002193 PeerConnectionInterface::RTCOfferAnswerOptions options;
2194 options.offer_to_receive_video = 0;
2195 callee()->SetOfferAnswerOptions(options);
2196 } else {
2197 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002198 callee()
2199 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2200 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002201 });
2202 }
deadbeef1dcb1642017-03-29 21:08:16 -07002203 caller()->CreateAndSetAndSignalOffer();
2204 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2205 // Sanity check that video "m=" section was actually rejected.
2206 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
2207 callee()->pc()->local_description()->description());
2208 ASSERT_NE(nullptr, answer_video_content);
2209 ASSERT_TRUE(answer_video_content->rejected);
2210
2211 // Enable video and do negotiation again, making sure video is received
2212 // end-to-end, also adding media stream to callee.
Florent Castelli15a38de2022-04-06 00:38:21 +02002213 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002214 PeerConnectionInterface::RTCOfferAnswerOptions options;
2215 options.offer_to_receive_video = 1;
2216 callee()->SetOfferAnswerOptions(options);
2217 } else {
2218 // The caller's transceiver is stopped, so we need to add another track.
2219 auto caller_transceiver =
2220 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002221 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002222 caller()->AddVideoTrack();
2223 }
2224 callee()->AddVideoTrack();
2225 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07002226 caller()->CreateAndSetAndSignalOffer();
2227 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002228
deadbeef1dcb1642017-03-29 21:08:16 -07002229 // Verify the caller receives frames from the newly added stream, and the
2230 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002231 MediaExpectations media_expectations;
2232 media_expectations.CalleeExpectsSomeAudio();
2233 media_expectations.ExpectBidirectionalVideo();
2234 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002235}
2236
deadbeef1dcb1642017-03-29 21:08:16 -07002237// This tests that if we negotiate after calling CreateSender but before we
2238// have a track, then set a track later, frames from the newly-set track are
2239// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002240TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07002241 MediaFlowsAfterEarlyWarmupWithCreateSender) {
2242 ASSERT_TRUE(CreatePeerConnectionWrappers());
2243 ConnectFakeSignaling();
2244 auto caller_audio_sender =
2245 caller()->pc()->CreateSender("audio", "caller_stream");
2246 auto caller_video_sender =
2247 caller()->pc()->CreateSender("video", "caller_stream");
2248 auto callee_audio_sender =
2249 callee()->pc()->CreateSender("audio", "callee_stream");
2250 auto callee_video_sender =
2251 callee()->pc()->CreateSender("video", "callee_stream");
2252 caller()->CreateAndSetAndSignalOffer();
2253 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2254 // Wait for ICE to complete, without any tracks being set.
2255 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2256 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2257 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2258 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2259 // Now set the tracks, and expect frames to immediately start flowing.
Niels Möllerafb246b2022-04-20 14:26:50 +02002260 EXPECT_TRUE(
2261 caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2262 EXPECT_TRUE(
2263 caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2264 EXPECT_TRUE(
2265 callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2266 EXPECT_TRUE(
2267 callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002268 MediaExpectations media_expectations;
2269 media_expectations.ExpectBidirectionalAudioAndVideo();
2270 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2271}
2272
2273// This tests that if we negotiate after calling AddTransceiver but before we
2274// have a track, then set a track later, frames from the newly-set tracks are
2275// received end-to-end.
2276TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2277 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
2278 ASSERT_TRUE(CreatePeerConnectionWrappers());
2279 ConnectFakeSignaling();
2280 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
2281 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
2282 auto caller_audio_sender = audio_result.MoveValue()->sender();
2283 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
2284 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
2285 auto caller_video_sender = video_result.MoveValue()->sender();
2286 callee()->SetRemoteOfferHandler([this] {
2287 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02002288 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002289 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002290 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002291 RtpTransceiverDirection::kSendRecv);
2292 });
2293 caller()->CreateAndSetAndSignalOffer();
2294 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2295 // Wait for ICE to complete, without any tracks being set.
2296 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2297 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2298 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2299 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2300 // Now set the tracks, and expect frames to immediately start flowing.
2301 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
2302 auto callee_video_sender = callee()->pc()->GetSenders()[1];
Niels Möllerafb246b2022-04-20 14:26:50 +02002303 ASSERT_TRUE(
2304 caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2305 ASSERT_TRUE(
2306 caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2307 ASSERT_TRUE(
2308 callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2309 ASSERT_TRUE(
2310 callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002311 MediaExpectations media_expectations;
2312 media_expectations.ExpectBidirectionalAudioAndVideo();
2313 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002314}
2315
2316// This test verifies that a remote video track can be added via AddStream,
2317// and sent end-to-end. For this particular test, it's simply echoed back
2318// from the caller to the callee, rather than being forwarded to a third
2319// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002320TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07002321 ASSERT_TRUE(CreatePeerConnectionWrappers());
2322 ConnectFakeSignaling();
2323 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08002324 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002325 caller()->CreateAndSetAndSignalOffer();
2326 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002327 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07002328
2329 // Echo the stream back, and do a new offer/anwer (initiated by callee this
2330 // time).
2331 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
2332 callee()->CreateAndSetAndSignalOffer();
2333 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2334
Seth Hampson2f0d7022018-02-20 11:54:42 -08002335 MediaExpectations media_expectations;
2336 media_expectations.ExpectBidirectionalVideo();
2337 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002338}
2339
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002340#if !defined(THREAD_SANITIZER)
2341// This test provokes TSAN errors. bugs.webrtc.org/11282
2342
deadbeef1dcb1642017-03-29 21:08:16 -07002343// Test that we achieve the expected end-to-end connection time, using a
2344// fake clock and simulated latency on the media and signaling paths.
2345// We use a TURN<->TURN connection because this is usually the quickest to
2346// set up initially, especially when we're confident the connection will work
2347// and can start sending media before we get a STUN response.
2348//
2349// With various optimizations enabled, here are the network delays we expect to
2350// be on the critical path:
2351// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
2352// signaling answer (with DTLS fingerprint).
2353// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
2354// using TURN<->TURN pair, and DTLS exchange is 4 packets,
2355// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01002356TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2357 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07002358 static constexpr int media_hop_delay_ms = 50;
2359 static constexpr int signaling_trip_delay_ms = 500;
2360 // For explanation of these values, see comment above.
2361 static constexpr int required_media_hops = 9;
2362 static constexpr int required_signaling_trips = 2;
2363 // For internal delays (such as posting an event asychronously).
2364 static constexpr int allowed_internal_delay_ms = 20;
2365 static constexpr int total_connection_time_ms =
2366 media_hop_delay_ms * required_media_hops +
2367 signaling_trip_delay_ms * required_signaling_trips +
2368 allowed_internal_delay_ms;
2369
2370 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2371 3478};
2372 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2373 0};
2374 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2375 3478};
2376 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2377 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002378 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
2379 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002380
Seth Hampsonaed71642018-06-11 07:41:32 -07002381 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
2382 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07002383 // Bypass permission check on received packets so media can be sent before
2384 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07002385 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
2386 turn_server_1->set_enable_permission_checks(false);
2387 });
2388 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
2389 turn_server_2->set_enable_permission_checks(false);
2390 });
deadbeef1dcb1642017-03-29 21:08:16 -07002391
2392 PeerConnectionInterface::RTCConfiguration client_1_config;
2393 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2394 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2395 ice_server_1.username = "test";
2396 ice_server_1.password = "test";
2397 client_1_config.servers.push_back(ice_server_1);
2398 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2399 client_1_config.presume_writable_when_fully_relayed = true;
2400
2401 PeerConnectionInterface::RTCConfiguration client_2_config;
2402 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2403 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2404 ice_server_2.username = "test";
2405 ice_server_2.password = "test";
2406 client_2_config.servers.push_back(ice_server_2);
2407 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2408 client_2_config.presume_writable_when_fully_relayed = true;
2409
2410 ASSERT_TRUE(
2411 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2412 // Set up the simulated delays.
2413 SetSignalingDelayMs(signaling_trip_delay_ms);
2414 ConnectFakeSignaling();
2415 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
2416 virtual_socket_server()->UpdateDelayDistribution();
2417
2418 // Set "offer to receive audio/video" without adding any tracks, so we just
2419 // set up ICE/DTLS with no media.
2420 PeerConnectionInterface::RTCOfferAnswerOptions options;
2421 options.offer_to_receive_audio = 1;
2422 options.offer_to_receive_video = 1;
2423 caller()->SetOfferAnswerOptions(options);
2424 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07002425 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01002426 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07002427 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
2428 // If this is not done a DCHECK can be hit in ports.cc, because a large
2429 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07002430 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07002431}
2432
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002433#endif // !defined(THREAD_SANITIZER)
2434
Jonas Orelandbdcee282017-10-10 14:01:40 +02002435// Verify that a TurnCustomizer passed in through RTCConfiguration
2436// is actually used by the underlying TURN candidate pair.
2437// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002438TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02002439 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2440 3478};
2441 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2442 0};
2443 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2444 3478};
2445 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2446 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002447 CreateTurnServer(turn_server_1_internal_address,
2448 turn_server_1_external_address);
2449 CreateTurnServer(turn_server_2_internal_address,
2450 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002451
2452 PeerConnectionInterface::RTCConfiguration client_1_config;
2453 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2454 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2455 ice_server_1.username = "test";
2456 ice_server_1.password = "test";
2457 client_1_config.servers.push_back(ice_server_1);
2458 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002459 auto* customizer1 = CreateTurnCustomizer();
2460 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002461
2462 PeerConnectionInterface::RTCConfiguration client_2_config;
2463 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2464 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2465 ice_server_2.username = "test";
2466 ice_server_2.password = "test";
2467 client_2_config.servers.push_back(ice_server_2);
2468 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002469 auto* customizer2 = CreateTurnCustomizer();
2470 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002471
2472 ASSERT_TRUE(
2473 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2474 ConnectFakeSignaling();
2475
2476 // Set "offer to receive audio/video" without adding any tracks, so we just
2477 // set up ICE/DTLS with no media.
2478 PeerConnectionInterface::RTCOfferAnswerOptions options;
2479 options.offer_to_receive_audio = 1;
2480 options.offer_to_receive_video = 1;
2481 caller()->SetOfferAnswerOptions(options);
2482 caller()->CreateAndSetAndSignalOffer();
2483 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2484
Seth Hampsonaed71642018-06-11 07:41:32 -07002485 ExpectTurnCustomizerCountersIncremented(customizer1);
2486 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002487}
2488
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002489// Verifies that you can use TCP instead of UDP to connect to a TURN server and
2490// send media between the caller and the callee.
2491TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
2492 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2493 3478};
2494 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2495
2496 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07002497 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2498 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002499
2500 webrtc::PeerConnectionInterface::IceServer ice_server;
2501 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
2502 ice_server.username = "test";
2503 ice_server.password = "test";
2504
2505 PeerConnectionInterface::RTCConfiguration client_1_config;
2506 client_1_config.servers.push_back(ice_server);
2507 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2508
2509 PeerConnectionInterface::RTCConfiguration client_2_config;
2510 client_2_config.servers.push_back(ice_server);
2511 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2512
2513 ASSERT_TRUE(
2514 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2515
2516 // Do normal offer/answer and wait for ICE to complete.
2517 ConnectFakeSignaling();
2518 caller()->AddAudioVideoTracks();
2519 callee()->AddAudioVideoTracks();
2520 caller()->CreateAndSetAndSignalOffer();
2521 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2522 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2523 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2524
2525 MediaExpectations media_expectations;
2526 media_expectations.ExpectBidirectionalAudioAndVideo();
2527 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2528}
2529
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002530// Verify that a SSLCertificateVerifier passed in through
2531// PeerConnectionDependencies is actually used by the underlying SSL
2532// implementation to determine whether a certificate presented by the TURN
2533// server is accepted by the client. Note that openssladapter_unittest.cc
2534// contains more detailed, lower-level tests.
2535TEST_P(PeerConnectionIntegrationTest,
2536 SSLCertificateVerifierUsedForTurnConnections) {
2537 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2538 3478};
2539 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2540
2541 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2542 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002543 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2544 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002545
2546 webrtc::PeerConnectionInterface::IceServer ice_server;
2547 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2548 ice_server.username = "test";
2549 ice_server.password = "test";
2550
2551 PeerConnectionInterface::RTCConfiguration client_1_config;
2552 client_1_config.servers.push_back(ice_server);
2553 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2554
2555 PeerConnectionInterface::RTCConfiguration client_2_config;
2556 client_2_config.servers.push_back(ice_server);
2557 // Setting the type to kRelay forces the connection to go through a TURN
2558 // server.
2559 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2560
2561 // Get a copy to the pointer so we can verify calls later.
2562 rtc::TestCertificateVerifier* client_1_cert_verifier =
2563 new rtc::TestCertificateVerifier();
2564 client_1_cert_verifier->verify_certificate_ = true;
2565 rtc::TestCertificateVerifier* client_2_cert_verifier =
2566 new rtc::TestCertificateVerifier();
2567 client_2_cert_verifier->verify_certificate_ = true;
2568
2569 // Create the dependencies with the test certificate verifier.
2570 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2571 client_1_deps.tls_cert_verifier =
2572 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2573 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2574 client_2_deps.tls_cert_verifier =
2575 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2576
2577 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2578 client_1_config, std::move(client_1_deps), client_2_config,
2579 std::move(client_2_deps)));
2580 ConnectFakeSignaling();
2581
2582 // Set "offer to receive audio/video" without adding any tracks, so we just
2583 // set up ICE/DTLS with no media.
2584 PeerConnectionInterface::RTCOfferAnswerOptions options;
2585 options.offer_to_receive_audio = 1;
2586 options.offer_to_receive_video = 1;
2587 caller()->SetOfferAnswerOptions(options);
2588 caller()->CreateAndSetAndSignalOffer();
2589 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2590
2591 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2592 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002593}
2594
Qingsi Wang25ec8882019-11-15 12:33:05 -08002595// Test that the injected ICE transport factory is used to create ICE transports
2596// for WebRTC connections.
2597TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
2598 PeerConnectionInterface::RTCConfiguration default_config;
2599 PeerConnectionDependencies dependencies(nullptr);
2600 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
2601 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
2602 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02002603 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
2604 std::move(dependencies), nullptr,
2605 /*reset_encoder_factory=*/false,
2606 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08002607 ASSERT_TRUE(wrapper);
2608 wrapper->CreateDataChannel();
Tommi87f70902021-04-27 14:43:08 +02002609 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02002610 wrapper->pc()->SetLocalDescription(observer.get(),
Qingsi Wang25ec8882019-11-15 12:33:05 -08002611 wrapper->CreateOfferAndWait().release());
2612}
2613
deadbeefc964d0b2017-04-03 10:03:35 -07002614// Test that audio and video flow end-to-end when codec names don't use the
2615// expected casing, given that they're supposed to be case insensitive. To test
2616// this, all but one codec is removed from each media description, and its
2617// casing is changed.
2618//
2619// In the past, this has regressed and caused crashes/black video, due to the
2620// fact that code at some layers was doing case-insensitive comparisons and
2621// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002622TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07002623 ASSERT_TRUE(CreatePeerConnectionWrappers());
2624 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002625 caller()->AddAudioVideoTracks();
2626 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07002627
2628 // Remove all but one audio/video codec (opus and VP8), and change the
2629 // casing of the caller's generated offer.
2630 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
2631 cricket::AudioContentDescription* audio =
2632 GetFirstAudioContentDescription(description);
2633 ASSERT_NE(nullptr, audio);
2634 auto audio_codecs = audio->codecs();
2635 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
2636 [](const cricket::AudioCodec& codec) {
2637 return codec.name != "opus";
2638 }),
2639 audio_codecs.end());
2640 ASSERT_EQ(1u, audio_codecs.size());
2641 audio_codecs[0].name = "OpUs";
2642 audio->set_codecs(audio_codecs);
2643
2644 cricket::VideoContentDescription* video =
2645 GetFirstVideoContentDescription(description);
2646 ASSERT_NE(nullptr, video);
2647 auto video_codecs = video->codecs();
2648 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
2649 [](const cricket::VideoCodec& codec) {
2650 return codec.name != "VP8";
2651 }),
2652 video_codecs.end());
2653 ASSERT_EQ(1u, video_codecs.size());
2654 video_codecs[0].name = "vP8";
2655 video->set_codecs(video_codecs);
2656 });
2657
2658 caller()->CreateAndSetAndSignalOffer();
2659 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2660
2661 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002662 MediaExpectations media_expectations;
2663 media_expectations.ExpectBidirectionalAudioAndVideo();
2664 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07002665}
2666
Jonas Oreland49ac5952018-09-26 16:04:32 +02002667TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07002668 ASSERT_TRUE(CreatePeerConnectionWrappers());
2669 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002670 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07002671 caller()->CreateAndSetAndSignalOffer();
2672 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07002673 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002674 MediaExpectations media_expectations;
2675 media_expectations.CalleeExpectsSomeAudio(1);
2676 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02002677 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07002678 auto receiver = callee()->pc()->GetReceivers()[0];
2679 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002680 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07002681 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
2682 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02002683 sources[0].source_id());
2684 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
2685}
2686
2687TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
2688 ASSERT_TRUE(CreatePeerConnectionWrappers());
2689 ConnectFakeSignaling();
2690 caller()->AddVideoTrack();
2691 caller()->CreateAndSetAndSignalOffer();
2692 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2693 // Wait for one video frame to be received by the callee.
2694 MediaExpectations media_expectations;
2695 media_expectations.CalleeExpectsSomeVideo(1);
2696 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2697 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2698 auto receiver = callee()->pc()->GetReceivers()[0];
2699 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
2700 auto sources = receiver->GetSources();
2701 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02002702 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002703 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
2704 sources[0].source_id());
2705 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07002706}
2707
deadbeef2f425aa2017-04-14 10:41:32 -07002708// Test that if a track is removed and added again with a different stream ID,
2709// the new stream ID is successfully communicated in SDP and media continues to
2710// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002711// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
2712// it will not reuse a transceiver that has already been sending. After creating
2713// a new transceiver it tries to create an offer with two senders of the same
2714// track ids and it fails.
2715TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07002716 ASSERT_TRUE(CreatePeerConnectionWrappers());
2717 ConnectFakeSignaling();
2718
deadbeef2f425aa2017-04-14 10:41:32 -07002719 // Add track using stream 1, do offer/answer.
2720 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2721 caller()->CreateLocalAudioTrack();
2722 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07002723 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07002724 caller()->CreateAndSetAndSignalOffer();
2725 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002726 {
2727 MediaExpectations media_expectations;
2728 media_expectations.CalleeExpectsSomeAudio(1);
2729 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2730 }
deadbeef2f425aa2017-04-14 10:41:32 -07002731 // Remove the sender, and create a new one with the new stream.
Harald Alvestrand93dd7632022-01-19 12:28:45 +00002732 caller()->pc()->RemoveTrackOrError(sender);
Steve Antond78323f2018-07-11 11:13:44 -07002733 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07002734 caller()->CreateAndSetAndSignalOffer();
2735 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2736 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002737 {
2738 MediaExpectations media_expectations;
2739 media_expectations.CalleeExpectsSomeAudio();
2740 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2741 }
deadbeef2f425aa2017-04-14 10:41:32 -07002742}
2743
Seth Hampson2f0d7022018-02-20 11:54:42 -08002744TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02002745 ASSERT_TRUE(CreatePeerConnectionWrappers());
2746 ConnectFakeSignaling();
2747
Mirko Bonadei317a1f02019-09-17 17:06:18 +02002748 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002749 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
2750 ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true));
Elad Alon99c3fe52017-10-13 16:29:40 +02002751 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01002752 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
2753 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02002754
Steve Anton15324772018-01-16 10:26:49 -08002755 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02002756 caller()->CreateAndSetAndSignalOffer();
2757 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2758}
2759
Steve Antonede9ca52017-10-16 13:04:27 -07002760// Test that if candidates are only signaled by applying full session
2761// descriptions (instead of using AddIceCandidate), the peers can connect to
2762// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002763TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07002764 ASSERT_TRUE(CreatePeerConnectionWrappers());
2765 // Each side will signal the session descriptions but not candidates.
2766 ConnectFakeSignalingForSdpOnly();
2767
2768 // Add audio video track and exchange the initial offer/answer with media
2769 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08002770 caller()->AddAudioVideoTracks();
2771 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002772 caller()->CreateAndSetAndSignalOffer();
2773
2774 // Wait for all candidates to be gathered on both the caller and callee.
2775 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2776 caller()->ice_gathering_state(), kDefaultTimeout);
2777 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2778 callee()->ice_gathering_state(), kDefaultTimeout);
2779
2780 // The candidates will now be included in the session description, so
2781 // signaling them will start the ICE connection.
2782 caller()->CreateAndSetAndSignalOffer();
2783 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2784
2785 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002786 MediaExpectations media_expectations;
2787 media_expectations.ExpectBidirectionalAudioAndVideo();
2788 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07002789}
2790
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002791#if !defined(THREAD_SANITIZER)
2792// These tests provokes TSAN errors. See bugs.webrtc.org/11305.
2793
henrika5f6bf242017-11-01 11:06:56 +01002794// Test that SetAudioPlayout can be used to disable audio playout from the
2795// start, then later enable it. This may be useful, for example, if the caller
2796// needs to play a local ringtone until some event occurs, after which it
2797// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002798TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01002799 ASSERT_TRUE(CreatePeerConnectionWrappers());
2800 ConnectFakeSignaling();
2801
2802 // Set up audio-only call where audio playout is disabled on caller's side.
2803 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08002804 caller()->AddAudioTrack();
2805 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01002806 caller()->CreateAndSetAndSignalOffer();
2807 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2808
2809 // Pump messages for a second.
2810 WAIT(false, 1000);
2811 // Since audio playout is disabled, the caller shouldn't have received
2812 // anything (at the playout level, at least).
2813 EXPECT_EQ(0, caller()->audio_frames_received());
2814 // As a sanity check, make sure the callee (for which playout isn't disabled)
2815 // did still see frames on its audio level.
2816 ASSERT_GT(callee()->audio_frames_received(), 0);
2817
2818 // Enable playout again, and ensure audio starts flowing.
2819 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002820 MediaExpectations media_expectations;
2821 media_expectations.ExpectBidirectionalAudio();
2822 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01002823}
2824
Harald Alvestrand39993842021-02-17 09:05:31 +00002825double GetAudioEnergyStat(PeerConnectionIntegrationWrapper* pc) {
henrika5f6bf242017-11-01 11:06:56 +01002826 auto report = pc->NewGetStats();
2827 auto track_stats_list =
2828 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2829 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
2830 for (const auto* track_stats : track_stats_list) {
2831 if (track_stats->remote_source.is_defined() &&
2832 *track_stats->remote_source) {
2833 remote_track_stats = track_stats;
2834 break;
2835 }
2836 }
2837
2838 if (!remote_track_stats->total_audio_energy.is_defined()) {
2839 return 0.0;
2840 }
2841 return *remote_track_stats->total_audio_energy;
2842}
2843
2844// Test that if audio playout is disabled via the SetAudioPlayout() method, then
2845// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002846TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01002847 DisableAudioPlayoutStillGeneratesAudioStats) {
2848 ASSERT_TRUE(CreatePeerConnectionWrappers());
2849 ConnectFakeSignaling();
2850
2851 // Set up audio-only call where playout is disabled but audio-processing is
2852 // still active.
Steve Anton15324772018-01-16 10:26:49 -08002853 caller()->AddAudioTrack();
2854 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01002855 caller()->pc()->SetAudioPlayout(false);
2856
2857 caller()->CreateAndSetAndSignalOffer();
2858 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2859
2860 // Wait for the callee to receive audio stats.
2861 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
2862}
2863
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002864#endif // !defined(THREAD_SANITIZER)
2865
henrika4f167df2017-11-01 14:45:55 +01002866// Test that SetAudioRecording can be used to disable audio recording from the
2867// start, then later enable it. This may be useful, for example, if the caller
2868// wants to ensure that no audio resources are active before a certain state
2869// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002870TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01002871 ASSERT_TRUE(CreatePeerConnectionWrappers());
2872 ConnectFakeSignaling();
2873
2874 // Set up audio-only call where audio recording is disabled on caller's side.
2875 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08002876 caller()->AddAudioTrack();
2877 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01002878 caller()->CreateAndSetAndSignalOffer();
2879 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2880
2881 // Pump messages for a second.
2882 WAIT(false, 1000);
2883 // Since caller has disabled audio recording, the callee shouldn't have
2884 // received anything.
2885 EXPECT_EQ(0, callee()->audio_frames_received());
2886 // As a sanity check, make sure the caller did still see frames on its
2887 // audio level since audio recording is enabled on the calle side.
2888 ASSERT_GT(caller()->audio_frames_received(), 0);
2889
2890 // Enable audio recording again, and ensure audio starts flowing.
2891 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002892 MediaExpectations media_expectations;
2893 media_expectations.ExpectBidirectionalAudio();
2894 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01002895}
2896
Qingsi Wang7685e862018-06-11 20:15:46 -07002897TEST_P(PeerConnectionIntegrationTest,
2898 IceEventsGeneratedAndLoggedInRtcEventLog) {
2899 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
2900 ConnectFakeSignaling();
2901 PeerConnectionInterface::RTCOfferAnswerOptions options;
2902 options.offer_to_receive_audio = 1;
2903 caller()->SetOfferAnswerOptions(options);
2904 caller()->CreateAndSetAndSignalOffer();
2905 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2906 ASSERT_NE(nullptr, caller()->event_log_factory());
2907 ASSERT_NE(nullptr, callee()->event_log_factory());
2908 webrtc::FakeRtcEventLog* caller_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01002909 caller()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07002910 webrtc::FakeRtcEventLog* callee_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01002911 callee()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07002912 ASSERT_NE(nullptr, caller_event_log);
2913 ASSERT_NE(nullptr, callee_event_log);
2914 int caller_ice_config_count = caller_event_log->GetEventCount(
2915 webrtc::RtcEvent::Type::IceCandidatePairConfig);
2916 int caller_ice_event_count = caller_event_log->GetEventCount(
2917 webrtc::RtcEvent::Type::IceCandidatePairEvent);
2918 int callee_ice_config_count = callee_event_log->GetEventCount(
2919 webrtc::RtcEvent::Type::IceCandidatePairConfig);
2920 int callee_ice_event_count = callee_event_log->GetEventCount(
2921 webrtc::RtcEvent::Type::IceCandidatePairEvent);
2922 EXPECT_LT(0, caller_ice_config_count);
2923 EXPECT_LT(0, caller_ice_event_count);
2924 EXPECT_LT(0, callee_ice_config_count);
2925 EXPECT_LT(0, callee_ice_event_count);
2926}
2927
Qingsi Wangc129c352019-04-18 10:41:58 -07002928TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07002929 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2930 3478};
2931 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2932
2933 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
2934
2935 webrtc::PeerConnectionInterface::IceServer ice_server;
2936 ice_server.urls.push_back("turn:88.88.88.0:3478");
2937 ice_server.username = "test";
2938 ice_server.password = "test";
2939
2940 PeerConnectionInterface::RTCConfiguration caller_config;
2941 caller_config.servers.push_back(ice_server);
2942 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
2943 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07002944 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07002945
2946 PeerConnectionInterface::RTCConfiguration callee_config;
2947 callee_config.servers.push_back(ice_server);
2948 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
2949 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07002950 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07002951
2952 ASSERT_TRUE(
2953 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
2954
2955 // Do normal offer/answer and wait for ICE to complete.
2956 ConnectFakeSignaling();
2957 caller()->AddAudioVideoTracks();
2958 callee()->AddAudioVideoTracks();
2959 caller()->CreateAndSetAndSignalOffer();
2960 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2961 // Since we are doing continual gathering, the ICE transport does not reach
2962 // kIceGatheringComplete (see
2963 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
2964 // kIceConnectionComplete.
2965 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2966 caller()->ice_connection_state(), kDefaultTimeout);
2967 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2968 callee()->ice_connection_state(), kDefaultTimeout);
2969 // Note that we cannot use the metric
Artem Titovcfea2182021-08-10 01:22:31 +02002970 // `WebRTC.PeerConnection.CandidatePairType_UDP` in this test since this
Qingsi Wangc129c352019-04-18 10:41:58 -07002971 // metric is only populated when we reach kIceConnectionComplete in the
2972 // current implementation.
2973 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
2974 caller()->last_candidate_gathered().type());
2975 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
2976 callee()->last_candidate_gathered().type());
2977
2978 // Loosen the caller's candidate filter.
2979 caller_config = caller()->pc()->GetConfiguration();
2980 caller_config.type = webrtc::PeerConnectionInterface::kAll;
2981 caller()->pc()->SetConfiguration(caller_config);
2982 // We should have gathered a new host candidate.
2983 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
2984 caller()->last_candidate_gathered().type(), kDefaultTimeout);
2985
2986 // Loosen the callee's candidate filter.
2987 callee_config = callee()->pc()->GetConfiguration();
2988 callee_config.type = webrtc::PeerConnectionInterface::kAll;
2989 callee()->pc()->SetConfiguration(callee_config);
2990 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
2991 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02002992
2993 // Create an offer and verify that it does not contain an ICE restart (i.e new
2994 // ice credentials).
2995 std::string caller_ufrag_pre_offer = caller()
2996 ->pc()
2997 ->local_description()
2998 ->description()
2999 ->transport_infos()[0]
3000 .description.ice_ufrag;
3001 caller()->CreateAndSetAndSignalOffer();
3002 std::string caller_ufrag_post_offer = caller()
3003 ->pc()
3004 ->local_description()
3005 ->description()
3006 ->transport_infos()[0]
3007 .description.ice_ufrag;
3008 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07003009}
3010
Eldar Relloda13ea22019-06-01 12:23:43 +03003011TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03003012 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3013 3478};
3014 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3015
3016 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3017
3018 webrtc::PeerConnectionInterface::IceServer ice_server;
3019 ice_server.urls.push_back("turn:88.88.88.0:3478");
3020 ice_server.username = "test";
3021 ice_server.password = "123";
3022
3023 PeerConnectionInterface::RTCConfiguration caller_config;
3024 caller_config.servers.push_back(ice_server);
3025 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3026 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3027
3028 PeerConnectionInterface::RTCConfiguration callee_config;
3029 callee_config.servers.push_back(ice_server);
3030 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3031 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3032
3033 ASSERT_TRUE(
3034 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3035
3036 // Do normal offer/answer and wait for ICE to complete.
3037 ConnectFakeSignaling();
3038 caller()->AddAudioVideoTracks();
3039 callee()->AddAudioVideoTracks();
3040 caller()->CreateAndSetAndSignalOffer();
3041 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3042 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
3043 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
3044 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02003045 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03003046}
3047
Eldar Rellofa8019c2020-05-14 11:59:33 +03003048TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
3049 webrtc::PeerConnectionInterface::IceServer ice_server;
3050 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
3051 ice_server.username = "test";
3052 ice_server.password = "test";
3053
3054 PeerConnectionInterface::RTCConfiguration caller_config;
3055 caller_config.servers.push_back(ice_server);
3056 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3057 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3058
3059 PeerConnectionInterface::RTCConfiguration callee_config;
3060 callee_config.servers.push_back(ice_server);
3061 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3062 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3063
3064 ASSERT_TRUE(
3065 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3066
3067 // Do normal offer/answer and wait for ICE to complete.
3068 ConnectFakeSignaling();
3069 caller()->AddAudioVideoTracks();
3070 callee()->AddAudioVideoTracks();
3071 caller()->CreateAndSetAndSignalOffer();
3072 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3073 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
3074 EXPECT_EQ(caller()->error_event().address, "");
3075}
3076
Eldar Rello5ab79e62019-10-09 18:29:44 +03003077TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3078 AudioKeepsFlowingAfterImplicitRollback) {
3079 PeerConnectionInterface::RTCConfiguration config;
3080 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3081 config.enable_implicit_rollback = true;
3082 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3083 ConnectFakeSignaling();
3084 caller()->AddAudioTrack();
3085 callee()->AddAudioTrack();
3086 caller()->CreateAndSetAndSignalOffer();
3087 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3088 MediaExpectations media_expectations;
3089 media_expectations.ExpectBidirectionalAudio();
3090 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3091 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
3092 caller()->AddVideoTrack();
3093 callee()->AddVideoTrack();
Tommi87f70902021-04-27 14:43:08 +02003094 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02003095 callee()->pc()->SetLocalDescription(observer.get(),
Eldar Rello5ab79e62019-10-09 18:29:44 +03003096 callee()->CreateOfferAndWait().release());
3097 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3098 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
3099 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3100 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3101}
3102
3103TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3104 ImplicitRollbackVisitsStableState) {
3105 RTCConfiguration config;
3106 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3107 config.enable_implicit_rollback = true;
3108
3109 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3110
Tommi87f70902021-04-27 14:43:08 +02003111 auto sld_observer =
3112 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02003113 callee()->pc()->SetLocalDescription(sld_observer.get(),
Eldar Rello5ab79e62019-10-09 18:29:44 +03003114 callee()->CreateOfferAndWait().release());
3115 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
3116 EXPECT_EQ(sld_observer->error(), "");
3117
Tommi87f70902021-04-27 14:43:08 +02003118 auto srd_observer =
3119 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003120 callee()->pc()->SetRemoteDescription(
Niels Möllerafb246b2022-04-20 14:26:50 +02003121 srd_observer.get(), caller()->CreateOfferAndWait().release());
Eldar Rello5ab79e62019-10-09 18:29:44 +03003122 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
3123 EXPECT_EQ(srd_observer->error(), "");
3124
3125 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
3126 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
3127 PeerConnectionInterface::kStable,
3128 PeerConnectionInterface::kHaveRemoteOffer));
3129}
3130
Eldar Rellobd9c33a2020-10-01 17:52:45 +03003131TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3132 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
3133 ASSERT_TRUE(CreatePeerConnectionWrappers());
3134 ConnectFakeSignaling();
3135 caller()->AddVideoTrack();
3136 callee()->AddVideoTrack();
3137 auto munger = [](cricket::SessionDescription* desc) {
3138 cricket::VideoContentDescription* video =
3139 GetFirstVideoContentDescription(desc);
3140 auto codecs = video->codecs();
3141 for (auto&& codec : codecs) {
3142 if (codec.name == "H264") {
3143 std::string value;
3144 // The parameter is not supposed to be present in SDP by default.
3145 EXPECT_FALSE(
3146 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3147 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
3148 std::string(""));
3149 }
3150 }
3151 video->set_codecs(codecs);
3152 };
3153 // Munge local offer for SLD.
3154 caller()->SetGeneratedSdpMunger(munger);
3155 // Munge remote answer for SRD.
3156 caller()->SetReceivedSdpMunger(munger);
3157 caller()->CreateAndSetAndSignalOffer();
3158 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3159 // Observe that after munging the parameter is present in generated SDP.
3160 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
3161 cricket::VideoContentDescription* video =
3162 GetFirstVideoContentDescription(desc);
3163 for (auto&& codec : video->codecs()) {
3164 if (codec.name == "H264") {
3165 std::string value;
3166 EXPECT_TRUE(
3167 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3168 }
3169 }
3170 });
3171 caller()->CreateOfferAndWait();
3172}
3173
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003174TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00003175 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003176 PeerConnectionInterface::RTCConfiguration config;
3177 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3178 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3179 ConnectFakeSignaling();
3180 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3181
3182 caller()->CreateAndSetAndSignalOffer();
3183 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3184 int current_size = caller()->pc()->GetTransceivers().size();
3185 // Add more tracks until we get close to having issues.
3186 // Issues have been seen at:
3187 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003188 // - 16 tracks on android_arm_dbg (flaky)
3189 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003190 // Double the number of tracks
3191 for (int i = 0; i < current_size; i++) {
3192 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3193 }
3194 current_size = caller()->pc()->GetTransceivers().size();
3195 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3196 auto start_time_ms = rtc::TimeMillis();
3197 caller()->CreateAndSetAndSignalOffer();
3198 // We want to stop when the time exceeds one second.
3199 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3200 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3201 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3202 ASSERT_GT(1000, elapsed_time_ms)
3203 << "Audio transceivers: Negotiation took too long after "
3204 << current_size << " tracks added";
3205 }
3206}
3207
3208TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3209 RenegotiateManyVideoTransceivers) {
3210 PeerConnectionInterface::RTCConfiguration config;
3211 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3212 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3213 ConnectFakeSignaling();
3214 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3215
3216 caller()->CreateAndSetAndSignalOffer();
3217 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3218 int current_size = caller()->pc()->GetTransceivers().size();
3219 // Add more tracks until we get close to having issues.
3220 // Issues have been seen at:
3221 // - 96 on a Linux workstation
3222 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
3223 // - 32 on android_arm64_rel and linux_dbg bots
Harald Alvestrand785e23b2021-03-15 21:26:27 +00003224 // - 16 on Android 64 (Nexus 5x)
3225 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003226 // Double the number of tracks
3227 for (int i = 0; i < current_size; i++) {
3228 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3229 }
3230 current_size = caller()->pc()->GetTransceivers().size();
3231 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3232 auto start_time_ms = rtc::TimeMillis();
3233 caller()->CreateAndSetAndSignalOffer();
3234 // We want to stop when the time exceeds one second.
3235 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3236 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3237 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3238 ASSERT_GT(1000, elapsed_time_ms)
3239 << "Video transceivers: Negotiation took too long after "
3240 << current_size << " tracks added";
3241 }
3242}
3243
Harald Alvestrand94324f22021-01-13 12:31:53 +00003244TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3245 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
3246 PeerConnectionInterface::RTCConfiguration config;
3247 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3248 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3249 ConnectFakeSignaling();
3250 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003251 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003252 caller()->CreateAndSetAndSignalOffer();
3253 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3254 // Wait until we can see the audio flowing.
3255 MediaExpectations media_expectations;
3256 media_expectations.CalleeExpectsSomeAudio();
3257 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3258
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003259 // Get the baseline numbers for audio_packets and audio_delay
3260 // in both directions.
3261 caller()->StartWatchingDelayStats();
3262 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003263
3264 int current_size = caller()->pc()->GetTransceivers().size();
3265 // Add more tracks until we get close to having issues.
3266 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003267 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00003268 // Double the number of tracks
3269 for (int i = 0; i < current_size; i++) {
3270 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3271 }
3272 current_size = caller()->pc()->GetTransceivers().size();
3273 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3274 auto start_time_ms = rtc::TimeMillis();
3275 caller()->CreateAndSetAndSignalOffer();
3276 // We want to stop when the time exceeds one second.
3277 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3278 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3279 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3280 // This is a guard against the test using excessive amounts of time.
3281 ASSERT_GT(5000, elapsed_time_ms)
3282 << "Video transceivers: Negotiation took too long after "
3283 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003284 caller()->UpdateDelayStats("caller reception", current_size);
3285 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00003286 }
3287}
3288
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003289INSTANTIATE_TEST_SUITE_P(
3290 PeerConnectionIntegrationTest,
3291 PeerConnectionIntegrationTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02003292 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003293 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3294 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3295 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Steve Antond3679212018-01-17 17:41:02 -08003296
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003297INSTANTIATE_TEST_SUITE_P(
3298 PeerConnectionIntegrationTest,
3299 PeerConnectionIntegrationTestWithFakeClock,
Florent Castelli15a38de2022-04-06 00:38:21 +02003300 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003301 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3302 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3303 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Yves Gerey100fe632020-01-17 19:15:53 +01003304
Steve Anton74255ff2018-01-24 18:32:57 -08003305// Tests that verify interoperability between Plan B and Unified Plan
3306// PeerConnections.
3307class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003308 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08003309 public ::testing::WithParamInterface<
3310 std::tuple<SdpSemantics, SdpSemantics>> {
3311 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003312 // Setting the SdpSemantics for the base test to kDefault does not matter
3313 // because we specify not to use the test semantics when creating
Harald Alvestrand39993842021-02-17 09:05:31 +00003314 // PeerConnectionIntegrationWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08003315 PeerConnectionIntegrationInteropTest()
Florent Castelli15a38de2022-04-06 00:38:21 +02003316 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB_DEPRECATED),
Seth Hampson2f0d7022018-02-20 11:54:42 -08003317 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08003318 callee_semantics_(std::get<1>(GetParam())) {}
3319
3320 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07003321 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
3322 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08003323 }
3324
3325 const SdpSemantics caller_semantics_;
3326 const SdpSemantics callee_semantics_;
3327};
3328
3329TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
3330 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3331 ConnectFakeSignaling();
3332
3333 caller()->CreateAndSetAndSignalOffer();
3334 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3335}
3336
3337TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
3338 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3339 ConnectFakeSignaling();
3340 auto audio_sender = caller()->AddAudioTrack();
3341
3342 caller()->CreateAndSetAndSignalOffer();
3343 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3344
3345 // Verify that one audio receiver has been created on the remote and that it
3346 // has the same track ID as the sending track.
3347 auto receivers = callee()->pc()->GetReceivers();
3348 ASSERT_EQ(1u, receivers.size());
3349 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
3350 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
3351
Seth Hampson2f0d7022018-02-20 11:54:42 -08003352 MediaExpectations media_expectations;
3353 media_expectations.CalleeExpectsSomeAudio();
3354 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003355}
3356
3357TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
3358 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3359 ConnectFakeSignaling();
3360 auto video_sender = caller()->AddVideoTrack();
3361 auto audio_sender = caller()->AddAudioTrack();
3362
3363 caller()->CreateAndSetAndSignalOffer();
3364 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3365
3366 // Verify that one audio and one video receiver have been created on the
3367 // remote and that they have the same track IDs as the sending tracks.
3368 auto audio_receivers =
3369 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
3370 ASSERT_EQ(1u, audio_receivers.size());
3371 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
3372 auto video_receivers =
3373 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
3374 ASSERT_EQ(1u, video_receivers.size());
3375 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
3376
Seth Hampson2f0d7022018-02-20 11:54:42 -08003377 MediaExpectations media_expectations;
3378 media_expectations.CalleeExpectsSomeAudioAndVideo();
3379 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003380}
3381
3382TEST_P(PeerConnectionIntegrationInteropTest,
3383 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
3384 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3385 ConnectFakeSignaling();
3386 caller()->AddAudioVideoTracks();
3387 callee()->AddAudioVideoTracks();
3388
3389 caller()->CreateAndSetAndSignalOffer();
3390 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3391
Seth Hampson2f0d7022018-02-20 11:54:42 -08003392 MediaExpectations media_expectations;
3393 media_expectations.ExpectBidirectionalAudioAndVideo();
3394 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003395}
3396
3397TEST_P(PeerConnectionIntegrationInteropTest,
3398 ReverseRolesOneAudioLocalToOneVideoRemote) {
3399 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3400 ConnectFakeSignaling();
3401 caller()->AddAudioTrack();
3402 callee()->AddVideoTrack();
3403
3404 caller()->CreateAndSetAndSignalOffer();
3405 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3406
3407 // Verify that only the audio track has been negotiated.
3408 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
3409 // Might also check that the callee's NegotiationNeeded flag is set.
3410
3411 // Reverse roles.
3412 callee()->CreateAndSetAndSignalOffer();
3413 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3414
Seth Hampson2f0d7022018-02-20 11:54:42 -08003415 MediaExpectations media_expectations;
3416 media_expectations.CallerExpectsSomeVideo();
3417 media_expectations.CalleeExpectsSomeAudio();
3418 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003419}
3420
Taylor Brandstetter1c7ecef2021-08-11 12:38:35 -07003421TEST_P(PeerConnectionIntegrationTest, NewTracksDoNotCauseNewCandidates) {
3422 ASSERT_TRUE(CreatePeerConnectionWrappers());
3423 ConnectFakeSignaling();
3424 caller()->AddAudioVideoTracks();
3425 caller()->CreateAndSetAndSignalOffer();
3426 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3427 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3428 caller()->ExpectCandidates(0);
3429 callee()->ExpectCandidates(0);
3430 caller()->AddAudioTrack();
3431 caller()->CreateAndSetAndSignalOffer();
3432 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3433}
3434
Harald Alvestrand35ba0c52022-05-05 07:37:41 +00003435TEST_P(PeerConnectionIntegrationTest, MediaCallWithoutMediaEngineFails) {
3436 ASSERT_TRUE(CreatePeerConnectionWrappersWithoutMediaEngine());
3437 // AddTrack should fail.
3438 EXPECT_FALSE(
3439 caller()->pc()->AddTrack(caller()->CreateLocalAudioTrack(), {}).ok());
3440}
3441
Mirko Bonadeic84f6612019-01-31 12:20:57 +01003442INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07003443 PeerConnectionIntegrationTest,
3444 PeerConnectionIntegrationInteropTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02003445 Values(std::make_tuple(SdpSemantics::kPlanB_DEPRECATED,
3446 SdpSemantics::kUnifiedPlan),
3447 std::make_tuple(SdpSemantics::kUnifiedPlan,
3448 SdpSemantics::kPlanB_DEPRECATED)));
Steve Antonba42e992018-04-09 14:10:01 -07003449
3450// Test that if the Unified Plan side offers two video tracks then the Plan B
3451// side will only see the first one and ignore the second.
3452TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07003453 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
Florent Castelli15a38de2022-04-06 00:38:21 +02003454 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB_DEPRECATED));
Steve Anton74255ff2018-01-24 18:32:57 -08003455 ConnectFakeSignaling();
3456 auto first_sender = caller()->AddVideoTrack();
3457 caller()->AddVideoTrack();
3458
3459 caller()->CreateAndSetAndSignalOffer();
3460 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3461
3462 // Verify that there is only one receiver and it corresponds to the first
3463 // added track.
3464 auto receivers = callee()->pc()->GetReceivers();
3465 ASSERT_EQ(1u, receivers.size());
3466 EXPECT_TRUE(receivers[0]->track()->enabled());
3467 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
3468
Seth Hampson2f0d7022018-02-20 11:54:42 -08003469 MediaExpectations media_expectations;
3470 media_expectations.CalleeExpectsSomeVideo();
3471 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003472}
3473
Steve Anton2bed3972019-01-04 17:04:30 -08003474// Test that if the initial offer tagged BUNDLE section is rejected due to its
3475// associated RtpTransceiver being stopped and another transceiver is added,
3476// then renegotiation causes the callee to receive the new video track without
3477// error.
3478// This is a regression test for bugs.webrtc.org/9954
3479TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3480 ReOfferWithStoppedBundleTaggedTransceiver) {
3481 RTCConfiguration config;
3482 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3483 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3484 ConnectFakeSignaling();
3485 auto audio_transceiver_or_error =
3486 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3487 ASSERT_TRUE(audio_transceiver_or_error.ok());
3488 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3489
3490 caller()->CreateAndSetAndSignalOffer();
3491 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3492 {
3493 MediaExpectations media_expectations;
3494 media_expectations.CalleeExpectsSomeAudio();
3495 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3496 }
3497
Harald Alvestrand6060df52020-08-11 09:54:02 +02003498 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08003499 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3500
3501 caller()->CreateAndSetAndSignalOffer();
3502 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3503 {
3504 MediaExpectations media_expectations;
3505 media_expectations.CalleeExpectsSomeVideo();
3506 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3507 }
3508}
3509
Harald Alvestrandbedb6052020-08-20 14:50:10 +02003510TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3511 StopTransceiverRemovesDtlsTransports) {
3512 RTCConfiguration config;
3513 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3514 ConnectFakeSignaling();
3515 auto audio_transceiver_or_error =
3516 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3517 ASSERT_TRUE(audio_transceiver_or_error.ok());
3518 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3519
3520 caller()->CreateAndSetAndSignalOffer();
3521 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3522
3523 audio_transceiver->StopStandard();
3524 caller()->CreateAndSetAndSignalOffer();
3525 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3526 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
3527 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
3528 caller()->pc()->ice_gathering_state());
3529 EXPECT_THAT(caller()->ice_gathering_state_history(),
3530 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3531 PeerConnectionInterface::kIceGatheringComplete,
3532 PeerConnectionInterface::kIceGatheringNew));
3533}
3534
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003535TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00003536 StopTransceiverStopsAndRemovesTransceivers) {
3537 RTCConfiguration config;
3538 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3539 ConnectFakeSignaling();
3540 auto audio_transceiver_or_error =
3541 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3542 ASSERT_TRUE(audio_transceiver_or_error.ok());
3543 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
3544
3545 caller()->CreateAndSetAndSignalOffer();
3546 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3547 caller_transceiver->StopStandard();
3548
3549 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
3550 caller()->CreateAndSetAndSignalOffer();
3551 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3552 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
3553 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
3554 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
3555 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
3556 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
3557 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
3558 EXPECT_TRUE(caller_transceiver->stopped());
3559 EXPECT_TRUE(callee_transceiver->stopped());
3560}
3561
3562TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003563 StopTransceiverEndsIncomingAudioTrack) {
3564 RTCConfiguration config;
3565 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3566 ConnectFakeSignaling();
3567 auto audio_transceiver_or_error =
3568 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3569 ASSERT_TRUE(audio_transceiver_or_error.ok());
3570 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3571
3572 caller()->CreateAndSetAndSignalOffer();
3573 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3574 auto caller_track = audio_transceiver->receiver()->track();
3575 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3576 audio_transceiver->StopStandard();
3577 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3578 caller_track->state());
3579 caller()->CreateAndSetAndSignalOffer();
3580 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3581 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3582 callee_track->state());
3583}
3584
3585TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3586 StopTransceiverEndsIncomingVideoTrack) {
3587 RTCConfiguration config;
3588 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3589 ConnectFakeSignaling();
3590 auto audio_transceiver_or_error =
3591 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3592 ASSERT_TRUE(audio_transceiver_or_error.ok());
3593 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3594
3595 caller()->CreateAndSetAndSignalOffer();
3596 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3597 auto caller_track = audio_transceiver->receiver()->track();
3598 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3599 audio_transceiver->StopStandard();
3600 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3601 caller_track->state());
3602 caller()->CreateAndSetAndSignalOffer();
3603 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3604 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3605 callee_track->state());
3606}
3607
Harald Alvestrand89c40e22021-02-17 08:58:35 +00003608} // namespace
Harald Alvestrand39993842021-02-17 09:05:31 +00003609
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01003610} // namespace webrtc