blob: 1ee85c3be6e8a4ff37db09d8e4c77c9a67ed0ab2 [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 Alvestrand39993842021-02-17 09:05:31 +000011#include <stdint.h>
deadbeef1dcb1642017-03-29 21:08:16 -070012
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -070013#include <algorithm>
deadbeef1dcb1642017-03-29 21:08:16 -070014#include <memory>
Harald Alvestrand39993842021-02-17 09:05:31 +000015#include <string>
16#include <tuple>
Harald Alvestrandc24a2182022-02-23 13:44:59 +000017#include <type_traits>
deadbeef1dcb1642017-03-29 21:08:16 -070018#include <utility>
19#include <vector>
20
Steve Anton64b626b2019-01-28 17:25:26 -080021#include "absl/algorithm/container.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000022#include "absl/types/optional.h"
23#include "api/async_resolver_factory.h"
24#include "api/candidate.h"
25#include "api/crypto/crypto_options.h"
26#include "api/dtmf_sender_interface.h"
27#include "api/ice_transport_interface.h"
28#include "api/jsep.h"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "api/media_stream_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000030#include "api/media_types.h"
Steve Anton10542f22019-01-11 09:11:00 -080031#include "api/peer_connection_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000032#include "api/rtc_error.h"
33#include "api/rtc_event_log/rtc_event.h"
34#include "api/rtc_event_log/rtc_event_log.h"
35#include "api/rtc_event_log_output.h"
36#include "api/rtp_parameters.h"
Steve Anton10542f22019-01-11 09:11:00 -080037#include "api/rtp_receiver_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000038#include "api/rtp_sender_interface.h"
39#include "api/rtp_transceiver_direction.h"
40#include "api/rtp_transceiver_interface.h"
41#include "api/scoped_refptr.h"
42#include "api/stats/rtc_stats.h"
43#include "api/stats/rtc_stats_report.h"
44#include "api/stats/rtcstats_objects.h"
45#include "api/transport/rtp/rtp_source.h"
Steve Anton10542f22019-01-11 09:11:00 -080046#include "api/uma_metrics.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000047#include "api/units/time_delta.h"
48#include "api/video/video_rotation.h"
49#include "logging/rtc_event_log/fake_rtc_event_log.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070050#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000051#include "media/base/codec.h"
52#include "media/base/media_constants.h"
53#include "media/base/stream_params.h"
Steve Anton10542f22019-01-11 09:11:00 -080054#include "p2p/base/mock_async_resolver.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000055#include "p2p/base/port.h"
56#include "p2p/base/port_allocator.h"
Steve Anton10542f22019-01-11 09:11:00 -080057#include "p2p/base/port_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000058#include "p2p/base/stun_server.h"
Steve Anton10542f22019-01-11 09:11:00 -080059#include "p2p/base/test_stun_server.h"
60#include "p2p/base/test_turn_customizer.h"
61#include "p2p/base/test_turn_server.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000062#include "p2p/base/transport_description.h"
63#include "p2p/base/transport_info.h"
Steve Anton10542f22019-01-11 09:11:00 -080064#include "pc/media_session.h"
65#include "pc/peer_connection.h"
66#include "pc/peer_connection_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080067#include "pc/session_description.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000068#include "pc/test/fake_periodic_video_source.h"
69#include "pc/test/integration_test_helpers.h"
Steve Anton10542f22019-01-11 09:11:00 -080070#include "pc/test/mock_peer_connection_observers.h"
Jonas Olssonb75d9e92019-02-22 10:33:29 +010071#include "rtc_base/fake_clock.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070072#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080073#include "rtc_base/fake_network.h"
74#include "rtc_base/firewall_socket_server.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020075#include "rtc_base/gunit.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000076#include "rtc_base/helpers.h"
77#include "rtc_base/location.h"
78#include "rtc_base/logging.h"
79#include "rtc_base/ref_counted_object.h"
80#include "rtc_base/socket_address.h"
81#include "rtc_base/ssl_certificate.h"
82#include "rtc_base/ssl_fingerprint.h"
83#include "rtc_base/ssl_identity.h"
84#include "rtc_base/ssl_stream_adapter.h"
Steve Anton10542f22019-01-11 09:11:00 -080085#include "rtc_base/test_certificate_verifier.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000086#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080087#include "rtc_base/time_utils.h"
88#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020089#include "system_wrappers/include/metrics.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000090#include "test/gmock.h"
91#include "test/gtest.h"
deadbeef1dcb1642017-03-29 21:08:16 -070092
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010093namespace webrtc {
Harald Alvestrand39993842021-02-17 09:05:31 +000094
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010095namespace {
96
Seth Hampson2f0d7022018-02-20 11:54:42 -080097class PeerConnectionIntegrationTest
98 : public PeerConnectionIntegrationBaseTest,
99 public ::testing::WithParamInterface<SdpSemantics> {
100 protected:
101 PeerConnectionIntegrationTest()
102 : PeerConnectionIntegrationBaseTest(GetParam()) {}
103};
104
Yves Gerey100fe632020-01-17 19:15:53 +0100105// Fake clock must be set before threads are started to prevent race on
106// Set/GetClockForTesting().
107// To achieve that, multiple inheritance is used as a mixin pattern
108// where order of construction is finely controlled.
109// This also ensures peerconnection is closed before switching back to non-fake
110// clock, avoiding other races and DCHECK failures such as in rtp_sender.cc.
111class FakeClockForTest : public rtc::ScopedFakeClock {
112 protected:
113 FakeClockForTest() {
114 // Some things use a time of "0" as a special value, so we need to start out
115 // the fake clock at a nonzero time.
116 // TODO(deadbeef): Fix this.
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100117 AdvanceTime(webrtc::TimeDelta::Seconds(1));
Yves Gerey100fe632020-01-17 19:15:53 +0100118 }
119
120 // Explicit handle.
121 ScopedFakeClock& FakeClock() { return *this; }
122};
123
124// Ensure FakeClockForTest is constructed first (see class for rationale).
125class PeerConnectionIntegrationTestWithFakeClock
126 : public FakeClockForTest,
127 public PeerConnectionIntegrationTest {};
128
Seth Hampson2f0d7022018-02-20 11:54:42 -0800129class PeerConnectionIntegrationTestPlanB
130 : public PeerConnectionIntegrationBaseTest {
131 protected:
132 PeerConnectionIntegrationTestPlanB()
133 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
134};
135
136class PeerConnectionIntegrationTestUnifiedPlan
137 : public PeerConnectionIntegrationBaseTest {
138 protected:
139 PeerConnectionIntegrationTestUnifiedPlan()
140 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
141};
142
deadbeef1dcb1642017-03-29 21:08:16 -0700143// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
144// includes testing that the callback is invoked if an observer is connected
145// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800146TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -0700147 RtpReceiverObserverOnFirstPacketReceived) {
148 ASSERT_TRUE(CreatePeerConnectionWrappers());
149 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800150 caller()->AddAudioVideoTracks();
151 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700152 // Start offer/answer exchange and wait for it to complete.
153 caller()->CreateAndSetAndSignalOffer();
154 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
155 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200156 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
157 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -0700158 // Wait for all "first packet received" callbacks to be fired.
159 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -0800160 absl::c_all_of(caller()->rtp_receiver_observers(),
161 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
162 return o->first_packet_received();
163 }),
deadbeef1dcb1642017-03-29 21:08:16 -0700164 kMaxWaitForFramesMs);
165 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -0800166 absl::c_all_of(callee()->rtp_receiver_observers(),
167 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
168 return o->first_packet_received();
169 }),
deadbeef1dcb1642017-03-29 21:08:16 -0700170 kMaxWaitForFramesMs);
171 // If new observers are set after the first packet was already received, the
172 // callback should still be invoked.
173 caller()->ResetRtpReceiverObservers();
174 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200175 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
176 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -0700177 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -0800178 absl::c_all_of(caller()->rtp_receiver_observers(),
179 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
180 return o->first_packet_received();
181 }));
deadbeef1dcb1642017-03-29 21:08:16 -0700182 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -0800183 absl::c_all_of(callee()->rtp_receiver_observers(),
184 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
185 return o->first_packet_received();
186 }));
deadbeef1dcb1642017-03-29 21:08:16 -0700187}
188
189class DummyDtmfObserver : public DtmfSenderObserverInterface {
190 public:
191 DummyDtmfObserver() : completed_(false) {}
192
193 // Implements DtmfSenderObserverInterface.
194 void OnToneChange(const std::string& tone) override {
195 tones_.push_back(tone);
196 if (tone.empty()) {
197 completed_ = true;
198 }
199 }
200
201 const std::vector<std::string>& tones() const { return tones_; }
202 bool completed() const { return completed_; }
203
204 private:
205 bool completed_;
206 std::vector<std::string> tones_;
207};
208
Artem Titov880fa812021-07-30 22:30:23 +0200209// Assumes `sender` already has an audio track added and the offer/answer
deadbeef1dcb1642017-03-29 21:08:16 -0700210// exchange is done.
Harald Alvestrand39993842021-02-17 09:05:31 +0000211void TestDtmfFromSenderToReceiver(PeerConnectionIntegrationWrapper* sender,
212 PeerConnectionIntegrationWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -0800213 // We should be able to get a DTMF sender from the local sender.
214 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
215 sender->pc()->GetSenders().at(0)->GetDtmfSender();
216 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -0700217 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -0700218 dtmf_sender->RegisterObserver(&observer);
219
220 // Test the DtmfSender object just created.
221 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
222 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
223
224 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
225 std::vector<std::string> tones = {"1", "a", ""};
226 EXPECT_EQ(tones, observer.tones());
227 dtmf_sender->UnregisterObserver();
228 // TODO(deadbeef): Verify the tones were actually received end-to-end.
229}
230
231// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
232// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800233TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -0700234 ASSERT_TRUE(CreatePeerConnectionWrappers());
235 ConnectFakeSignaling();
236 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -0800237 caller()->AddAudioTrack();
238 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700239 caller()->CreateAndSetAndSignalOffer();
240 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -0700241 // DTLS must finish before the DTMF sender can be used reliably.
242 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -0700243 TestDtmfFromSenderToReceiver(caller(), callee());
244 TestDtmfFromSenderToReceiver(callee(), caller());
245}
246
247// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
248// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800249TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -0700250 ASSERT_TRUE(CreatePeerConnectionWrappers());
251 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +0100252
deadbeef1dcb1642017-03-29 21:08:16 -0700253 // Do normal offer/answer and wait for some frames to be received in each
254 // direction.
Steve Anton15324772018-01-16 10:26:49 -0800255 caller()->AddAudioVideoTracks();
256 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700257 caller()->CreateAndSetAndSignalOffer();
258 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800259 MediaExpectations media_expectations;
260 media_expectations.ExpectBidirectionalAudioAndVideo();
261 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Ying Wangef3998f2019-12-09 13:06:53 +0100262 EXPECT_METRIC_LE(
263 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
264 webrtc::kEnumCounterKeyProtocolDtls));
265 EXPECT_METRIC_EQ(
266 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
267 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -0700268}
269
Harald Alvestrand50b95522021-11-18 10:01:06 +0000270// Uses SDES instead of DTLS for key agreement.
271TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
272 PeerConnectionInterface::RTCConfiguration sdes_config;
273 sdes_config.enable_dtls_srtp.emplace(false);
274 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
275 ConnectFakeSignaling();
276
277 // Do normal offer/answer and wait for some frames to be received in each
278 // direction.
279 caller()->AddAudioVideoTracks();
280 callee()->AddAudioVideoTracks();
281 caller()->CreateAndSetAndSignalOffer();
282 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
283 MediaExpectations media_expectations;
284 media_expectations.ExpectBidirectionalAudioAndVideo();
285 ASSERT_TRUE(ExpectNewFrames(media_expectations));
286 EXPECT_METRIC_LE(
287 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
288 webrtc::kEnumCounterKeyProtocolSdes));
289 EXPECT_METRIC_EQ(
290 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
291 webrtc::kEnumCounterKeyProtocolDtls));
292}
293
Artem Titov880fa812021-07-30 22:30:23 +0200294// Basic end-to-end test specifying the `enable_encrypted_rtp_header_extensions`
Steve Anton9a44b2d2019-07-12 12:58:30 -0700295// option to offer encrypted versions of all header extensions alongside the
296// unencrypted versions.
297TEST_P(PeerConnectionIntegrationTest,
298 EndToEndCallWithEncryptedRtpHeaderExtensions) {
299 CryptoOptions crypto_options;
300 crypto_options.srtp.enable_encrypted_rtp_header_extensions = true;
301 PeerConnectionInterface::RTCConfiguration config;
302 config.crypto_options = crypto_options;
303 // Note: This allows offering >14 RTP header extensions.
304 config.offer_extmap_allow_mixed = true;
305 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
306 ConnectFakeSignaling();
307
308 // Do normal offer/answer and wait for some frames to be received in each
309 // direction.
310 caller()->AddAudioVideoTracks();
311 callee()->AddAudioVideoTracks();
312 caller()->CreateAndSetAndSignalOffer();
313 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
314 MediaExpectations media_expectations;
315 media_expectations.ExpectBidirectionalAudioAndVideo();
316 ASSERT_TRUE(ExpectNewFrames(media_expectations));
317}
318
deadbeef1dcb1642017-03-29 21:08:16 -0700319// This test sets up a call between two parties with a source resolution of
320// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800321TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -0700322 Send1280By720ResolutionAndReceive16To9AspectRatio) {
323 ASSERT_TRUE(CreatePeerConnectionWrappers());
324 ConnectFakeSignaling();
325
Niels Möller5c7efe72018-05-11 10:34:46 +0200326 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
327 webrtc::FakePeriodicVideoSource::Config config;
328 config.width = 1280;
329 config.height = 720;
Johannes Kron965e7942018-09-13 15:36:20 +0200330 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +0200331 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
332 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -0700333
334 // Do normal offer/answer and wait for at least one frame to be received in
335 // each direction.
336 caller()->CreateAndSetAndSignalOffer();
337 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
338 callee()->min_video_frames_received_per_track() > 0,
339 kMaxWaitForFramesMs);
340
341 // Check rendered aspect ratio.
342 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
343 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
344 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
345 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
346}
347
348// This test sets up an one-way call, with media only from caller to
349// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800350TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -0700351 ASSERT_TRUE(CreatePeerConnectionWrappers());
352 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800353 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700354 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800355 MediaExpectations media_expectations;
356 media_expectations.CalleeExpectsSomeAudioAndVideo();
357 media_expectations.CallerExpectsNoAudio();
358 media_expectations.CallerExpectsNoVideo();
359 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700360}
361
Johannes Kron3e983682020-03-29 22:17:00 +0200362// Tests that send only works without the caller having a decoder factory and
363// the callee having an encoder factory.
364TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSendOnlyVideo) {
365 ASSERT_TRUE(
366 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
367 ConnectFakeSignaling();
368 // Add one-directional video, from caller to callee.
369 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
370 caller()->CreateLocalVideoTrack();
371 caller()->AddTrack(caller_track);
372 PeerConnectionInterface::RTCOfferAnswerOptions options;
373 options.offer_to_receive_video = 0;
374 caller()->SetOfferAnswerOptions(options);
375 caller()->CreateAndSetAndSignalOffer();
376 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
377 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
378
379 // Expect video to be received in one direction.
380 MediaExpectations media_expectations;
381 media_expectations.CallerExpectsNoVideo();
382 media_expectations.CalleeExpectsSomeVideo();
383
384 EXPECT_TRUE(ExpectNewFrames(media_expectations));
385}
386
387// Tests that receive only works without the caller having an encoder factory
388// and the callee having a decoder factory.
389TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithReceiveOnlyVideo) {
390 ASSERT_TRUE(
391 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/false));
392 ConnectFakeSignaling();
393 // Add one-directional video, from callee to caller.
394 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
395 callee()->CreateLocalVideoTrack();
396 callee()->AddTrack(callee_track);
397 PeerConnectionInterface::RTCOfferAnswerOptions options;
398 options.offer_to_receive_video = 1;
399 caller()->SetOfferAnswerOptions(options);
400 caller()->CreateAndSetAndSignalOffer();
401 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
402 ASSERT_EQ(caller()->pc()->GetReceivers().size(), 1u);
403
404 // Expect video to be received in one direction.
405 MediaExpectations media_expectations;
406 media_expectations.CallerExpectsSomeVideo();
407 media_expectations.CalleeExpectsNoVideo();
408
409 EXPECT_TRUE(ExpectNewFrames(media_expectations));
410}
411
412TEST_P(PeerConnectionIntegrationTest,
413 EndToEndCallAddReceiveVideoToSendOnlyCall) {
414 ASSERT_TRUE(CreatePeerConnectionWrappers());
415 ConnectFakeSignaling();
416 // Add one-directional video, from caller to callee.
417 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
418 caller()->CreateLocalVideoTrack();
419 caller()->AddTrack(caller_track);
420 caller()->CreateAndSetAndSignalOffer();
421 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
422
423 // Add receive video.
424 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
425 callee()->CreateLocalVideoTrack();
426 callee()->AddTrack(callee_track);
427 caller()->CreateAndSetAndSignalOffer();
428 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
429
430 // Ensure that video frames are received end-to-end.
431 MediaExpectations media_expectations;
432 media_expectations.ExpectBidirectionalVideo();
433 ASSERT_TRUE(ExpectNewFrames(media_expectations));
434}
435
436TEST_P(PeerConnectionIntegrationTest,
437 EndToEndCallAddSendVideoToReceiveOnlyCall) {
438 ASSERT_TRUE(CreatePeerConnectionWrappers());
439 ConnectFakeSignaling();
440 // Add one-directional video, from callee to caller.
441 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
442 callee()->CreateLocalVideoTrack();
443 callee()->AddTrack(callee_track);
444 caller()->CreateAndSetAndSignalOffer();
445 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
446
447 // Add send video.
448 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
449 caller()->CreateLocalVideoTrack();
450 caller()->AddTrack(caller_track);
451 caller()->CreateAndSetAndSignalOffer();
452 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
453
454 // Expect video to be received in one direction.
455 MediaExpectations media_expectations;
456 media_expectations.ExpectBidirectionalVideo();
457 ASSERT_TRUE(ExpectNewFrames(media_expectations));
458}
459
460TEST_P(PeerConnectionIntegrationTest,
461 EndToEndCallRemoveReceiveVideoFromSendReceiveCall) {
462 ASSERT_TRUE(CreatePeerConnectionWrappers());
463 ConnectFakeSignaling();
464 // Add send video, from caller to callee.
465 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
466 caller()->CreateLocalVideoTrack();
467 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
468 caller()->AddTrack(caller_track);
469 // Add receive video, from callee to caller.
470 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
471 callee()->CreateLocalVideoTrack();
472
473 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
474 callee()->AddTrack(callee_track);
475 caller()->CreateAndSetAndSignalOffer();
476 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
477
478 // Remove receive video (i.e., callee sender track).
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000479 callee()->pc()->RemoveTrackOrError(callee_sender);
Johannes Kron3e983682020-03-29 22:17:00 +0200480
481 caller()->CreateAndSetAndSignalOffer();
482 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
483
484 // Expect one-directional video.
485 MediaExpectations media_expectations;
486 media_expectations.CallerExpectsNoVideo();
487 media_expectations.CalleeExpectsSomeVideo();
488
489 ASSERT_TRUE(ExpectNewFrames(media_expectations));
490}
491
492TEST_P(PeerConnectionIntegrationTest,
493 EndToEndCallRemoveSendVideoFromSendReceiveCall) {
494 ASSERT_TRUE(CreatePeerConnectionWrappers());
495 ConnectFakeSignaling();
496 // Add send video, from caller to callee.
497 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
498 caller()->CreateLocalVideoTrack();
499 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
500 caller()->AddTrack(caller_track);
501 // Add receive video, from callee to caller.
502 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
503 callee()->CreateLocalVideoTrack();
504
505 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
506 callee()->AddTrack(callee_track);
507 caller()->CreateAndSetAndSignalOffer();
508 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
509
510 // Remove send video (i.e., caller sender track).
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000511 caller()->pc()->RemoveTrackOrError(caller_sender);
Johannes Kron3e983682020-03-29 22:17:00 +0200512
513 caller()->CreateAndSetAndSignalOffer();
514 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
515
516 // Expect one-directional video.
517 MediaExpectations media_expectations;
518 media_expectations.CalleeExpectsNoVideo();
519 media_expectations.CallerExpectsSomeVideo();
520
521 ASSERT_TRUE(ExpectNewFrames(media_expectations));
522}
523
deadbeef1dcb1642017-03-29 21:08:16 -0700524// This test sets up a audio call initially, with the callee rejecting video
525// initially. Then later the callee decides to upgrade to audio/video, and
526// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800527TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -0700528 ASSERT_TRUE(CreatePeerConnectionWrappers());
529 ConnectFakeSignaling();
530 // Initially, offer an audio/video stream from the caller, but refuse to
531 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -0800532 caller()->AddAudioVideoTracks();
533 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800534 if (sdp_semantics_ == SdpSemantics::kPlanB) {
535 PeerConnectionInterface::RTCOfferAnswerOptions options;
536 options.offer_to_receive_video = 0;
537 callee()->SetOfferAnswerOptions(options);
538 } else {
539 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200540 callee()
541 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
542 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800543 });
544 }
deadbeef1dcb1642017-03-29 21:08:16 -0700545 // Do offer/answer and make sure audio is still received end-to-end.
546 caller()->CreateAndSetAndSignalOffer();
547 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800548 {
549 MediaExpectations media_expectations;
550 media_expectations.ExpectBidirectionalAudio();
551 media_expectations.ExpectNoVideo();
552 ASSERT_TRUE(ExpectNewFrames(media_expectations));
553 }
deadbeef1dcb1642017-03-29 21:08:16 -0700554 // Sanity check that the callee's description has a rejected video section.
555 ASSERT_NE(nullptr, callee()->pc()->local_description());
556 const ContentInfo* callee_video_content =
557 GetFirstVideoContent(callee()->pc()->local_description()->description());
558 ASSERT_NE(nullptr, callee_video_content);
559 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800560
deadbeef1dcb1642017-03-29 21:08:16 -0700561 // Now negotiate with video and ensure negotiation succeeds, with video
562 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -0800563 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800564 if (sdp_semantics_ == SdpSemantics::kPlanB) {
565 PeerConnectionInterface::RTCOfferAnswerOptions options;
566 options.offer_to_receive_video = 1;
567 callee()->SetOfferAnswerOptions(options);
568 } else {
569 callee()->SetRemoteOfferHandler(nullptr);
570 caller()->SetRemoteOfferHandler([this] {
571 // The caller creates a new transceiver to receive video on when receiving
572 // the offer, but by default it is send only.
573 auto transceivers = caller()->pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +0200574 ASSERT_EQ(2U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800575 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
Harald Alvestrand6060df52020-08-11 09:54:02 +0200576 transceivers[1]->receiver()->media_type());
577 transceivers[1]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
578 transceivers[1]->SetDirectionWithError(
579 RtpTransceiverDirection::kSendRecv);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800580 });
581 }
deadbeef1dcb1642017-03-29 21:08:16 -0700582 callee()->CreateAndSetAndSignalOffer();
583 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800584 {
585 // Expect additional audio frames to be received after the upgrade.
586 MediaExpectations media_expectations;
587 media_expectations.ExpectBidirectionalAudioAndVideo();
588 ASSERT_TRUE(ExpectNewFrames(media_expectations));
589 }
deadbeef1dcb1642017-03-29 21:08:16 -0700590}
591
deadbeef4389b4d2017-09-07 09:07:36 -0700592// Simpler than the above test; just add an audio track to an established
593// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800594TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -0700595 ASSERT_TRUE(CreatePeerConnectionWrappers());
596 ConnectFakeSignaling();
597 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -0800598 caller()->AddVideoTrack();
599 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700600 caller()->CreateAndSetAndSignalOffer();
601 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
602 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -0800603 caller()->AddAudioTrack();
604 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700605 caller()->CreateAndSetAndSignalOffer();
606 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
607 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800608 MediaExpectations media_expectations;
609 media_expectations.ExpectBidirectionalAudioAndVideo();
610 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -0700611}
612
deadbeef1dcb1642017-03-29 21:08:16 -0700613// This test sets up a call that's transferred to a new caller with a different
614// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800615TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -0700616 ASSERT_TRUE(CreatePeerConnectionWrappers());
617 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800618 caller()->AddAudioVideoTracks();
619 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700620 caller()->CreateAndSetAndSignalOffer();
621 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
622
623 // Keep the original peer around which will still send packets to the
624 // receiving client. These SRTP packets will be dropped.
Harald Alvestrand39993842021-02-17 09:05:31 +0000625 std::unique_ptr<PeerConnectionIntegrationWrapper> original_peer(
deadbeef1dcb1642017-03-29 21:08:16 -0700626 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -0800627 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -0700628 // TODO(deadbeef): Why do we call Close here? That goes against the comment
629 // directly above.
630 original_peer->pc()->Close();
631
632 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800633 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700634 caller()->CreateAndSetAndSignalOffer();
635 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
636 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800637 MediaExpectations media_expectations;
638 media_expectations.ExpectBidirectionalAudioAndVideo();
639 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700640}
641
642// This test sets up a call that's transferred to a new callee with a different
643// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800644TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -0700645 ASSERT_TRUE(CreatePeerConnectionWrappers());
646 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800647 caller()->AddAudioVideoTracks();
648 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700649 caller()->CreateAndSetAndSignalOffer();
650 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
651
652 // Keep the original peer around which will still send packets to the
653 // receiving client. These SRTP packets will be dropped.
Harald Alvestrand39993842021-02-17 09:05:31 +0000654 std::unique_ptr<PeerConnectionIntegrationWrapper> original_peer(
deadbeef1dcb1642017-03-29 21:08:16 -0700655 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -0800656 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -0700657 // TODO(deadbeef): Why do we call Close here? That goes against the comment
658 // directly above.
659 original_peer->pc()->Close();
660
661 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800662 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700663 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
664 caller()->CreateAndSetAndSignalOffer();
665 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
666 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800667 MediaExpectations media_expectations;
668 media_expectations.ExpectBidirectionalAudioAndVideo();
669 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700670}
671
672// This test sets up a non-bundled call and negotiates bundling at the same
673// time as starting an ICE restart. When bundling is in effect in the restart,
674// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800675TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -0700676 ASSERT_TRUE(CreatePeerConnectionWrappers());
677 ConnectFakeSignaling();
678
Steve Anton15324772018-01-16 10:26:49 -0800679 caller()->AddAudioVideoTracks();
680 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700681 // Remove the bundle group from the SDP received by the callee.
682 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
683 desc->RemoveGroupByName("BUNDLE");
684 });
685 caller()->CreateAndSetAndSignalOffer();
686 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800687 {
688 MediaExpectations media_expectations;
689 media_expectations.ExpectBidirectionalAudioAndVideo();
690 ASSERT_TRUE(ExpectNewFrames(media_expectations));
691 }
deadbeef1dcb1642017-03-29 21:08:16 -0700692 // Now stop removing the BUNDLE group, and trigger an ICE restart.
693 callee()->SetReceivedSdpMunger(nullptr);
694 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
695 caller()->CreateAndSetAndSignalOffer();
696 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
697
698 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800699 {
700 MediaExpectations media_expectations;
701 media_expectations.ExpectBidirectionalAudioAndVideo();
702 ASSERT_TRUE(ExpectNewFrames(media_expectations));
703 }
deadbeef1dcb1642017-03-29 21:08:16 -0700704}
705
706// Test CVO (Coordination of Video Orientation). If a video source is rotated
707// and both peers support the CVO RTP header extension, the actual video frames
708// don't need to be encoded in different resolutions, since the rotation is
709// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800710TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700711 ASSERT_TRUE(CreatePeerConnectionWrappers());
712 ConnectFakeSignaling();
713 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800714 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700715 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800716 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700717 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
718
719 // Wait for video frames to be received by both sides.
720 caller()->CreateAndSetAndSignalOffer();
721 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
722 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
723 callee()->min_video_frames_received_per_track() > 0,
724 kMaxWaitForFramesMs);
725
726 // Ensure that the aspect ratio is unmodified.
727 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
728 // not just assumed.
729 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
730 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
731 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
732 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
733 // Ensure that the CVO bits were surfaced to the renderer.
734 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
735 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
736}
737
738// Test that when the CVO extension isn't supported, video is rotated the
739// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800740TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700741 ASSERT_TRUE(CreatePeerConnectionWrappers());
742 ConnectFakeSignaling();
743 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800744 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700745 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800746 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700747 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
748
749 // Remove the CVO extension from the offered SDP.
750 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
751 cricket::VideoContentDescription* video =
752 GetFirstVideoContentDescription(desc);
753 video->ClearRtpHeaderExtensions();
754 });
755 // Wait for video frames to be received by both sides.
756 caller()->CreateAndSetAndSignalOffer();
757 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
758 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
759 callee()->min_video_frames_received_per_track() > 0,
760 kMaxWaitForFramesMs);
761
762 // Expect that the aspect ratio is inversed to account for the 90/270 degree
763 // rotation.
764 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
765 // not just assumed.
766 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
767 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
768 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
769 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
770 // Expect that each endpoint is unaware of the rotation of the other endpoint.
771 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
772 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
773}
774
deadbeef1dcb1642017-03-29 21:08:16 -0700775// Test that if the answerer rejects the audio m= section, no audio is sent or
776// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800777TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700778 ASSERT_TRUE(CreatePeerConnectionWrappers());
779 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800780 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800781 if (sdp_semantics_ == SdpSemantics::kPlanB) {
782 // Only add video track for callee, and set offer_to_receive_audio to 0, so
783 // it will reject the audio m= section completely.
784 PeerConnectionInterface::RTCOfferAnswerOptions options;
785 options.offer_to_receive_audio = 0;
786 callee()->SetOfferAnswerOptions(options);
787 } else {
788 // Stopping the audio RtpTransceiver will cause the media section to be
789 // rejected in the answer.
790 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200791 callee()
792 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
793 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800794 });
795 }
Steve Anton15324772018-01-16 10:26:49 -0800796 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700797 // Do offer/answer and wait for successful end-to-end video frames.
798 caller()->CreateAndSetAndSignalOffer();
799 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800800 MediaExpectations media_expectations;
801 media_expectations.ExpectBidirectionalVideo();
802 media_expectations.ExpectNoAudio();
803 ASSERT_TRUE(ExpectNewFrames(media_expectations));
804
deadbeef1dcb1642017-03-29 21:08:16 -0700805 // Sanity check that the callee's description has a rejected audio section.
806 ASSERT_NE(nullptr, callee()->pc()->local_description());
807 const ContentInfo* callee_audio_content =
808 GetFirstAudioContent(callee()->pc()->local_description()->description());
809 ASSERT_NE(nullptr, callee_audio_content);
810 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800811 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200812 // The caller's transceiver should have stopped after receiving the answer,
813 // and thus no longer listed in transceivers.
814 EXPECT_EQ(nullptr,
815 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800816 }
deadbeef1dcb1642017-03-29 21:08:16 -0700817}
818
819// Test that if the answerer rejects the video m= section, no video is sent or
820// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800821TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700822 ASSERT_TRUE(CreatePeerConnectionWrappers());
823 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800824 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800825 if (sdp_semantics_ == SdpSemantics::kPlanB) {
826 // Only add audio track for callee, and set offer_to_receive_video to 0, so
827 // it will reject the video m= section completely.
828 PeerConnectionInterface::RTCOfferAnswerOptions options;
829 options.offer_to_receive_video = 0;
830 callee()->SetOfferAnswerOptions(options);
831 } else {
832 // Stopping the video RtpTransceiver will cause the media section to be
833 // rejected in the answer.
834 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200835 callee()
836 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
837 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800838 });
839 }
Steve Anton15324772018-01-16 10:26:49 -0800840 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700841 // Do offer/answer and wait for successful end-to-end audio frames.
842 caller()->CreateAndSetAndSignalOffer();
843 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800844 MediaExpectations media_expectations;
845 media_expectations.ExpectBidirectionalAudio();
846 media_expectations.ExpectNoVideo();
847 ASSERT_TRUE(ExpectNewFrames(media_expectations));
848
deadbeef1dcb1642017-03-29 21:08:16 -0700849 // Sanity check that the callee's description has a rejected video section.
850 ASSERT_NE(nullptr, callee()->pc()->local_description());
851 const ContentInfo* callee_video_content =
852 GetFirstVideoContent(callee()->pc()->local_description()->description());
853 ASSERT_NE(nullptr, callee_video_content);
854 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800855 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200856 // The caller's transceiver should have stopped after receiving the answer,
857 // and thus is no longer present.
858 EXPECT_EQ(nullptr,
859 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800860 }
deadbeef1dcb1642017-03-29 21:08:16 -0700861}
862
863// Test that if the answerer rejects both audio and video m= sections, nothing
864// bad happens.
865// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
866// test anything but the fact that negotiation succeeds, which doesn't mean
867// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800868TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -0700869 ASSERT_TRUE(CreatePeerConnectionWrappers());
870 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800871 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800872 if (sdp_semantics_ == SdpSemantics::kPlanB) {
873 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
874 // will reject both audio and video m= sections.
875 PeerConnectionInterface::RTCOfferAnswerOptions options;
876 options.offer_to_receive_audio = 0;
877 options.offer_to_receive_video = 0;
878 callee()->SetOfferAnswerOptions(options);
879 } else {
880 callee()->SetRemoteOfferHandler([this] {
881 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +0100882 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200883 transceiver->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800884 }
885 });
886 }
deadbeef1dcb1642017-03-29 21:08:16 -0700887 // Do offer/answer and wait for stable signaling state.
888 caller()->CreateAndSetAndSignalOffer();
889 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800890
deadbeef1dcb1642017-03-29 21:08:16 -0700891 // Sanity check that the callee's description has rejected m= sections.
892 ASSERT_NE(nullptr, callee()->pc()->local_description());
893 const ContentInfo* callee_audio_content =
894 GetFirstAudioContent(callee()->pc()->local_description()->description());
895 ASSERT_NE(nullptr, callee_audio_content);
896 EXPECT_TRUE(callee_audio_content->rejected);
897 const ContentInfo* callee_video_content =
898 GetFirstVideoContent(callee()->pc()->local_description()->description());
899 ASSERT_NE(nullptr, callee_video_content);
900 EXPECT_TRUE(callee_video_content->rejected);
901}
902
903// This test sets up an audio and video call between two parties. After the
904// call runs for a while, the caller sends an updated offer with video being
905// rejected. Once the re-negotiation is done, the video flow should stop and
906// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800907TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700908 ASSERT_TRUE(CreatePeerConnectionWrappers());
909 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800910 caller()->AddAudioVideoTracks();
911 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700912 caller()->CreateAndSetAndSignalOffer();
913 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800914 {
915 MediaExpectations media_expectations;
916 media_expectations.ExpectBidirectionalAudioAndVideo();
917 ASSERT_TRUE(ExpectNewFrames(media_expectations));
918 }
deadbeef1dcb1642017-03-29 21:08:16 -0700919 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800920 if (sdp_semantics_ == SdpSemantics::kPlanB) {
921 caller()->SetGeneratedSdpMunger(
922 [](cricket::SessionDescription* description) {
923 for (cricket::ContentInfo& content : description->contents()) {
924 if (cricket::IsVideoContent(&content)) {
925 content.rejected = true;
926 }
927 }
928 });
929 } else {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200930 caller()
931 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
932 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800933 }
deadbeef1dcb1642017-03-29 21:08:16 -0700934 caller()->CreateAndSetAndSignalOffer();
935 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
936
937 // Sanity check that the caller's description has a rejected video section.
938 ASSERT_NE(nullptr, caller()->pc()->local_description());
939 const ContentInfo* caller_video_content =
940 GetFirstVideoContent(caller()->pc()->local_description()->description());
941 ASSERT_NE(nullptr, caller_video_content);
942 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -0700943 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800944 {
945 MediaExpectations media_expectations;
946 media_expectations.ExpectBidirectionalAudio();
947 media_expectations.ExpectNoVideo();
948 ASSERT_TRUE(ExpectNewFrames(media_expectations));
949 }
deadbeef1dcb1642017-03-29 21:08:16 -0700950}
951
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700952// Do one offer/answer with audio, another that disables it (rejecting the m=
953// section), and another that re-enables it. Regression test for:
954// bugs.webrtc.org/6023
955TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
956 ASSERT_TRUE(CreatePeerConnectionWrappers());
957 ConnectFakeSignaling();
958
959 // Add audio track, do normal offer/answer.
960 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
961 caller()->CreateLocalAudioTrack();
962 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
963 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
964 caller()->CreateAndSetAndSignalOffer();
965 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
966
967 // Remove audio track, and set offer_to_receive_audio to false to cause the
968 // m= section to be completely disabled, not just "recvonly".
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000969 caller()->pc()->RemoveTrackOrError(sender);
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700970 PeerConnectionInterface::RTCOfferAnswerOptions options;
971 options.offer_to_receive_audio = 0;
972 caller()->SetOfferAnswerOptions(options);
973 caller()->CreateAndSetAndSignalOffer();
974 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
975
976 // Add the audio track again, expecting negotiation to succeed and frames to
977 // flow.
978 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
979 options.offer_to_receive_audio = 1;
980 caller()->SetOfferAnswerOptions(options);
981 caller()->CreateAndSetAndSignalOffer();
982 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
983
984 MediaExpectations media_expectations;
985 media_expectations.CalleeExpectsSomeAudio();
986 EXPECT_TRUE(ExpectNewFrames(media_expectations));
987}
988
deadbeef1dcb1642017-03-29 21:08:16 -0700989// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
990// is needed to support legacy endpoints.
991// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
992// add a test for an end-to-end test without MID signaling either (basically,
993// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800994TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -0700995 ASSERT_TRUE(CreatePeerConnectionWrappers());
996 ConnectFakeSignaling();
997 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -0800998 caller()->AddAudioVideoTracks();
999 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07001000 // Remove SSRCs and MSIDs from the received offer SDP.
1001 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07001002 caller()->CreateAndSetAndSignalOffer();
1003 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001004 MediaExpectations media_expectations;
1005 media_expectations.ExpectBidirectionalAudioAndVideo();
1006 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001007}
1008
Seth Hampson5897a6e2018-04-03 11:16:33 -07001009// Basic end-to-end test, without SSRC signaling. This means that the track
1010// was created properly and frames are delivered when the MSIDs are communicated
1011// with a=msid lines and no a=ssrc lines.
1012TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1013 EndToEndCallWithoutSsrcSignaling) {
1014 const char kStreamId[] = "streamId";
1015 ASSERT_TRUE(CreatePeerConnectionWrappers());
1016 ConnectFakeSignaling();
1017 // Add just audio tracks.
1018 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
1019 callee()->AddAudioTrack();
1020
1021 // Remove SSRCs from the received offer SDP.
1022 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
1023 caller()->CreateAndSetAndSignalOffer();
1024 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1025 MediaExpectations media_expectations;
1026 media_expectations.ExpectBidirectionalAudio();
1027 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1028}
1029
Johannes Kron3e983682020-03-29 22:17:00 +02001030TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1031 EndToEndCallAddReceiveVideoToSendOnlyCall) {
1032 ASSERT_TRUE(CreatePeerConnectionWrappers());
1033 ConnectFakeSignaling();
1034 // Add one-directional video, from caller to callee.
1035 rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
1036 caller()->CreateLocalVideoTrack();
1037
1038 RtpTransceiverInit video_transceiver_init;
1039 video_transceiver_init.stream_ids = {"video1"};
1040 video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly;
1041 auto video_sender =
1042 caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue();
1043 caller()->CreateAndSetAndSignalOffer();
1044 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1045
1046 // Add receive direction.
Harald Alvestrand6060df52020-08-11 09:54:02 +02001047 video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);
Johannes Kron3e983682020-03-29 22:17:00 +02001048
1049 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
1050 callee()->CreateLocalVideoTrack();
1051
1052 callee()->AddTrack(callee_track);
1053 caller()->CreateAndSetAndSignalOffer();
1054 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1055 // Ensure that video frames are received end-to-end.
1056 MediaExpectations media_expectations;
1057 media_expectations.ExpectBidirectionalVideo();
1058 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1059}
1060
Steve Antondf527fd2018-04-27 15:52:03 -07001061// Tests that video flows between multiple video tracks when SSRCs are not
1062// signaled. This exercises the MID RTP header extension which is needed to
1063// demux the incoming video tracks.
1064TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1065 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
1066 ASSERT_TRUE(CreatePeerConnectionWrappers());
1067 ConnectFakeSignaling();
1068 caller()->AddVideoTrack();
1069 caller()->AddVideoTrack();
1070 callee()->AddVideoTrack();
1071 callee()->AddVideoTrack();
1072
1073 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1074 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1075 caller()->CreateAndSetAndSignalOffer();
1076 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1077 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1078 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1079
1080 // Expect video to be received in both directions on both tracks.
1081 MediaExpectations media_expectations;
1082 media_expectations.ExpectBidirectionalVideo();
1083 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1084}
1085
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -07001086// Used for the test below.
1087void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
1088 RemoveSsrcsAndKeepMsids(desc);
1089 desc->RemoveGroupByName("BUNDLE");
1090 for (ContentInfo& content : desc->contents()) {
1091 cricket::MediaContentDescription* media = content.media_description();
1092 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1093 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1094 [](const RtpExtension& extension) {
1095 return extension.uri ==
1096 RtpExtension::kMidUri;
1097 }),
1098 extensions.end());
1099 media->set_rtp_header_extensions(extensions);
1100 }
1101}
1102
1103// Tests that video flows between multiple video tracks when BUNDLE is not used,
1104// SSRCs are not signaled and the MID RTP header extension is not used. This
1105// relies on demuxing by payload type, which normally doesn't work if you have
1106// multiple media sections using the same payload type, but which should work as
1107// long as the media sections aren't bundled.
1108// Regression test for: http://crbug.com/webrtc/12023
1109TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1110 EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid) {
1111 ASSERT_TRUE(CreatePeerConnectionWrappers());
1112 ConnectFakeSignaling();
1113 caller()->AddVideoTrack();
1114 caller()->AddVideoTrack();
1115 callee()->AddVideoTrack();
1116 callee()->AddVideoTrack();
1117 caller()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1118 callee()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1119 caller()->CreateAndSetAndSignalOffer();
1120 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1121 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1122 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1123 // Make sure we are not bundled.
1124 ASSERT_NE(caller()->pc()->GetSenders()[0]->dtls_transport(),
1125 caller()->pc()->GetSenders()[1]->dtls_transport());
1126
1127 // Expect video to be received in both directions on both tracks.
1128 MediaExpectations media_expectations;
1129 media_expectations.ExpectBidirectionalVideo();
1130 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1131}
1132
1133// Used for the test below.
1134void ModifyPayloadTypesAndRemoveMidExtension(
1135 cricket::SessionDescription* desc) {
1136 int pt = 96;
1137 for (ContentInfo& content : desc->contents()) {
1138 cricket::MediaContentDescription* media = content.media_description();
1139 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1140 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1141 [](const RtpExtension& extension) {
1142 return extension.uri ==
1143 RtpExtension::kMidUri;
1144 }),
1145 extensions.end());
1146 media->set_rtp_header_extensions(extensions);
1147 cricket::VideoContentDescription* video = media->as_video();
1148 ASSERT_TRUE(video != nullptr);
1149 std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
1150 video->set_codecs(codecs);
1151 }
1152}
1153
1154// Tests that two video tracks can be demultiplexed by payload type alone, by
1155// using different payload types for the same codec in different m= sections.
1156// This practice is discouraged but historically has been supported.
1157// Regression test for: http://crbug.com/webrtc/12029
1158TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1159 EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType) {
1160 ASSERT_TRUE(CreatePeerConnectionWrappers());
1161 ConnectFakeSignaling();
1162 caller()->AddVideoTrack();
1163 caller()->AddVideoTrack();
1164 callee()->AddVideoTrack();
1165 callee()->AddVideoTrack();
1166 caller()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1167 callee()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1168 // We can't remove SSRCs from the generated SDP because then no send streams
1169 // would be created.
1170 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1171 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1172 caller()->CreateAndSetAndSignalOffer();
1173 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1174 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1175 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1176 // Make sure we are bundled.
1177 ASSERT_EQ(caller()->pc()->GetSenders()[0]->dtls_transport(),
1178 caller()->pc()->GetSenders()[1]->dtls_transport());
1179
1180 // Expect video to be received in both directions on both tracks.
1181 MediaExpectations media_expectations;
1182 media_expectations.ExpectBidirectionalVideo();
1183 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1184}
1185
Henrik Boström5b147782018-12-04 11:25:05 +01001186TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
1187 ASSERT_TRUE(CreatePeerConnectionWrappers());
1188 ConnectFakeSignaling();
1189 caller()->AddAudioTrack();
1190 caller()->AddVideoTrack();
1191 caller()->CreateAndSetAndSignalOffer();
1192 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1193 auto callee_receivers = callee()->pc()->GetReceivers();
1194 ASSERT_EQ(2u, callee_receivers.size());
1195 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
1196 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
1197}
1198
1199TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
1200 ASSERT_TRUE(CreatePeerConnectionWrappers());
1201 ConnectFakeSignaling();
1202 caller()->AddAudioTrack();
1203 caller()->AddVideoTrack();
1204 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1205 caller()->CreateAndSetAndSignalOffer();
1206 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1207 auto callee_receivers = callee()->pc()->GetReceivers();
1208 ASSERT_EQ(2u, callee_receivers.size());
1209 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
1210 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
1211 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
1212 callee_receivers[1]->stream_ids()[0]);
1213 EXPECT_EQ(callee_receivers[0]->streams()[0],
1214 callee_receivers[1]->streams()[0]);
1215}
1216
deadbeef1dcb1642017-03-29 21:08:16 -07001217// Test that if two video tracks are sent (from caller to callee, in this test),
1218// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001219TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07001220 ASSERT_TRUE(CreatePeerConnectionWrappers());
1221 ConnectFakeSignaling();
1222 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08001223 caller()->AddAudioVideoTracks();
1224 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001225 caller()->CreateAndSetAndSignalOffer();
1226 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08001227 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08001228
1229 MediaExpectations media_expectations;
1230 media_expectations.CalleeExpectsSomeAudioAndVideo();
1231 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001232}
1233
1234static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
1235 bool first = true;
1236 for (cricket::ContentInfo& content : desc->contents()) {
1237 if (first) {
1238 first = false;
1239 continue;
1240 }
1241 content.bundle_only = true;
1242 }
1243 first = true;
1244 for (cricket::TransportInfo& transport : desc->transport_infos()) {
1245 if (first) {
1246 first = false;
1247 continue;
1248 }
1249 transport.description.ice_ufrag.clear();
1250 transport.description.ice_pwd.clear();
1251 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
1252 transport.description.identity_fingerprint.reset(nullptr);
1253 }
1254}
1255
1256// Test that if applying a true "max bundle" offer, which uses ports of 0,
1257// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
1258// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
1259// successfully and media flows.
1260// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
1261// TODO(deadbeef): Won't need this test once we start generating actual
1262// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001263TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001264 EndToEndCallWithSpecCompliantMaxBundleOffer) {
1265 ASSERT_TRUE(CreatePeerConnectionWrappers());
1266 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001267 caller()->AddAudioVideoTracks();
1268 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001269 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
1270 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
1271 // but the first m= section.
1272 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
1273 caller()->CreateAndSetAndSignalOffer();
1274 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001275 MediaExpectations media_expectations;
1276 media_expectations.ExpectBidirectionalAudioAndVideo();
1277 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001278}
1279
1280// Test that we can receive the audio output level from a remote audio track.
1281// TODO(deadbeef): Use a fake audio source and verify that the output level is
1282// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001283TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001284 ASSERT_TRUE(CreatePeerConnectionWrappers());
1285 ConnectFakeSignaling();
1286 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001287 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001288 caller()->CreateAndSetAndSignalOffer();
1289 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1290
1291 // Get the audio output level stats. Note that the level is not available
1292 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07001293 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001294 kMaxWaitForFramesMs);
1295}
1296
1297// Test that an audio input level is reported.
1298// TODO(deadbeef): Use a fake audio source and verify that the input level is
1299// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001300TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001301 ASSERT_TRUE(CreatePeerConnectionWrappers());
1302 ConnectFakeSignaling();
1303 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001304 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001305 caller()->CreateAndSetAndSignalOffer();
1306 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1307
1308 // Get the audio input level stats. The level should be available very
1309 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07001310 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001311 kMaxWaitForStatsMs);
1312}
1313
1314// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001315TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001316 ASSERT_TRUE(CreatePeerConnectionWrappers());
1317 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001318 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001319 // Do offer/answer, wait for the callee to receive some frames.
1320 caller()->CreateAndSetAndSignalOffer();
1321 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001322
1323 MediaExpectations media_expectations;
1324 media_expectations.CalleeExpectsSomeAudioAndVideo();
1325 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001326
1327 // Get a handle to the remote tracks created, so they can be used as GetStats
1328 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01001329 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08001330 // We received frames, so we definitely should have nonzero "received bytes"
1331 // stats at this point.
1332 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
1333 0);
1334 }
deadbeef1dcb1642017-03-29 21:08:16 -07001335}
1336
1337// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001338TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001339 ASSERT_TRUE(CreatePeerConnectionWrappers());
1340 ConnectFakeSignaling();
1341 auto audio_track = caller()->CreateLocalAudioTrack();
1342 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08001343 caller()->AddTrack(audio_track);
1344 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07001345 // Do offer/answer, wait for the callee to receive some frames.
1346 caller()->CreateAndSetAndSignalOffer();
1347 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001348 MediaExpectations media_expectations;
1349 media_expectations.CalleeExpectsSomeAudioAndVideo();
1350 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001351
1352 // The callee received frames, so we definitely should have nonzero "sent
1353 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07001354 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
1355 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
1356}
1357
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001358// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001359TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001360 ASSERT_TRUE(CreatePeerConnectionWrappers());
1361 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001362 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001363
Steve Anton15324772018-01-16 10:26:49 -08001364 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001365
1366 // Do offer/answer, wait for the callee to receive some frames.
1367 caller()->CreateAndSetAndSignalOffer();
1368 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1369
1370 // Get the remote audio track created on the receiver, so they can be used as
1371 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08001372 auto receivers = callee()->pc()->GetReceivers();
1373 ASSERT_EQ(1u, receivers.size());
1374 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001375
1376 // Get the audio output level stats. Note that the level is not available
1377 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07001378 EXPECT_TRUE_WAIT(
1379 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
1380 0,
1381 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001382}
1383
Steve Antona41959e2018-11-28 11:15:33 -08001384// Test that the track ID is associated with all local and remote SSRC stats
1385// using the old GetStats() and more than 1 audio and more than 1 video track.
1386// This is a regression test for crbug.com/906988
1387TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1388 OldGetStatsAssociatesTrackIdForManyMediaSections) {
1389 ASSERT_TRUE(CreatePeerConnectionWrappers());
1390 ConnectFakeSignaling();
1391 auto audio_sender_1 = caller()->AddAudioTrack();
1392 auto video_sender_1 = caller()->AddVideoTrack();
1393 auto audio_sender_2 = caller()->AddAudioTrack();
1394 auto video_sender_2 = caller()->AddVideoTrack();
1395 caller()->CreateAndSetAndSignalOffer();
1396 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1397
1398 MediaExpectations media_expectations;
1399 media_expectations.CalleeExpectsSomeAudioAndVideo();
1400 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1401
1402 std::vector<std::string> track_ids = {
1403 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1404 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1405
1406 auto caller_stats = caller()->OldGetStats();
1407 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1408 auto callee_stats = callee()->OldGetStats();
1409 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1410}
1411
Steve Antonffa6ce42018-11-30 09:26:08 -08001412// Test that the new GetStats() returns stats for all outgoing/incoming streams
1413// with the correct track IDs if there are more than one audio and more than one
1414// video senders/receivers.
1415TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
1416 ASSERT_TRUE(CreatePeerConnectionWrappers());
1417 ConnectFakeSignaling();
1418 auto audio_sender_1 = caller()->AddAudioTrack();
1419 auto video_sender_1 = caller()->AddVideoTrack();
1420 auto audio_sender_2 = caller()->AddAudioTrack();
1421 auto video_sender_2 = caller()->AddVideoTrack();
1422 caller()->CreateAndSetAndSignalOffer();
1423 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1424
1425 MediaExpectations media_expectations;
1426 media_expectations.CalleeExpectsSomeAudioAndVideo();
1427 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1428
1429 std::vector<std::string> track_ids = {
1430 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1431 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1432
1433 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
1434 caller()->NewGetStats();
1435 ASSERT_TRUE(caller_report);
1436 auto outbound_stream_stats =
1437 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
Henrik Boströma0ff50c2020-05-05 15:54:46 +02001438 ASSERT_EQ(outbound_stream_stats.size(), 4u);
Steve Antonffa6ce42018-11-30 09:26:08 -08001439 std::vector<std::string> outbound_track_ids;
1440 for (const auto& stat : outbound_stream_stats) {
1441 ASSERT_TRUE(stat->bytes_sent.is_defined());
1442 EXPECT_LT(0u, *stat->bytes_sent);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001443 if (*stat->kind == "video") {
1444 ASSERT_TRUE(stat->key_frames_encoded.is_defined());
1445 EXPECT_GT(*stat->key_frames_encoded, 0u);
1446 ASSERT_TRUE(stat->frames_encoded.is_defined());
1447 EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
1448 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001449 ASSERT_TRUE(stat->track_id.is_defined());
1450 const auto* track_stat =
1451 caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1452 ASSERT_TRUE(track_stat);
1453 outbound_track_ids.push_back(*track_stat->track_identifier);
1454 }
1455 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
1456
1457 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
1458 callee()->NewGetStats();
1459 ASSERT_TRUE(callee_report);
1460 auto inbound_stream_stats =
1461 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1462 ASSERT_EQ(4u, inbound_stream_stats.size());
1463 std::vector<std::string> inbound_track_ids;
1464 for (const auto& stat : inbound_stream_stats) {
1465 ASSERT_TRUE(stat->bytes_received.is_defined());
1466 EXPECT_LT(0u, *stat->bytes_received);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001467 if (*stat->kind == "video") {
1468 ASSERT_TRUE(stat->key_frames_decoded.is_defined());
1469 EXPECT_GT(*stat->key_frames_decoded, 0u);
1470 ASSERT_TRUE(stat->frames_decoded.is_defined());
1471 EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
1472 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001473 ASSERT_TRUE(stat->track_id.is_defined());
1474 const auto* track_stat =
1475 callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1476 ASSERT_TRUE(track_stat);
1477 inbound_track_ids.push_back(*track_stat->track_identifier);
1478 }
1479 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
1480}
1481
1482// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07001483// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
1484// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001485TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07001486 GetStatsForUnsignaledStreamWithNewStatsApi) {
1487 ASSERT_TRUE(CreatePeerConnectionWrappers());
1488 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001489 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07001490 // Remove SSRCs and MSIDs from the received offer SDP.
1491 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1492 caller()->CreateAndSetAndSignalOffer();
1493 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001494 MediaExpectations media_expectations;
1495 media_expectations.CalleeExpectsSomeAudio(1);
1496 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07001497
1498 // We received a frame, so we should have nonzero "bytes received" stats for
1499 // the unsignaled stream, if stats are working for it.
1500 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1501 callee()->NewGetStats();
1502 ASSERT_NE(nullptr, report);
1503 auto inbound_stream_stats =
1504 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1505 ASSERT_EQ(1U, inbound_stream_stats.size());
1506 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
1507 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07001508 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
1509}
1510
Taylor Brandstettera4653442018-06-19 09:44:26 -07001511// Same as above but for the legacy stats implementation.
1512TEST_P(PeerConnectionIntegrationTest,
1513 GetStatsForUnsignaledStreamWithOldStatsApi) {
1514 ASSERT_TRUE(CreatePeerConnectionWrappers());
1515 ConnectFakeSignaling();
1516 caller()->AddAudioTrack();
1517 // Remove SSRCs and MSIDs from the received offer SDP.
1518 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1519 caller()->CreateAndSetAndSignalOffer();
1520 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1521
1522 // Note that, since the old stats implementation associates SSRCs with tracks
1523 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
1524 // associated track ID. So we can't use the track "selector" argument.
1525 //
1526 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
1527 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001528 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07001529 kDefaultTimeout);
1530}
1531
zhihuangf8164932017-05-19 13:09:47 -07001532// Test that we can successfully get the media related stats (audio level
1533// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001534TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07001535 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
1536 ASSERT_TRUE(CreatePeerConnectionWrappers());
1537 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001538 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07001539 // Remove SSRCs and MSIDs from the received offer SDP.
1540 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1541 caller()->CreateAndSetAndSignalOffer();
1542 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001543 MediaExpectations media_expectations;
1544 media_expectations.CalleeExpectsSomeAudio(1);
1545 media_expectations.CalleeExpectsSomeVideo(1);
1546 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07001547
1548 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1549 callee()->NewGetStats();
1550 ASSERT_NE(nullptr, report);
1551
1552 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1553 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
1554 ASSERT_GE(audio_index, 0);
1555 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07001556}
1557
deadbeef4e2deab2017-09-20 13:56:21 -07001558// Helper for test below.
1559void ModifySsrcs(cricket::SessionDescription* desc) {
1560 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07001561 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08001562 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07001563 for (uint32_t& ssrc : stream.ssrcs) {
1564 ssrc = rtc::CreateRandomId();
1565 }
1566 }
1567 }
1568}
1569
1570// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
1571// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
1572// This should result in two "RTCInboundRTPStreamStats", but only one
1573// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
1574// being reset to 0 once the SSRC change occurs.
1575//
1576// Regression test for this bug:
1577// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
1578//
1579// The bug causes the track stats to only represent one of the two streams:
1580// whichever one has the higher SSRC. So with this bug, there was a 50% chance
1581// that the track stat counters would reset to 0 when the new stream is
1582// received, and a 50% chance that they'll stop updating (while
1583// "concealed_samples" continues increasing, due to silence being generated for
1584// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001585TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08001586 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07001587 ASSERT_TRUE(CreatePeerConnectionWrappers());
1588 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001589 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07001590 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
1591 // that doesn't signal SSRCs (from the callee's perspective).
1592 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1593 caller()->CreateAndSetAndSignalOffer();
1594 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1595 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001596 {
1597 MediaExpectations media_expectations;
1598 media_expectations.CalleeExpectsSomeAudio(50);
1599 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1600 }
deadbeef4e2deab2017-09-20 13:56:21 -07001601 // Some audio frames were received, so we should have nonzero "samples
1602 // received" for the track.
1603 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1604 callee()->NewGetStats();
1605 ASSERT_NE(nullptr, report);
1606 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1607 ASSERT_EQ(1U, track_stats.size());
1608 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1609 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
1610 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
1611
1612 // Create a new offer and munge it to cause the caller to use a new SSRC.
1613 caller()->SetGeneratedSdpMunger(ModifySsrcs);
1614 caller()->CreateAndSetAndSignalOffer();
1615 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1616 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
1617 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001618 {
1619 MediaExpectations media_expectations;
1620 media_expectations.CalleeExpectsSomeAudio(25);
1621 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1622 }
deadbeef4e2deab2017-09-20 13:56:21 -07001623
1624 report = callee()->NewGetStats();
1625 ASSERT_NE(nullptr, report);
1626 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1627 ASSERT_EQ(1U, track_stats.size());
1628 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1629 // The "total samples received" stat should only be greater than it was
1630 // before.
1631 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
1632 // Right now, the new SSRC will cause the counters to reset to 0.
1633 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
1634
1635 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08001636 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07001637 // good sign that we're seeing stats from the old stream that's no longer
1638 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08001639 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07001640 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
1641 EXPECT_LT(*track_stats[0]->concealed_samples,
1642 *track_stats[0]->total_samples_received *
1643 kAcceptableConcealedSamplesPercentage);
1644
1645 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
1646 // sanity check that the SSRC really changed.
1647 // TODO(deadbeef): This isn't working right now, because we're not returning
1648 // *any* stats for the inactive stream. Uncomment when the bug is completely
1649 // fixed.
1650 // auto inbound_stream_stats =
1651 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1652 // ASSERT_EQ(2U, inbound_stream_stats.size());
1653}
1654
deadbeef1dcb1642017-03-29 21:08:16 -07001655// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001656TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001657 PeerConnectionFactory::Options dtls_10_options;
1658 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1659 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1660 dtls_10_options));
1661 ConnectFakeSignaling();
1662 // Do normal offer/answer and wait for some frames to be received in each
1663 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001664 caller()->AddAudioVideoTracks();
1665 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001666 caller()->CreateAndSetAndSignalOffer();
1667 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001668 MediaExpectations media_expectations;
1669 media_expectations.ExpectBidirectionalAudioAndVideo();
1670 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001671}
1672
1673// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001674TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001675 PeerConnectionFactory::Options dtls_10_options;
1676 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1677 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1678 dtls_10_options));
1679 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001680 caller()->AddAudioVideoTracks();
1681 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001682 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001683 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001684 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001685 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001686 kDefaultTimeout);
1687 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001688 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001689 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001690 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1691 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1692 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001693}
1694
1695// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001696TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001697 PeerConnectionFactory::Options dtls_12_options;
1698 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1699 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
1700 dtls_12_options));
1701 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001702 caller()->AddAudioVideoTracks();
1703 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001704 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001705 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001706 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001707 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001708 kDefaultTimeout);
1709 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001710 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001711 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001712 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1713 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1714 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001715}
1716
1717// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
1718// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001719TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001720 PeerConnectionFactory::Options caller_options;
1721 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1722 PeerConnectionFactory::Options callee_options;
1723 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1724 ASSERT_TRUE(
1725 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1726 ConnectFakeSignaling();
1727 // Do normal offer/answer and wait for some frames to be received in each
1728 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001729 caller()->AddAudioVideoTracks();
1730 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001731 caller()->CreateAndSetAndSignalOffer();
1732 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001733 MediaExpectations media_expectations;
1734 media_expectations.ExpectBidirectionalAudioAndVideo();
1735 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001736}
1737
1738// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
1739// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001740TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07001741 PeerConnectionFactory::Options caller_options;
1742 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1743 PeerConnectionFactory::Options callee_options;
1744 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1745 ASSERT_TRUE(
1746 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1747 ConnectFakeSignaling();
1748 // Do normal offer/answer and wait for some frames to be received in each
1749 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001750 caller()->AddAudioVideoTracks();
1751 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001752 caller()->CreateAndSetAndSignalOffer();
1753 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001754 MediaExpectations media_expectations;
1755 media_expectations.ExpectBidirectionalAudioAndVideo();
1756 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001757}
1758
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001759// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
1760// works as expected; the cipher should only be used if enabled by both sides.
1761TEST_P(PeerConnectionIntegrationTest,
1762 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
1763 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001764 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001765 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001766 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1767 false;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001768 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001769 TestNegotiatedCipherSuite(caller_options, callee_options,
1770 expected_cipher_suite);
1771}
1772
1773TEST_P(PeerConnectionIntegrationTest,
1774 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
1775 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001776 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1777 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001778 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001779 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001780 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001781 TestNegotiatedCipherSuite(caller_options, callee_options,
1782 expected_cipher_suite);
1783}
1784
1785TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
1786 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001787 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001788 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001789 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001790 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_32;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001791 TestNegotiatedCipherSuite(caller_options, callee_options,
1792 expected_cipher_suite);
1793}
1794
deadbeef1dcb1642017-03-29 21:08:16 -07001795// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001796TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001797 bool local_gcm_enabled = false;
1798 bool remote_gcm_enabled = false;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001799 bool aes_ctr_enabled = true;
deadbeef1dcb1642017-03-29 21:08:16 -07001800 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
1801 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001802 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001803}
1804
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001805// Test that a GCM cipher is used if both ends support it and non-GCM is
1806// disabled.
1807TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001808 bool local_gcm_enabled = true;
1809 bool remote_gcm_enabled = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001810 bool aes_ctr_enabled = false;
deadbeef1dcb1642017-03-29 21:08:16 -07001811 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
1812 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001813 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001814}
1815
deadbeef7914b8c2017-04-21 03:23:33 -07001816// Verify that media can be transmitted end-to-end when GCM crypto suites are
1817// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
1818// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
1819// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001820TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07001821 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001822 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001823 gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false;
deadbeef7914b8c2017-04-21 03:23:33 -07001824 ASSERT_TRUE(
1825 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
1826 ConnectFakeSignaling();
1827 // Do normal offer/answer and wait for some frames to be received in each
1828 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001829 caller()->AddAudioVideoTracks();
1830 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07001831 caller()->CreateAndSetAndSignalOffer();
1832 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001833 MediaExpectations media_expectations;
1834 media_expectations.ExpectBidirectionalAudioAndVideo();
1835 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07001836}
1837
deadbeef1dcb1642017-03-29 21:08:16 -07001838// Test that the ICE connection and gathering states eventually reach
1839// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08001840TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07001841 ASSERT_TRUE(CreatePeerConnectionWrappers());
1842 ConnectFakeSignaling();
1843 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001844 caller()->AddAudioVideoTracks();
1845 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001846 caller()->CreateAndSetAndSignalOffer();
1847 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1848 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1849 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
1850 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1851 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
1852 // After the best candidate pair is selected and all candidates are signaled,
1853 // the ICE connection state should reach "complete".
1854 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
1855 // answerer/"callee" by default) only reaches "connected". When this is
1856 // fixed, this test should be updated.
1857 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1858 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00001859 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1860 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001861}
1862
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001863#if !defined(THREAD_SANITIZER)
1864// This test provokes TSAN errors. See bugs.webrtc.org/3608
1865
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001866constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
1867 cricket::PORTALLOCATOR_DISABLE_RELAY |
1868 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001869
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001870// Use a mock resolver to resolve the hostname back to the original IP on both
1871// sides and check that the ICE connection connects.
Markus Handell56910532021-04-10 11:23:14 +00001872// TODO(bugs.webrtc.org/12590): Flaky on Windows and on Linux MSAN.
1873#if defined(WEBRTC_WIN) || defined(WEBRTC_LINUX)
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001874#define MAYBE_IceStatesReachCompletionWithRemoteHostname \
1875 DISABLED_IceStatesReachCompletionWithRemoteHostname
1876#else
1877#define MAYBE_IceStatesReachCompletionWithRemoteHostname \
1878 IceStatesReachCompletionWithRemoteHostname
1879#endif
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001880TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001881 MAYBE_IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001882 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001883 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001884 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001885 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001886 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
1887 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001888
1889 // This also verifies that the injected AsyncResolverFactory is used by
1890 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001891 EXPECT_CALL(*caller_resolver_factory, Create())
1892 .WillOnce(Return(&caller_async_resolver));
1893 webrtc::PeerConnectionDependencies caller_deps(nullptr);
1894 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
1895
1896 EXPECT_CALL(*callee_resolver_factory, Create())
1897 .WillOnce(Return(&callee_async_resolver));
1898 webrtc::PeerConnectionDependencies callee_deps(nullptr);
1899 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
1900
1901 PeerConnectionInterface::RTCConfiguration config;
1902 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
1903 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
1904
1905 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
1906 config, std::move(caller_deps), config, std::move(callee_deps)));
1907
1908 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
1909 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
1910
1911 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07001912 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001913 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07001914 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001915 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001916
1917 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001918
1919 ConnectFakeSignaling();
1920 caller()->AddAudioVideoTracks();
1921 callee()->AddAudioVideoTracks();
1922 caller()->CreateAndSetAndSignalOffer();
1923 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1924 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1925 caller()->ice_connection_state(), kDefaultTimeout);
1926 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1927 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08001928
Ying Wangef3998f2019-12-09 13:06:53 +01001929 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1930 "WebRTC.PeerConnection.CandidatePairType_UDP",
1931 webrtc::kIceCandidatePairHostNameHostName));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001932}
1933
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001934#endif // !defined(THREAD_SANITIZER)
1935
Steve Antonede9ca52017-10-16 13:04:27 -07001936// Test that firewalling the ICE connection causes the clients to identify the
1937// disconnected state and then removing the firewall causes them to reconnect.
1938class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08001939 : public PeerConnectionIntegrationBaseTest,
1940 public ::testing::WithParamInterface<
1941 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07001942 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001943 PeerConnectionIntegrationIceStatesTest()
1944 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
1945 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07001946 }
1947
1948 void StartStunServer(const SocketAddress& server_address) {
1949 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01001950 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07001951 }
1952
1953 bool TestIPv6() {
1954 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
1955 }
1956
1957 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001958 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
1959 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07001960 }
1961
1962 std::vector<SocketAddress> CallerAddresses() {
1963 std::vector<SocketAddress> addresses;
1964 addresses.push_back(SocketAddress("1.1.1.1", 0));
1965 if (TestIPv6()) {
1966 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
1967 }
1968 return addresses;
1969 }
1970
1971 std::vector<SocketAddress> CalleeAddresses() {
1972 std::vector<SocketAddress> addresses;
1973 addresses.push_back(SocketAddress("2.2.2.2", 0));
1974 if (TestIPv6()) {
1975 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
1976 }
1977 return addresses;
1978 }
1979
1980 void SetUpNetworkInterfaces() {
1981 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07001982 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
1983 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07001984
1985 // Add network addresses for test.
1986 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001987 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001988 }
1989 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001990 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001991 }
1992 }
1993
1994 private:
1995 uint32_t port_allocator_flags_;
1996 std::unique_ptr<cricket::TestStunServer> stun_server_;
1997};
1998
Yves Gerey100fe632020-01-17 19:15:53 +01001999// Ensure FakeClockForTest is constructed first (see class for rationale).
2000class PeerConnectionIntegrationIceStatesTestWithFakeClock
2001 : public FakeClockForTest,
2002 public PeerConnectionIntegrationIceStatesTest {};
2003
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002004#if !defined(THREAD_SANITIZER)
2005// This test provokes TSAN errors. bugs.webrtc.org/11282
2006
Steve Antonede9ca52017-10-16 13:04:27 -07002007// Tests that the PeerConnection goes through all the ICE gathering/connection
2008// states over the duration of the call. This includes Disconnected and Failed
2009// states, induced by putting a firewall between the peers and waiting for them
2010// to time out.
Yves Gerey100fe632020-01-17 19:15:53 +01002011TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock, VerifyIceStates) {
Steve Antonede9ca52017-10-16 13:04:27 -07002012 const SocketAddress kStunServerAddress =
2013 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
2014 StartStunServer(kStunServerAddress);
2015
2016 PeerConnectionInterface::RTCConfiguration config;
2017 PeerConnectionInterface::IceServer ice_stun_server;
2018 ice_stun_server.urls.push_back(
2019 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
2020 kStunServerAddress.PortAsString());
2021 config.servers.push_back(ice_stun_server);
2022
2023 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2024 ConnectFakeSignaling();
2025 SetPortAllocatorFlags();
2026 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08002027 caller()->AddAudioVideoTracks();
2028 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002029
2030 // Initial state before anything happens.
2031 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
2032 caller()->ice_gathering_state());
2033 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
2034 caller()->ice_connection_state());
Jonas Olsson7a6739e2019-01-15 16:31:55 +01002035 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
2036 caller()->standardized_ice_connection_state());
Steve Antonede9ca52017-10-16 13:04:27 -07002037
2038 // Start the call by creating the offer, setting it as the local description,
2039 // then sending it to the peer who will respond with an answer. This happens
2040 // asynchronously so that we can watch the states as it runs in the
2041 // background.
2042 caller()->CreateAndSetAndSignalOffer();
2043
Steve Antona9b67ce2020-01-16 14:00:44 -08002044 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2045 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002046 FakeClock());
Steve Antona9b67ce2020-01-16 14:00:44 -08002047 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2048 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002049 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002050
2051 // Verify that the observer was notified of the intermediate transitions.
2052 EXPECT_THAT(caller()->ice_connection_state_history(),
2053 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
2054 PeerConnectionInterface::kIceConnectionConnected,
2055 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olssonacd8ae72019-02-25 15:26:24 +01002056 EXPECT_THAT(caller()->standardized_ice_connection_state_history(),
2057 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
2058 PeerConnectionInterface::kIceConnectionConnected,
2059 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olsson635474e2018-10-18 15:58:17 +02002060 EXPECT_THAT(
2061 caller()->peer_connection_state_history(),
2062 ElementsAre(PeerConnectionInterface::PeerConnectionState::kConnecting,
Jonas Olsson635474e2018-10-18 15:58:17 +02002063 PeerConnectionInterface::PeerConnectionState::kConnected));
Steve Antonede9ca52017-10-16 13:04:27 -07002064 EXPECT_THAT(caller()->ice_gathering_state_history(),
2065 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
2066 PeerConnectionInterface::kIceGatheringComplete));
2067
2068 // Block connections to/from the caller and wait for ICE to become
2069 // disconnected.
2070 for (const auto& caller_address : CallerAddresses()) {
2071 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
2072 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01002073 RTC_LOG(LS_INFO) << "Firewall rules applied";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002074 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
2075 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002076 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002077 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
2078 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002079 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002080
2081 // Let ICE re-establish by removing the firewall rules.
2082 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01002083 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002084 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2085 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002086 FakeClock());
Jonas Olssonacd8ae72019-02-25 15:26:24 +01002087 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002088 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002089 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002090
2091 // According to RFC7675, if there is no response within 30 seconds then the
2092 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08002093 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07002094 constexpr int kConsentTimeout = 30000;
2095 for (const auto& caller_address : CallerAddresses()) {
2096 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
2097 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01002098 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002099 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
2100 caller()->ice_connection_state(), kConsentTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002101 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002102 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
2103 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002104 kConsentTimeout, FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002105}
2106
2107// Tests that if the connection doesn't get set up properly we eventually reach
2108// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01002109TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
2110 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002111 // Block connections to/from the caller and wait for ICE to become
2112 // disconnected.
2113 for (const auto& caller_address : CallerAddresses()) {
2114 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
2115 }
2116
2117 ASSERT_TRUE(CreatePeerConnectionWrappers());
2118 ConnectFakeSignaling();
2119 SetPortAllocatorFlags();
2120 SetUpNetworkInterfaces();
2121 caller()->AddAudioVideoTracks();
2122 caller()->CreateAndSetAndSignalOffer();
2123
2124 // According to RFC7675, if there is no response within 30 seconds then the
2125 // peer should consider the other side to have rejected the connection. This
2126 // is signaled by the state transitioning to "failed".
2127 constexpr int kConsentTimeout = 30000;
2128 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
2129 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002130 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002131}
2132
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002133#endif // !defined(THREAD_SANITIZER)
2134
Steve Antonede9ca52017-10-16 13:04:27 -07002135// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
2136// and that the statistics in the metric observers are updated correctly.
Rasmus Brandt32af25b2021-03-17 13:40:21 +01002137// TODO(bugs.webrtc.org/12591): Flaky on Windows.
2138#if defined(WEBRTC_WIN)
2139#define MAYBE_VerifyBestConnection DISABLED_VerifyBestConnection
2140#else
2141#define MAYBE_VerifyBestConnection VerifyBestConnection
2142#endif
2143TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
Steve Antonede9ca52017-10-16 13:04:27 -07002144 ASSERT_TRUE(CreatePeerConnectionWrappers());
2145 ConnectFakeSignaling();
2146 SetPortAllocatorFlags();
2147 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08002148 caller()->AddAudioVideoTracks();
2149 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002150 caller()->CreateAndSetAndSignalOffer();
2151
2152 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08002153 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2154 caller()->ice_connection_state(), kDefaultTimeout);
2155 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2156 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07002157
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002158 // TODO(bugs.webrtc.org/9456): Fix it.
2159 const int num_best_ipv4 = webrtc::metrics::NumEvents(
2160 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
2161 const int num_best_ipv6 = webrtc::metrics::NumEvents(
2162 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07002163 if (TestIPv6()) {
2164 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
2165 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01002166 EXPECT_METRIC_EQ(0, num_best_ipv4);
2167 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07002168 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01002169 EXPECT_METRIC_EQ(1, num_best_ipv4);
2170 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07002171 }
2172
Ying Wangef3998f2019-12-09 13:06:53 +01002173 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
2174 "WebRTC.PeerConnection.CandidatePairType_UDP",
2175 webrtc::kIceCandidatePairHostHost));
2176 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
2177 "WebRTC.PeerConnection.CandidatePairType_UDP",
2178 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07002179}
2180
2181constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
2182 cricket::PORTALLOCATOR_DISABLE_STUN |
2183 cricket::PORTALLOCATOR_DISABLE_RELAY;
2184constexpr uint32_t kFlagsIPv6NoStun =
2185 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
2186 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
2187constexpr uint32_t kFlagsIPv4Stun =
2188 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
2189
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002190INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002191 PeerConnectionIntegrationTest,
2192 PeerConnectionIntegrationIceStatesTest,
2193 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
2194 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2195 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2196 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07002197
Yves Gerey100fe632020-01-17 19:15:53 +01002198INSTANTIATE_TEST_SUITE_P(
2199 PeerConnectionIntegrationTest,
2200 PeerConnectionIntegrationIceStatesTestWithFakeClock,
2201 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
2202 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2203 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2204 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
2205
deadbeef1dcb1642017-03-29 21:08:16 -07002206// This test sets up a call between two parties with audio and video.
2207// During the call, the caller restarts ICE and the test verifies that
2208// new ICE candidates are generated and audio and video still can flow, and the
2209// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002210TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07002211 ASSERT_TRUE(CreatePeerConnectionWrappers());
2212 ConnectFakeSignaling();
2213 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08002214 caller()->AddAudioVideoTracks();
2215 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002216 caller()->CreateAndSetAndSignalOffer();
2217 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2218 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2219 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002220 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2221 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07002222
2223 // To verify that the ICE restart actually occurs, get
2224 // ufrag/password/candidates before and after restart.
2225 // Create an SDP string of the first audio candidate for both clients.
2226 const webrtc::IceCandidateCollection* audio_candidates_caller =
2227 caller()->pc()->local_description()->candidates(0);
2228 const webrtc::IceCandidateCollection* audio_candidates_callee =
2229 callee()->pc()->local_description()->candidates(0);
2230 ASSERT_GT(audio_candidates_caller->count(), 0u);
2231 ASSERT_GT(audio_candidates_callee->count(), 0u);
2232 std::string caller_candidate_pre_restart;
2233 ASSERT_TRUE(
2234 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
2235 std::string callee_candidate_pre_restart;
2236 ASSERT_TRUE(
2237 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
2238 const cricket::SessionDescription* desc =
2239 caller()->pc()->local_description()->description();
2240 std::string caller_ufrag_pre_restart =
2241 desc->transport_infos()[0].description.ice_ufrag;
2242 desc = callee()->pc()->local_description()->description();
2243 std::string callee_ufrag_pre_restart =
2244 desc->transport_infos()[0].description.ice_ufrag;
2245
Alex Drake00c7ecf2019-08-06 10:54:47 -07002246 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002247 // Have the caller initiate an ICE restart.
2248 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2249 caller()->CreateAndSetAndSignalOffer();
2250 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2251 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2252 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002253 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07002254 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2255
2256 // Grab the ufrags/candidates again.
2257 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
2258 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
2259 ASSERT_GT(audio_candidates_caller->count(), 0u);
2260 ASSERT_GT(audio_candidates_callee->count(), 0u);
2261 std::string caller_candidate_post_restart;
2262 ASSERT_TRUE(
2263 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
2264 std::string callee_candidate_post_restart;
2265 ASSERT_TRUE(
2266 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
2267 desc = caller()->pc()->local_description()->description();
2268 std::string caller_ufrag_post_restart =
2269 desc->transport_infos()[0].description.ice_ufrag;
2270 desc = callee()->pc()->local_description()->description();
2271 std::string callee_ufrag_post_restart =
2272 desc->transport_infos()[0].description.ice_ufrag;
2273 // Sanity check that an ICE restart was actually negotiated in SDP.
2274 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
2275 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
2276 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
2277 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07002278 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002279
2280 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002281 MediaExpectations media_expectations;
2282 media_expectations.ExpectBidirectionalAudioAndVideo();
2283 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002284}
2285
2286// Verify that audio/video can be received end-to-end when ICE renomination is
2287// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002288TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07002289 PeerConnectionInterface::RTCConfiguration config;
2290 config.enable_ice_renomination = true;
2291 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2292 ConnectFakeSignaling();
2293 // Do normal offer/answer and wait for some frames to be received in each
2294 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002295 caller()->AddAudioVideoTracks();
2296 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002297 caller()->CreateAndSetAndSignalOffer();
2298 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2299 // Sanity check that ICE renomination was actually negotiated.
2300 const cricket::SessionDescription* desc =
2301 caller()->pc()->local_description()->description();
2302 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002303 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002304 }
2305 desc = callee()->pc()->local_description()->description();
2306 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002307 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002308 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08002309 MediaExpectations media_expectations;
2310 media_expectations.ExpectBidirectionalAudioAndVideo();
2311 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002312}
2313
Steve Anton6f25b092017-10-23 09:39:20 -07002314// With a max bundle policy and RTCP muxing, adding a new media description to
2315// the connection should not affect ICE at all because the new media will use
2316// the existing connection.
Rasmus Brandt685be142021-03-15 14:03:38 +01002317// TODO(bugs.webrtc.org/12538): Fails on tsan.
2318#if defined(THREAD_SANITIZER)
2319#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2320 DISABLED_AddMediaToConnectedBundleDoesNotRestartIce
2321#else
2322#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2323 AddMediaToConnectedBundleDoesNotRestartIce
2324#endif
Seth Hampson2f0d7022018-02-20 11:54:42 -08002325TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt685be142021-03-15 14:03:38 +01002326 MAYBE_AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07002327 PeerConnectionInterface::RTCConfiguration config;
2328 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
2329 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
2330 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
2331 config, PeerConnectionInterface::RTCConfiguration()));
2332 ConnectFakeSignaling();
2333
Steve Anton15324772018-01-16 10:26:49 -08002334 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002335 caller()->CreateAndSetAndSignalOffer();
2336 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07002337 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2338 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07002339
2340 caller()->clear_ice_connection_state_history();
2341
Steve Anton15324772018-01-16 10:26:49 -08002342 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002343 caller()->CreateAndSetAndSignalOffer();
2344 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2345
2346 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
2347}
2348
deadbeef1dcb1642017-03-29 21:08:16 -07002349// This test sets up a call between two parties with audio and video. It then
2350// renegotiates setting the video m-line to "port 0", then later renegotiates
2351// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002352TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002353 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
2354 ASSERT_TRUE(CreatePeerConnectionWrappers());
2355 ConnectFakeSignaling();
2356
2357 // Do initial negotiation, only sending media from the caller. Will result in
2358 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08002359 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002360 caller()->CreateAndSetAndSignalOffer();
2361 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2362
2363 // Negotiate again, disabling the video "m=" section (the callee will set the
2364 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002365 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2366 PeerConnectionInterface::RTCOfferAnswerOptions options;
2367 options.offer_to_receive_video = 0;
2368 callee()->SetOfferAnswerOptions(options);
2369 } else {
2370 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002371 callee()
2372 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2373 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002374 });
2375 }
deadbeef1dcb1642017-03-29 21:08:16 -07002376 caller()->CreateAndSetAndSignalOffer();
2377 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2378 // Sanity check that video "m=" section was actually rejected.
2379 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
2380 callee()->pc()->local_description()->description());
2381 ASSERT_NE(nullptr, answer_video_content);
2382 ASSERT_TRUE(answer_video_content->rejected);
2383
2384 // Enable video and do negotiation again, making sure video is received
2385 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002386 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2387 PeerConnectionInterface::RTCOfferAnswerOptions options;
2388 options.offer_to_receive_video = 1;
2389 callee()->SetOfferAnswerOptions(options);
2390 } else {
2391 // The caller's transceiver is stopped, so we need to add another track.
2392 auto caller_transceiver =
2393 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002394 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002395 caller()->AddVideoTrack();
2396 }
2397 callee()->AddVideoTrack();
2398 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07002399 caller()->CreateAndSetAndSignalOffer();
2400 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002401
deadbeef1dcb1642017-03-29 21:08:16 -07002402 // Verify the caller receives frames from the newly added stream, and the
2403 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002404 MediaExpectations media_expectations;
2405 media_expectations.CalleeExpectsSomeAudio();
2406 media_expectations.ExpectBidirectionalVideo();
2407 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002408}
2409
deadbeef1dcb1642017-03-29 21:08:16 -07002410// This tests that if we negotiate after calling CreateSender but before we
2411// have a track, then set a track later, frames from the newly-set track are
2412// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002413TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07002414 MediaFlowsAfterEarlyWarmupWithCreateSender) {
2415 ASSERT_TRUE(CreatePeerConnectionWrappers());
2416 ConnectFakeSignaling();
2417 auto caller_audio_sender =
2418 caller()->pc()->CreateSender("audio", "caller_stream");
2419 auto caller_video_sender =
2420 caller()->pc()->CreateSender("video", "caller_stream");
2421 auto callee_audio_sender =
2422 callee()->pc()->CreateSender("audio", "callee_stream");
2423 auto callee_video_sender =
2424 callee()->pc()->CreateSender("video", "callee_stream");
2425 caller()->CreateAndSetAndSignalOffer();
2426 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2427 // Wait for ICE to complete, without any tracks being set.
2428 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2429 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2430 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2431 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2432 // Now set the tracks, and expect frames to immediately start flowing.
2433 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
2434 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
2435 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
2436 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002437 MediaExpectations media_expectations;
2438 media_expectations.ExpectBidirectionalAudioAndVideo();
2439 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2440}
2441
2442// This tests that if we negotiate after calling AddTransceiver but before we
2443// have a track, then set a track later, frames from the newly-set tracks are
2444// received end-to-end.
2445TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2446 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
2447 ASSERT_TRUE(CreatePeerConnectionWrappers());
2448 ConnectFakeSignaling();
2449 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
2450 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
2451 auto caller_audio_sender = audio_result.MoveValue()->sender();
2452 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
2453 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
2454 auto caller_video_sender = video_result.MoveValue()->sender();
2455 callee()->SetRemoteOfferHandler([this] {
2456 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02002457 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002458 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002459 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002460 RtpTransceiverDirection::kSendRecv);
2461 });
2462 caller()->CreateAndSetAndSignalOffer();
2463 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2464 // Wait for ICE to complete, without any tracks being set.
2465 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2466 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2467 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2468 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2469 // Now set the tracks, and expect frames to immediately start flowing.
2470 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
2471 auto callee_video_sender = callee()->pc()->GetSenders()[1];
2472 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
2473 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
2474 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
2475 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
2476 MediaExpectations media_expectations;
2477 media_expectations.ExpectBidirectionalAudioAndVideo();
2478 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002479}
2480
2481// This test verifies that a remote video track can be added via AddStream,
2482// and sent end-to-end. For this particular test, it's simply echoed back
2483// from the caller to the callee, rather than being forwarded to a third
2484// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002485TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07002486 ASSERT_TRUE(CreatePeerConnectionWrappers());
2487 ConnectFakeSignaling();
2488 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08002489 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002490 caller()->CreateAndSetAndSignalOffer();
2491 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002492 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07002493
2494 // Echo the stream back, and do a new offer/anwer (initiated by callee this
2495 // time).
2496 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
2497 callee()->CreateAndSetAndSignalOffer();
2498 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2499
Seth Hampson2f0d7022018-02-20 11:54:42 -08002500 MediaExpectations media_expectations;
2501 media_expectations.ExpectBidirectionalVideo();
2502 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002503}
2504
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002505#if !defined(THREAD_SANITIZER)
2506// This test provokes TSAN errors. bugs.webrtc.org/11282
2507
deadbeef1dcb1642017-03-29 21:08:16 -07002508// Test that we achieve the expected end-to-end connection time, using a
2509// fake clock and simulated latency on the media and signaling paths.
2510// We use a TURN<->TURN connection because this is usually the quickest to
2511// set up initially, especially when we're confident the connection will work
2512// and can start sending media before we get a STUN response.
2513//
2514// With various optimizations enabled, here are the network delays we expect to
2515// be on the critical path:
2516// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
2517// signaling answer (with DTLS fingerprint).
2518// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
2519// using TURN<->TURN pair, and DTLS exchange is 4 packets,
2520// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01002521TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2522 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07002523 static constexpr int media_hop_delay_ms = 50;
2524 static constexpr int signaling_trip_delay_ms = 500;
2525 // For explanation of these values, see comment above.
2526 static constexpr int required_media_hops = 9;
2527 static constexpr int required_signaling_trips = 2;
2528 // For internal delays (such as posting an event asychronously).
2529 static constexpr int allowed_internal_delay_ms = 20;
2530 static constexpr int total_connection_time_ms =
2531 media_hop_delay_ms * required_media_hops +
2532 signaling_trip_delay_ms * required_signaling_trips +
2533 allowed_internal_delay_ms;
2534
2535 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2536 3478};
2537 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2538 0};
2539 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2540 3478};
2541 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2542 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002543 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
2544 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002545
Seth Hampsonaed71642018-06-11 07:41:32 -07002546 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
2547 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07002548 // Bypass permission check on received packets so media can be sent before
2549 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07002550 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
2551 turn_server_1->set_enable_permission_checks(false);
2552 });
2553 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
2554 turn_server_2->set_enable_permission_checks(false);
2555 });
deadbeef1dcb1642017-03-29 21:08:16 -07002556
2557 PeerConnectionInterface::RTCConfiguration client_1_config;
2558 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2559 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2560 ice_server_1.username = "test";
2561 ice_server_1.password = "test";
2562 client_1_config.servers.push_back(ice_server_1);
2563 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2564 client_1_config.presume_writable_when_fully_relayed = true;
2565
2566 PeerConnectionInterface::RTCConfiguration client_2_config;
2567 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2568 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2569 ice_server_2.username = "test";
2570 ice_server_2.password = "test";
2571 client_2_config.servers.push_back(ice_server_2);
2572 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2573 client_2_config.presume_writable_when_fully_relayed = true;
2574
2575 ASSERT_TRUE(
2576 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2577 // Set up the simulated delays.
2578 SetSignalingDelayMs(signaling_trip_delay_ms);
2579 ConnectFakeSignaling();
2580 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
2581 virtual_socket_server()->UpdateDelayDistribution();
2582
2583 // Set "offer to receive audio/video" without adding any tracks, so we just
2584 // set up ICE/DTLS with no media.
2585 PeerConnectionInterface::RTCOfferAnswerOptions options;
2586 options.offer_to_receive_audio = 1;
2587 options.offer_to_receive_video = 1;
2588 caller()->SetOfferAnswerOptions(options);
2589 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07002590 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01002591 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07002592 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
2593 // If this is not done a DCHECK can be hit in ports.cc, because a large
2594 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07002595 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07002596}
2597
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002598#endif // !defined(THREAD_SANITIZER)
2599
Jonas Orelandbdcee282017-10-10 14:01:40 +02002600// Verify that a TurnCustomizer passed in through RTCConfiguration
2601// is actually used by the underlying TURN candidate pair.
2602// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002603TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02002604 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2605 3478};
2606 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2607 0};
2608 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2609 3478};
2610 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2611 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002612 CreateTurnServer(turn_server_1_internal_address,
2613 turn_server_1_external_address);
2614 CreateTurnServer(turn_server_2_internal_address,
2615 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002616
2617 PeerConnectionInterface::RTCConfiguration client_1_config;
2618 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2619 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2620 ice_server_1.username = "test";
2621 ice_server_1.password = "test";
2622 client_1_config.servers.push_back(ice_server_1);
2623 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002624 auto* customizer1 = CreateTurnCustomizer();
2625 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002626
2627 PeerConnectionInterface::RTCConfiguration client_2_config;
2628 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2629 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2630 ice_server_2.username = "test";
2631 ice_server_2.password = "test";
2632 client_2_config.servers.push_back(ice_server_2);
2633 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002634 auto* customizer2 = CreateTurnCustomizer();
2635 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002636
2637 ASSERT_TRUE(
2638 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2639 ConnectFakeSignaling();
2640
2641 // Set "offer to receive audio/video" without adding any tracks, so we just
2642 // set up ICE/DTLS with no media.
2643 PeerConnectionInterface::RTCOfferAnswerOptions options;
2644 options.offer_to_receive_audio = 1;
2645 options.offer_to_receive_video = 1;
2646 caller()->SetOfferAnswerOptions(options);
2647 caller()->CreateAndSetAndSignalOffer();
2648 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2649
Seth Hampsonaed71642018-06-11 07:41:32 -07002650 ExpectTurnCustomizerCountersIncremented(customizer1);
2651 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002652}
2653
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002654// Verifies that you can use TCP instead of UDP to connect to a TURN server and
2655// send media between the caller and the callee.
2656TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
2657 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2658 3478};
2659 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2660
2661 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07002662 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2663 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002664
2665 webrtc::PeerConnectionInterface::IceServer ice_server;
2666 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
2667 ice_server.username = "test";
2668 ice_server.password = "test";
2669
2670 PeerConnectionInterface::RTCConfiguration client_1_config;
2671 client_1_config.servers.push_back(ice_server);
2672 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2673
2674 PeerConnectionInterface::RTCConfiguration client_2_config;
2675 client_2_config.servers.push_back(ice_server);
2676 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2677
2678 ASSERT_TRUE(
2679 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2680
2681 // Do normal offer/answer and wait for ICE to complete.
2682 ConnectFakeSignaling();
2683 caller()->AddAudioVideoTracks();
2684 callee()->AddAudioVideoTracks();
2685 caller()->CreateAndSetAndSignalOffer();
2686 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2687 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2688 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2689
2690 MediaExpectations media_expectations;
2691 media_expectations.ExpectBidirectionalAudioAndVideo();
2692 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2693}
2694
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002695// Verify that a SSLCertificateVerifier passed in through
2696// PeerConnectionDependencies is actually used by the underlying SSL
2697// implementation to determine whether a certificate presented by the TURN
2698// server is accepted by the client. Note that openssladapter_unittest.cc
2699// contains more detailed, lower-level tests.
2700TEST_P(PeerConnectionIntegrationTest,
2701 SSLCertificateVerifierUsedForTurnConnections) {
2702 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2703 3478};
2704 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2705
2706 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2707 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002708 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2709 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002710
2711 webrtc::PeerConnectionInterface::IceServer ice_server;
2712 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2713 ice_server.username = "test";
2714 ice_server.password = "test";
2715
2716 PeerConnectionInterface::RTCConfiguration client_1_config;
2717 client_1_config.servers.push_back(ice_server);
2718 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2719
2720 PeerConnectionInterface::RTCConfiguration client_2_config;
2721 client_2_config.servers.push_back(ice_server);
2722 // Setting the type to kRelay forces the connection to go through a TURN
2723 // server.
2724 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2725
2726 // Get a copy to the pointer so we can verify calls later.
2727 rtc::TestCertificateVerifier* client_1_cert_verifier =
2728 new rtc::TestCertificateVerifier();
2729 client_1_cert_verifier->verify_certificate_ = true;
2730 rtc::TestCertificateVerifier* client_2_cert_verifier =
2731 new rtc::TestCertificateVerifier();
2732 client_2_cert_verifier->verify_certificate_ = true;
2733
2734 // Create the dependencies with the test certificate verifier.
2735 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2736 client_1_deps.tls_cert_verifier =
2737 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2738 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2739 client_2_deps.tls_cert_verifier =
2740 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2741
2742 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2743 client_1_config, std::move(client_1_deps), client_2_config,
2744 std::move(client_2_deps)));
2745 ConnectFakeSignaling();
2746
2747 // Set "offer to receive audio/video" without adding any tracks, so we just
2748 // set up ICE/DTLS with no media.
2749 PeerConnectionInterface::RTCOfferAnswerOptions options;
2750 options.offer_to_receive_audio = 1;
2751 options.offer_to_receive_video = 1;
2752 caller()->SetOfferAnswerOptions(options);
2753 caller()->CreateAndSetAndSignalOffer();
2754 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2755
2756 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2757 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002758}
2759
2760TEST_P(PeerConnectionIntegrationTest,
2761 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
2762 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2763 3478};
2764 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2765
2766 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2767 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002768 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2769 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002770
2771 webrtc::PeerConnectionInterface::IceServer ice_server;
2772 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2773 ice_server.username = "test";
2774 ice_server.password = "test";
2775
2776 PeerConnectionInterface::RTCConfiguration client_1_config;
2777 client_1_config.servers.push_back(ice_server);
2778 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2779
2780 PeerConnectionInterface::RTCConfiguration client_2_config;
2781 client_2_config.servers.push_back(ice_server);
2782 // Setting the type to kRelay forces the connection to go through a TURN
2783 // server.
2784 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2785
2786 // Get a copy to the pointer so we can verify calls later.
2787 rtc::TestCertificateVerifier* client_1_cert_verifier =
2788 new rtc::TestCertificateVerifier();
2789 client_1_cert_verifier->verify_certificate_ = false;
2790 rtc::TestCertificateVerifier* client_2_cert_verifier =
2791 new rtc::TestCertificateVerifier();
2792 client_2_cert_verifier->verify_certificate_ = false;
2793
2794 // Create the dependencies with the test certificate verifier.
2795 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2796 client_1_deps.tls_cert_verifier =
2797 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2798 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2799 client_2_deps.tls_cert_verifier =
2800 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2801
2802 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2803 client_1_config, std::move(client_1_deps), client_2_config,
2804 std::move(client_2_deps)));
2805 ConnectFakeSignaling();
2806
2807 // Set "offer to receive audio/video" without adding any tracks, so we just
2808 // set up ICE/DTLS with no media.
2809 PeerConnectionInterface::RTCOfferAnswerOptions options;
2810 options.offer_to_receive_audio = 1;
2811 options.offer_to_receive_video = 1;
2812 caller()->SetOfferAnswerOptions(options);
2813 caller()->CreateAndSetAndSignalOffer();
2814 bool wait_res = true;
2815 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
2816 // properly, should be able to just wait for a state of "failed" instead of
2817 // waiting a fixed 10 seconds.
2818 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
2819 ASSERT_FALSE(wait_res);
2820
2821 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2822 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002823}
2824
Qingsi Wang25ec8882019-11-15 12:33:05 -08002825// Test that the injected ICE transport factory is used to create ICE transports
2826// for WebRTC connections.
2827TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
2828 PeerConnectionInterface::RTCConfiguration default_config;
2829 PeerConnectionDependencies dependencies(nullptr);
2830 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
2831 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
2832 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02002833 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
2834 std::move(dependencies), nullptr,
2835 /*reset_encoder_factory=*/false,
2836 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08002837 ASSERT_TRUE(wrapper);
2838 wrapper->CreateDataChannel();
Tommi87f70902021-04-27 14:43:08 +02002839 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Qingsi Wang25ec8882019-11-15 12:33:05 -08002840 wrapper->pc()->SetLocalDescription(observer,
2841 wrapper->CreateOfferAndWait().release());
2842}
2843
deadbeefc964d0b2017-04-03 10:03:35 -07002844// Test that audio and video flow end-to-end when codec names don't use the
2845// expected casing, given that they're supposed to be case insensitive. To test
2846// this, all but one codec is removed from each media description, and its
2847// casing is changed.
2848//
2849// In the past, this has regressed and caused crashes/black video, due to the
2850// fact that code at some layers was doing case-insensitive comparisons and
2851// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002852TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07002853 ASSERT_TRUE(CreatePeerConnectionWrappers());
2854 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002855 caller()->AddAudioVideoTracks();
2856 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07002857
2858 // Remove all but one audio/video codec (opus and VP8), and change the
2859 // casing of the caller's generated offer.
2860 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
2861 cricket::AudioContentDescription* audio =
2862 GetFirstAudioContentDescription(description);
2863 ASSERT_NE(nullptr, audio);
2864 auto audio_codecs = audio->codecs();
2865 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
2866 [](const cricket::AudioCodec& codec) {
2867 return codec.name != "opus";
2868 }),
2869 audio_codecs.end());
2870 ASSERT_EQ(1u, audio_codecs.size());
2871 audio_codecs[0].name = "OpUs";
2872 audio->set_codecs(audio_codecs);
2873
2874 cricket::VideoContentDescription* video =
2875 GetFirstVideoContentDescription(description);
2876 ASSERT_NE(nullptr, video);
2877 auto video_codecs = video->codecs();
2878 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
2879 [](const cricket::VideoCodec& codec) {
2880 return codec.name != "VP8";
2881 }),
2882 video_codecs.end());
2883 ASSERT_EQ(1u, video_codecs.size());
2884 video_codecs[0].name = "vP8";
2885 video->set_codecs(video_codecs);
2886 });
2887
2888 caller()->CreateAndSetAndSignalOffer();
2889 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2890
2891 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002892 MediaExpectations media_expectations;
2893 media_expectations.ExpectBidirectionalAudioAndVideo();
2894 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07002895}
2896
Jonas Oreland49ac5952018-09-26 16:04:32 +02002897TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07002898 ASSERT_TRUE(CreatePeerConnectionWrappers());
2899 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002900 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07002901 caller()->CreateAndSetAndSignalOffer();
2902 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07002903 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002904 MediaExpectations media_expectations;
2905 media_expectations.CalleeExpectsSomeAudio(1);
2906 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02002907 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07002908 auto receiver = callee()->pc()->GetReceivers()[0];
2909 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002910 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07002911 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
2912 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02002913 sources[0].source_id());
2914 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
2915}
2916
2917TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
2918 ASSERT_TRUE(CreatePeerConnectionWrappers());
2919 ConnectFakeSignaling();
2920 caller()->AddVideoTrack();
2921 caller()->CreateAndSetAndSignalOffer();
2922 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2923 // Wait for one video frame to be received by the callee.
2924 MediaExpectations media_expectations;
2925 media_expectations.CalleeExpectsSomeVideo(1);
2926 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2927 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2928 auto receiver = callee()->pc()->GetReceivers()[0];
2929 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
2930 auto sources = receiver->GetSources();
2931 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02002932 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002933 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
2934 sources[0].source_id());
2935 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07002936}
2937
deadbeef2f425aa2017-04-14 10:41:32 -07002938// Test that if a track is removed and added again with a different stream ID,
2939// the new stream ID is successfully communicated in SDP and media continues to
2940// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002941// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
2942// it will not reuse a transceiver that has already been sending. After creating
2943// a new transceiver it tries to create an offer with two senders of the same
2944// track ids and it fails.
2945TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07002946 ASSERT_TRUE(CreatePeerConnectionWrappers());
2947 ConnectFakeSignaling();
2948
deadbeef2f425aa2017-04-14 10:41:32 -07002949 // Add track using stream 1, do offer/answer.
2950 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2951 caller()->CreateLocalAudioTrack();
2952 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07002953 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07002954 caller()->CreateAndSetAndSignalOffer();
2955 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002956 {
2957 MediaExpectations media_expectations;
2958 media_expectations.CalleeExpectsSomeAudio(1);
2959 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2960 }
deadbeef2f425aa2017-04-14 10:41:32 -07002961 // Remove the sender, and create a new one with the new stream.
Harald Alvestrand93dd7632022-01-19 12:28:45 +00002962 caller()->pc()->RemoveTrackOrError(sender);
Steve Antond78323f2018-07-11 11:13:44 -07002963 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07002964 caller()->CreateAndSetAndSignalOffer();
2965 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2966 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002967 {
2968 MediaExpectations media_expectations;
2969 media_expectations.CalleeExpectsSomeAudio();
2970 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2971 }
deadbeef2f425aa2017-04-14 10:41:32 -07002972}
2973
Seth Hampson2f0d7022018-02-20 11:54:42 -08002974TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02002975 ASSERT_TRUE(CreatePeerConnectionWrappers());
2976 ConnectFakeSignaling();
2977
Mirko Bonadei317a1f02019-09-17 17:06:18 +02002978 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002979 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
2980 ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true));
Elad Alon99c3fe52017-10-13 16:29:40 +02002981 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01002982 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
2983 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02002984
Steve Anton15324772018-01-16 10:26:49 -08002985 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02002986 caller()->CreateAndSetAndSignalOffer();
2987 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2988}
2989
Steve Antonede9ca52017-10-16 13:04:27 -07002990// Test that if candidates are only signaled by applying full session
2991// descriptions (instead of using AddIceCandidate), the peers can connect to
2992// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002993TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07002994 ASSERT_TRUE(CreatePeerConnectionWrappers());
2995 // Each side will signal the session descriptions but not candidates.
2996 ConnectFakeSignalingForSdpOnly();
2997
2998 // Add audio video track and exchange the initial offer/answer with media
2999 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08003000 caller()->AddAudioVideoTracks();
3001 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003002 caller()->CreateAndSetAndSignalOffer();
3003
3004 // Wait for all candidates to be gathered on both the caller and callee.
3005 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
3006 caller()->ice_gathering_state(), kDefaultTimeout);
3007 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
3008 callee()->ice_gathering_state(), kDefaultTimeout);
3009
3010 // The candidates will now be included in the session description, so
3011 // signaling them will start the ICE connection.
3012 caller()->CreateAndSetAndSignalOffer();
3013 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3014
3015 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003016 MediaExpectations media_expectations;
3017 media_expectations.ExpectBidirectionalAudioAndVideo();
3018 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07003019}
3020
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00003021#if !defined(THREAD_SANITIZER)
3022// These tests provokes TSAN errors. See bugs.webrtc.org/11305.
3023
henrika5f6bf242017-11-01 11:06:56 +01003024// Test that SetAudioPlayout can be used to disable audio playout from the
3025// start, then later enable it. This may be useful, for example, if the caller
3026// needs to play a local ringtone until some event occurs, after which it
3027// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003028TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01003029 ASSERT_TRUE(CreatePeerConnectionWrappers());
3030 ConnectFakeSignaling();
3031
3032 // Set up audio-only call where audio playout is disabled on caller's side.
3033 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08003034 caller()->AddAudioTrack();
3035 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01003036 caller()->CreateAndSetAndSignalOffer();
3037 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3038
3039 // Pump messages for a second.
3040 WAIT(false, 1000);
3041 // Since audio playout is disabled, the caller shouldn't have received
3042 // anything (at the playout level, at least).
3043 EXPECT_EQ(0, caller()->audio_frames_received());
3044 // As a sanity check, make sure the callee (for which playout isn't disabled)
3045 // did still see frames on its audio level.
3046 ASSERT_GT(callee()->audio_frames_received(), 0);
3047
3048 // Enable playout again, and ensure audio starts flowing.
3049 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003050 MediaExpectations media_expectations;
3051 media_expectations.ExpectBidirectionalAudio();
3052 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01003053}
3054
Harald Alvestrand39993842021-02-17 09:05:31 +00003055double GetAudioEnergyStat(PeerConnectionIntegrationWrapper* pc) {
henrika5f6bf242017-11-01 11:06:56 +01003056 auto report = pc->NewGetStats();
3057 auto track_stats_list =
3058 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3059 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
3060 for (const auto* track_stats : track_stats_list) {
3061 if (track_stats->remote_source.is_defined() &&
3062 *track_stats->remote_source) {
3063 remote_track_stats = track_stats;
3064 break;
3065 }
3066 }
3067
3068 if (!remote_track_stats->total_audio_energy.is_defined()) {
3069 return 0.0;
3070 }
3071 return *remote_track_stats->total_audio_energy;
3072}
3073
3074// Test that if audio playout is disabled via the SetAudioPlayout() method, then
3075// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003076TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01003077 DisableAudioPlayoutStillGeneratesAudioStats) {
3078 ASSERT_TRUE(CreatePeerConnectionWrappers());
3079 ConnectFakeSignaling();
3080
3081 // Set up audio-only call where playout is disabled but audio-processing is
3082 // still active.
Steve Anton15324772018-01-16 10:26:49 -08003083 caller()->AddAudioTrack();
3084 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01003085 caller()->pc()->SetAudioPlayout(false);
3086
3087 caller()->CreateAndSetAndSignalOffer();
3088 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3089
3090 // Wait for the callee to receive audio stats.
3091 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
3092}
3093
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00003094#endif // !defined(THREAD_SANITIZER)
3095
henrika4f167df2017-11-01 14:45:55 +01003096// Test that SetAudioRecording can be used to disable audio recording from the
3097// start, then later enable it. This may be useful, for example, if the caller
3098// wants to ensure that no audio resources are active before a certain state
3099// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003100TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01003101 ASSERT_TRUE(CreatePeerConnectionWrappers());
3102 ConnectFakeSignaling();
3103
3104 // Set up audio-only call where audio recording is disabled on caller's side.
3105 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08003106 caller()->AddAudioTrack();
3107 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01003108 caller()->CreateAndSetAndSignalOffer();
3109 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3110
3111 // Pump messages for a second.
3112 WAIT(false, 1000);
3113 // Since caller has disabled audio recording, the callee shouldn't have
3114 // received anything.
3115 EXPECT_EQ(0, callee()->audio_frames_received());
3116 // As a sanity check, make sure the caller did still see frames on its
3117 // audio level since audio recording is enabled on the calle side.
3118 ASSERT_GT(caller()->audio_frames_received(), 0);
3119
3120 // Enable audio recording again, and ensure audio starts flowing.
3121 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003122 MediaExpectations media_expectations;
3123 media_expectations.ExpectBidirectionalAudio();
3124 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01003125}
3126
Qingsi Wang7685e862018-06-11 20:15:46 -07003127TEST_P(PeerConnectionIntegrationTest,
3128 IceEventsGeneratedAndLoggedInRtcEventLog) {
3129 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
3130 ConnectFakeSignaling();
3131 PeerConnectionInterface::RTCOfferAnswerOptions options;
3132 options.offer_to_receive_audio = 1;
3133 caller()->SetOfferAnswerOptions(options);
3134 caller()->CreateAndSetAndSignalOffer();
3135 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3136 ASSERT_NE(nullptr, caller()->event_log_factory());
3137 ASSERT_NE(nullptr, callee()->event_log_factory());
3138 webrtc::FakeRtcEventLog* caller_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01003139 caller()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07003140 webrtc::FakeRtcEventLog* callee_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01003141 callee()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07003142 ASSERT_NE(nullptr, caller_event_log);
3143 ASSERT_NE(nullptr, callee_event_log);
3144 int caller_ice_config_count = caller_event_log->GetEventCount(
3145 webrtc::RtcEvent::Type::IceCandidatePairConfig);
3146 int caller_ice_event_count = caller_event_log->GetEventCount(
3147 webrtc::RtcEvent::Type::IceCandidatePairEvent);
3148 int callee_ice_config_count = callee_event_log->GetEventCount(
3149 webrtc::RtcEvent::Type::IceCandidatePairConfig);
3150 int callee_ice_event_count = callee_event_log->GetEventCount(
3151 webrtc::RtcEvent::Type::IceCandidatePairEvent);
3152 EXPECT_LT(0, caller_ice_config_count);
3153 EXPECT_LT(0, caller_ice_event_count);
3154 EXPECT_LT(0, callee_ice_config_count);
3155 EXPECT_LT(0, callee_ice_event_count);
3156}
3157
Qingsi Wangc129c352019-04-18 10:41:58 -07003158TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07003159 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3160 3478};
3161 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3162
3163 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3164
3165 webrtc::PeerConnectionInterface::IceServer ice_server;
3166 ice_server.urls.push_back("turn:88.88.88.0:3478");
3167 ice_server.username = "test";
3168 ice_server.password = "test";
3169
3170 PeerConnectionInterface::RTCConfiguration caller_config;
3171 caller_config.servers.push_back(ice_server);
3172 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3173 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07003174 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07003175
3176 PeerConnectionInterface::RTCConfiguration callee_config;
3177 callee_config.servers.push_back(ice_server);
3178 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3179 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07003180 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07003181
3182 ASSERT_TRUE(
3183 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3184
3185 // Do normal offer/answer and wait for ICE to complete.
3186 ConnectFakeSignaling();
3187 caller()->AddAudioVideoTracks();
3188 callee()->AddAudioVideoTracks();
3189 caller()->CreateAndSetAndSignalOffer();
3190 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3191 // Since we are doing continual gathering, the ICE transport does not reach
3192 // kIceGatheringComplete (see
3193 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
3194 // kIceConnectionComplete.
3195 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3196 caller()->ice_connection_state(), kDefaultTimeout);
3197 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3198 callee()->ice_connection_state(), kDefaultTimeout);
3199 // Note that we cannot use the metric
Artem Titovcfea2182021-08-10 01:22:31 +02003200 // `WebRTC.PeerConnection.CandidatePairType_UDP` in this test since this
Qingsi Wangc129c352019-04-18 10:41:58 -07003201 // metric is only populated when we reach kIceConnectionComplete in the
3202 // current implementation.
3203 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3204 caller()->last_candidate_gathered().type());
3205 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3206 callee()->last_candidate_gathered().type());
3207
3208 // Loosen the caller's candidate filter.
3209 caller_config = caller()->pc()->GetConfiguration();
3210 caller_config.type = webrtc::PeerConnectionInterface::kAll;
3211 caller()->pc()->SetConfiguration(caller_config);
3212 // We should have gathered a new host candidate.
3213 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3214 caller()->last_candidate_gathered().type(), kDefaultTimeout);
3215
3216 // Loosen the callee's candidate filter.
3217 callee_config = callee()->pc()->GetConfiguration();
3218 callee_config.type = webrtc::PeerConnectionInterface::kAll;
3219 callee()->pc()->SetConfiguration(callee_config);
3220 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3221 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02003222
3223 // Create an offer and verify that it does not contain an ICE restart (i.e new
3224 // ice credentials).
3225 std::string caller_ufrag_pre_offer = caller()
3226 ->pc()
3227 ->local_description()
3228 ->description()
3229 ->transport_infos()[0]
3230 .description.ice_ufrag;
3231 caller()->CreateAndSetAndSignalOffer();
3232 std::string caller_ufrag_post_offer = caller()
3233 ->pc()
3234 ->local_description()
3235 ->description()
3236 ->transport_infos()[0]
3237 .description.ice_ufrag;
3238 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07003239}
3240
Eldar Relloda13ea22019-06-01 12:23:43 +03003241TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03003242 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3243 3478};
3244 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3245
3246 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3247
3248 webrtc::PeerConnectionInterface::IceServer ice_server;
3249 ice_server.urls.push_back("turn:88.88.88.0:3478");
3250 ice_server.username = "test";
3251 ice_server.password = "123";
3252
3253 PeerConnectionInterface::RTCConfiguration caller_config;
3254 caller_config.servers.push_back(ice_server);
3255 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3256 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3257
3258 PeerConnectionInterface::RTCConfiguration callee_config;
3259 callee_config.servers.push_back(ice_server);
3260 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3261 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3262
3263 ASSERT_TRUE(
3264 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3265
3266 // Do normal offer/answer and wait for ICE to complete.
3267 ConnectFakeSignaling();
3268 caller()->AddAudioVideoTracks();
3269 callee()->AddAudioVideoTracks();
3270 caller()->CreateAndSetAndSignalOffer();
3271 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3272 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
3273 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
3274 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02003275 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03003276}
3277
Eldar Rellofa8019c2020-05-14 11:59:33 +03003278TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
3279 webrtc::PeerConnectionInterface::IceServer ice_server;
3280 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
3281 ice_server.username = "test";
3282 ice_server.password = "test";
3283
3284 PeerConnectionInterface::RTCConfiguration caller_config;
3285 caller_config.servers.push_back(ice_server);
3286 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3287 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3288
3289 PeerConnectionInterface::RTCConfiguration callee_config;
3290 callee_config.servers.push_back(ice_server);
3291 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3292 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3293
3294 ASSERT_TRUE(
3295 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3296
3297 // Do normal offer/answer and wait for ICE to complete.
3298 ConnectFakeSignaling();
3299 caller()->AddAudioVideoTracks();
3300 callee()->AddAudioVideoTracks();
3301 caller()->CreateAndSetAndSignalOffer();
3302 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3303 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
3304 EXPECT_EQ(caller()->error_event().address, "");
3305}
3306
Eldar Rello5ab79e62019-10-09 18:29:44 +03003307TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3308 AudioKeepsFlowingAfterImplicitRollback) {
3309 PeerConnectionInterface::RTCConfiguration config;
3310 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3311 config.enable_implicit_rollback = true;
3312 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3313 ConnectFakeSignaling();
3314 caller()->AddAudioTrack();
3315 callee()->AddAudioTrack();
3316 caller()->CreateAndSetAndSignalOffer();
3317 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3318 MediaExpectations media_expectations;
3319 media_expectations.ExpectBidirectionalAudio();
3320 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3321 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
3322 caller()->AddVideoTrack();
3323 callee()->AddVideoTrack();
Tommi87f70902021-04-27 14:43:08 +02003324 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003325 callee()->pc()->SetLocalDescription(observer,
3326 callee()->CreateOfferAndWait().release());
3327 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3328 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
3329 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3330 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3331}
3332
3333TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3334 ImplicitRollbackVisitsStableState) {
3335 RTCConfiguration config;
3336 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3337 config.enable_implicit_rollback = true;
3338
3339 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3340
Tommi87f70902021-04-27 14:43:08 +02003341 auto sld_observer =
3342 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003343 callee()->pc()->SetLocalDescription(sld_observer,
3344 callee()->CreateOfferAndWait().release());
3345 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
3346 EXPECT_EQ(sld_observer->error(), "");
3347
Tommi87f70902021-04-27 14:43:08 +02003348 auto srd_observer =
3349 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003350 callee()->pc()->SetRemoteDescription(
3351 srd_observer, caller()->CreateOfferAndWait().release());
3352 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
3353 EXPECT_EQ(srd_observer->error(), "");
3354
3355 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
3356 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
3357 PeerConnectionInterface::kStable,
3358 PeerConnectionInterface::kHaveRemoteOffer));
3359}
3360
Eldar Rellobd9c33a2020-10-01 17:52:45 +03003361TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3362 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
3363 ASSERT_TRUE(CreatePeerConnectionWrappers());
3364 ConnectFakeSignaling();
3365 caller()->AddVideoTrack();
3366 callee()->AddVideoTrack();
3367 auto munger = [](cricket::SessionDescription* desc) {
3368 cricket::VideoContentDescription* video =
3369 GetFirstVideoContentDescription(desc);
3370 auto codecs = video->codecs();
3371 for (auto&& codec : codecs) {
3372 if (codec.name == "H264") {
3373 std::string value;
3374 // The parameter is not supposed to be present in SDP by default.
3375 EXPECT_FALSE(
3376 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3377 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
3378 std::string(""));
3379 }
3380 }
3381 video->set_codecs(codecs);
3382 };
3383 // Munge local offer for SLD.
3384 caller()->SetGeneratedSdpMunger(munger);
3385 // Munge remote answer for SRD.
3386 caller()->SetReceivedSdpMunger(munger);
3387 caller()->CreateAndSetAndSignalOffer();
3388 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3389 // Observe that after munging the parameter is present in generated SDP.
3390 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
3391 cricket::VideoContentDescription* video =
3392 GetFirstVideoContentDescription(desc);
3393 for (auto&& codec : video->codecs()) {
3394 if (codec.name == "H264") {
3395 std::string value;
3396 EXPECT_TRUE(
3397 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3398 }
3399 }
3400 });
3401 caller()->CreateOfferAndWait();
3402}
3403
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003404TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00003405 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003406 PeerConnectionInterface::RTCConfiguration config;
3407 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3408 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3409 ConnectFakeSignaling();
3410 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3411
3412 caller()->CreateAndSetAndSignalOffer();
3413 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3414 int current_size = caller()->pc()->GetTransceivers().size();
3415 // Add more tracks until we get close to having issues.
3416 // Issues have been seen at:
3417 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003418 // - 16 tracks on android_arm_dbg (flaky)
3419 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003420 // Double the number of tracks
3421 for (int i = 0; i < current_size; i++) {
3422 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3423 }
3424 current_size = caller()->pc()->GetTransceivers().size();
3425 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3426 auto start_time_ms = rtc::TimeMillis();
3427 caller()->CreateAndSetAndSignalOffer();
3428 // We want to stop when the time exceeds one second.
3429 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3430 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3431 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3432 ASSERT_GT(1000, elapsed_time_ms)
3433 << "Audio transceivers: Negotiation took too long after "
3434 << current_size << " tracks added";
3435 }
3436}
3437
3438TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3439 RenegotiateManyVideoTransceivers) {
3440 PeerConnectionInterface::RTCConfiguration config;
3441 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3442 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3443 ConnectFakeSignaling();
3444 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3445
3446 caller()->CreateAndSetAndSignalOffer();
3447 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3448 int current_size = caller()->pc()->GetTransceivers().size();
3449 // Add more tracks until we get close to having issues.
3450 // Issues have been seen at:
3451 // - 96 on a Linux workstation
3452 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
3453 // - 32 on android_arm64_rel and linux_dbg bots
Harald Alvestrand785e23b2021-03-15 21:26:27 +00003454 // - 16 on Android 64 (Nexus 5x)
3455 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003456 // Double the number of tracks
3457 for (int i = 0; i < current_size; i++) {
3458 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3459 }
3460 current_size = caller()->pc()->GetTransceivers().size();
3461 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3462 auto start_time_ms = rtc::TimeMillis();
3463 caller()->CreateAndSetAndSignalOffer();
3464 // We want to stop when the time exceeds one second.
3465 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3466 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3467 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3468 ASSERT_GT(1000, elapsed_time_ms)
3469 << "Video transceivers: Negotiation took too long after "
3470 << current_size << " tracks added";
3471 }
3472}
3473
Harald Alvestrand94324f22021-01-13 12:31:53 +00003474TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3475 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
3476 PeerConnectionInterface::RTCConfiguration config;
3477 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3478 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3479 ConnectFakeSignaling();
3480 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003481 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003482 caller()->CreateAndSetAndSignalOffer();
3483 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3484 // Wait until we can see the audio flowing.
3485 MediaExpectations media_expectations;
3486 media_expectations.CalleeExpectsSomeAudio();
3487 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3488
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003489 // Get the baseline numbers for audio_packets and audio_delay
3490 // in both directions.
3491 caller()->StartWatchingDelayStats();
3492 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003493
3494 int current_size = caller()->pc()->GetTransceivers().size();
3495 // Add more tracks until we get close to having issues.
3496 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003497 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00003498 // Double the number of tracks
3499 for (int i = 0; i < current_size; i++) {
3500 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3501 }
3502 current_size = caller()->pc()->GetTransceivers().size();
3503 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3504 auto start_time_ms = rtc::TimeMillis();
3505 caller()->CreateAndSetAndSignalOffer();
3506 // We want to stop when the time exceeds one second.
3507 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3508 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3509 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3510 // This is a guard against the test using excessive amounts of time.
3511 ASSERT_GT(5000, elapsed_time_ms)
3512 << "Video transceivers: Negotiation took too long after "
3513 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003514 caller()->UpdateDelayStats("caller reception", current_size);
3515 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00003516 }
3517}
3518
Mirko Bonadeic84f6612019-01-31 12:20:57 +01003519INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
3520 PeerConnectionIntegrationTest,
3521 Values(SdpSemantics::kPlanB,
3522 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-17 17:41:02 -08003523
Yves Gerey100fe632020-01-17 19:15:53 +01003524INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
3525 PeerConnectionIntegrationTestWithFakeClock,
3526 Values(SdpSemantics::kPlanB,
3527 SdpSemantics::kUnifiedPlan));
3528
Steve Anton74255ff2018-01-24 18:32:57 -08003529// Tests that verify interoperability between Plan B and Unified Plan
3530// PeerConnections.
3531class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003532 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08003533 public ::testing::WithParamInterface<
3534 std::tuple<SdpSemantics, SdpSemantics>> {
3535 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003536 // Setting the SdpSemantics for the base test to kDefault does not matter
3537 // because we specify not to use the test semantics when creating
Harald Alvestrand39993842021-02-17 09:05:31 +00003538 // PeerConnectionIntegrationWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08003539 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07003540 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08003541 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08003542 callee_semantics_(std::get<1>(GetParam())) {}
3543
3544 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07003545 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
3546 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08003547 }
3548
3549 const SdpSemantics caller_semantics_;
3550 const SdpSemantics callee_semantics_;
3551};
3552
3553TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
3554 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3555 ConnectFakeSignaling();
3556
3557 caller()->CreateAndSetAndSignalOffer();
3558 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3559}
3560
3561TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
3562 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3563 ConnectFakeSignaling();
3564 auto audio_sender = caller()->AddAudioTrack();
3565
3566 caller()->CreateAndSetAndSignalOffer();
3567 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3568
3569 // Verify that one audio receiver has been created on the remote and that it
3570 // has the same track ID as the sending track.
3571 auto receivers = callee()->pc()->GetReceivers();
3572 ASSERT_EQ(1u, receivers.size());
3573 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
3574 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
3575
Seth Hampson2f0d7022018-02-20 11:54:42 -08003576 MediaExpectations media_expectations;
3577 media_expectations.CalleeExpectsSomeAudio();
3578 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003579}
3580
3581TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
3582 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3583 ConnectFakeSignaling();
3584 auto video_sender = caller()->AddVideoTrack();
3585 auto audio_sender = caller()->AddAudioTrack();
3586
3587 caller()->CreateAndSetAndSignalOffer();
3588 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3589
3590 // Verify that one audio and one video receiver have been created on the
3591 // remote and that they have the same track IDs as the sending tracks.
3592 auto audio_receivers =
3593 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
3594 ASSERT_EQ(1u, audio_receivers.size());
3595 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
3596 auto video_receivers =
3597 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
3598 ASSERT_EQ(1u, video_receivers.size());
3599 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
3600
Seth Hampson2f0d7022018-02-20 11:54:42 -08003601 MediaExpectations media_expectations;
3602 media_expectations.CalleeExpectsSomeAudioAndVideo();
3603 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003604}
3605
3606TEST_P(PeerConnectionIntegrationInteropTest,
3607 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
3608 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3609 ConnectFakeSignaling();
3610 caller()->AddAudioVideoTracks();
3611 callee()->AddAudioVideoTracks();
3612
3613 caller()->CreateAndSetAndSignalOffer();
3614 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3615
Seth Hampson2f0d7022018-02-20 11:54:42 -08003616 MediaExpectations media_expectations;
3617 media_expectations.ExpectBidirectionalAudioAndVideo();
3618 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003619}
3620
3621TEST_P(PeerConnectionIntegrationInteropTest,
3622 ReverseRolesOneAudioLocalToOneVideoRemote) {
3623 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3624 ConnectFakeSignaling();
3625 caller()->AddAudioTrack();
3626 callee()->AddVideoTrack();
3627
3628 caller()->CreateAndSetAndSignalOffer();
3629 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3630
3631 // Verify that only the audio track has been negotiated.
3632 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
3633 // Might also check that the callee's NegotiationNeeded flag is set.
3634
3635 // Reverse roles.
3636 callee()->CreateAndSetAndSignalOffer();
3637 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3638
Seth Hampson2f0d7022018-02-20 11:54:42 -08003639 MediaExpectations media_expectations;
3640 media_expectations.CallerExpectsSomeVideo();
3641 media_expectations.CalleeExpectsSomeAudio();
3642 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003643}
3644
Taylor Brandstetter1c7ecef2021-08-11 12:38:35 -07003645TEST_P(PeerConnectionIntegrationTest, NewTracksDoNotCauseNewCandidates) {
3646 ASSERT_TRUE(CreatePeerConnectionWrappers());
3647 ConnectFakeSignaling();
3648 caller()->AddAudioVideoTracks();
3649 caller()->CreateAndSetAndSignalOffer();
3650 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3651 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3652 caller()->ExpectCandidates(0);
3653 callee()->ExpectCandidates(0);
3654 caller()->AddAudioTrack();
3655 caller()->CreateAndSetAndSignalOffer();
3656 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3657}
3658
Mirko Bonadeic84f6612019-01-31 12:20:57 +01003659INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07003660 PeerConnectionIntegrationTest,
3661 PeerConnectionIntegrationInteropTest,
3662 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3663 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
3664
3665// Test that if the Unified Plan side offers two video tracks then the Plan B
3666// side will only see the first one and ignore the second.
3667TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07003668 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
3669 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08003670 ConnectFakeSignaling();
3671 auto first_sender = caller()->AddVideoTrack();
3672 caller()->AddVideoTrack();
3673
3674 caller()->CreateAndSetAndSignalOffer();
3675 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3676
3677 // Verify that there is only one receiver and it corresponds to the first
3678 // added track.
3679 auto receivers = callee()->pc()->GetReceivers();
3680 ASSERT_EQ(1u, receivers.size());
3681 EXPECT_TRUE(receivers[0]->track()->enabled());
3682 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
3683
Seth Hampson2f0d7022018-02-20 11:54:42 -08003684 MediaExpectations media_expectations;
3685 media_expectations.CalleeExpectsSomeVideo();
3686 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003687}
3688
Steve Anton2bed3972019-01-04 17:04:30 -08003689// Test that if the initial offer tagged BUNDLE section is rejected due to its
3690// associated RtpTransceiver being stopped and another transceiver is added,
3691// then renegotiation causes the callee to receive the new video track without
3692// error.
3693// This is a regression test for bugs.webrtc.org/9954
3694TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3695 ReOfferWithStoppedBundleTaggedTransceiver) {
3696 RTCConfiguration config;
3697 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3698 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3699 ConnectFakeSignaling();
3700 auto audio_transceiver_or_error =
3701 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3702 ASSERT_TRUE(audio_transceiver_or_error.ok());
3703 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3704
3705 caller()->CreateAndSetAndSignalOffer();
3706 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3707 {
3708 MediaExpectations media_expectations;
3709 media_expectations.CalleeExpectsSomeAudio();
3710 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3711 }
3712
Harald Alvestrand6060df52020-08-11 09:54:02 +02003713 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08003714 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3715
3716 caller()->CreateAndSetAndSignalOffer();
3717 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3718 {
3719 MediaExpectations media_expectations;
3720 media_expectations.CalleeExpectsSomeVideo();
3721 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3722 }
3723}
3724
Harald Alvestrandbedb6052020-08-20 14:50:10 +02003725TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3726 StopTransceiverRemovesDtlsTransports) {
3727 RTCConfiguration config;
3728 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3729 ConnectFakeSignaling();
3730 auto audio_transceiver_or_error =
3731 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3732 ASSERT_TRUE(audio_transceiver_or_error.ok());
3733 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3734
3735 caller()->CreateAndSetAndSignalOffer();
3736 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3737
3738 audio_transceiver->StopStandard();
3739 caller()->CreateAndSetAndSignalOffer();
3740 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3741 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
3742 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
3743 caller()->pc()->ice_gathering_state());
3744 EXPECT_THAT(caller()->ice_gathering_state_history(),
3745 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3746 PeerConnectionInterface::kIceGatheringComplete,
3747 PeerConnectionInterface::kIceGatheringNew));
3748}
3749
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003750TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00003751 StopTransceiverStopsAndRemovesTransceivers) {
3752 RTCConfiguration config;
3753 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3754 ConnectFakeSignaling();
3755 auto audio_transceiver_or_error =
3756 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3757 ASSERT_TRUE(audio_transceiver_or_error.ok());
3758 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
3759
3760 caller()->CreateAndSetAndSignalOffer();
3761 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3762 caller_transceiver->StopStandard();
3763
3764 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
3765 caller()->CreateAndSetAndSignalOffer();
3766 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3767 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
3768 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
3769 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
3770 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
3771 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
3772 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
3773 EXPECT_TRUE(caller_transceiver->stopped());
3774 EXPECT_TRUE(callee_transceiver->stopped());
3775}
3776
3777TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003778 StopTransceiverEndsIncomingAudioTrack) {
3779 RTCConfiguration config;
3780 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3781 ConnectFakeSignaling();
3782 auto audio_transceiver_or_error =
3783 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3784 ASSERT_TRUE(audio_transceiver_or_error.ok());
3785 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3786
3787 caller()->CreateAndSetAndSignalOffer();
3788 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3789 auto caller_track = audio_transceiver->receiver()->track();
3790 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3791 audio_transceiver->StopStandard();
3792 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3793 caller_track->state());
3794 caller()->CreateAndSetAndSignalOffer();
3795 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3796 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3797 callee_track->state());
3798}
3799
3800TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3801 StopTransceiverEndsIncomingVideoTrack) {
3802 RTCConfiguration config;
3803 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3804 ConnectFakeSignaling();
3805 auto audio_transceiver_or_error =
3806 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3807 ASSERT_TRUE(audio_transceiver_or_error.ok());
3808 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3809
3810 caller()->CreateAndSetAndSignalOffer();
3811 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3812 auto caller_track = audio_transceiver->receiver()->track();
3813 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3814 audio_transceiver->StopStandard();
3815 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3816 caller_track->state());
3817 caller()->CreateAndSetAndSignalOffer();
3818 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3819 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3820 callee_track->state());
3821}
3822
Harald Alvestrand89c40e22021-02-17 08:58:35 +00003823} // namespace
Harald Alvestrand39993842021-02-17 09:05:31 +00003824
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01003825} // namespace webrtc