blob: 53aa63efd97194852af9f590000a7b702cdf5c5b [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>
deadbeef1dcb1642017-03-29 21:08:16 -070017#include <utility>
18#include <vector>
19
Steve Anton64b626b2019-01-28 17:25:26 -080020#include "absl/algorithm/container.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000021#include "absl/types/optional.h"
22#include "api/async_resolver_factory.h"
23#include "api/candidate.h"
24#include "api/crypto/crypto_options.h"
25#include "api/dtmf_sender_interface.h"
26#include "api/ice_transport_interface.h"
27#include "api/jsep.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "api/media_stream_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000029#include "api/media_types.h"
Steve Anton10542f22019-01-11 09:11:00 -080030#include "api/peer_connection_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000031#include "api/rtc_error.h"
32#include "api/rtc_event_log/rtc_event.h"
33#include "api/rtc_event_log/rtc_event_log.h"
34#include "api/rtc_event_log_output.h"
35#include "api/rtp_parameters.h"
Steve Anton10542f22019-01-11 09:11:00 -080036#include "api/rtp_receiver_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000037#include "api/rtp_sender_interface.h"
38#include "api/rtp_transceiver_direction.h"
39#include "api/rtp_transceiver_interface.h"
40#include "api/scoped_refptr.h"
41#include "api/stats/rtc_stats.h"
42#include "api/stats/rtc_stats_report.h"
43#include "api/stats/rtcstats_objects.h"
44#include "api/transport/rtp/rtp_source.h"
Steve Anton10542f22019-01-11 09:11:00 -080045#include "api/uma_metrics.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000046#include "api/units/time_delta.h"
47#include "api/video/video_rotation.h"
48#include "logging/rtc_event_log/fake_rtc_event_log.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070049#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000050#include "media/base/codec.h"
51#include "media/base/media_constants.h"
52#include "media/base/stream_params.h"
Steve Anton10542f22019-01-11 09:11:00 -080053#include "p2p/base/mock_async_resolver.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000054#include "p2p/base/port.h"
55#include "p2p/base/port_allocator.h"
Steve Anton10542f22019-01-11 09:11:00 -080056#include "p2p/base/port_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000057#include "p2p/base/stun_server.h"
Steve Anton10542f22019-01-11 09:11:00 -080058#include "p2p/base/test_stun_server.h"
59#include "p2p/base/test_turn_customizer.h"
60#include "p2p/base/test_turn_server.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000061#include "p2p/base/transport_description.h"
62#include "p2p/base/transport_info.h"
Steve Anton10542f22019-01-11 09:11:00 -080063#include "pc/media_session.h"
64#include "pc/peer_connection.h"
65#include "pc/peer_connection_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080066#include "pc/session_description.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000067#include "pc/test/fake_periodic_video_source.h"
68#include "pc/test/integration_test_helpers.h"
Steve Anton10542f22019-01-11 09:11:00 -080069#include "pc/test/mock_peer_connection_observers.h"
Jonas Olssonb75d9e92019-02-22 10:33:29 +010070#include "rtc_base/fake_clock.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070071#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080072#include "rtc_base/fake_network.h"
73#include "rtc_base/firewall_socket_server.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020074#include "rtc_base/gunit.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000075#include "rtc_base/helpers.h"
76#include "rtc_base/location.h"
77#include "rtc_base/logging.h"
78#include "rtc_base/ref_counted_object.h"
79#include "rtc_base/socket_address.h"
80#include "rtc_base/ssl_certificate.h"
81#include "rtc_base/ssl_fingerprint.h"
82#include "rtc_base/ssl_identity.h"
83#include "rtc_base/ssl_stream_adapter.h"
Steve Anton10542f22019-01-11 09:11:00 -080084#include "rtc_base/test_certificate_verifier.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000085#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080086#include "rtc_base/time_utils.h"
87#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020088#include "system_wrappers/include/metrics.h"
deadbeef1dcb1642017-03-29 21:08:16 -070089
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010090namespace webrtc {
Harald Alvestrand39993842021-02-17 09:05:31 +000091
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010092namespace {
93
Seth Hampson2f0d7022018-02-20 11:54:42 -080094class PeerConnectionIntegrationTest
95 : public PeerConnectionIntegrationBaseTest,
96 public ::testing::WithParamInterface<SdpSemantics> {
97 protected:
98 PeerConnectionIntegrationTest()
99 : PeerConnectionIntegrationBaseTest(GetParam()) {}
100};
101
Yves Gerey100fe632020-01-17 19:15:53 +0100102// Fake clock must be set before threads are started to prevent race on
103// Set/GetClockForTesting().
104// To achieve that, multiple inheritance is used as a mixin pattern
105// where order of construction is finely controlled.
106// This also ensures peerconnection is closed before switching back to non-fake
107// clock, avoiding other races and DCHECK failures such as in rtp_sender.cc.
108class FakeClockForTest : public rtc::ScopedFakeClock {
109 protected:
110 FakeClockForTest() {
111 // Some things use a time of "0" as a special value, so we need to start out
112 // the fake clock at a nonzero time.
113 // TODO(deadbeef): Fix this.
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100114 AdvanceTime(webrtc::TimeDelta::Seconds(1));
Yves Gerey100fe632020-01-17 19:15:53 +0100115 }
116
117 // Explicit handle.
118 ScopedFakeClock& FakeClock() { return *this; }
119};
120
121// Ensure FakeClockForTest is constructed first (see class for rationale).
122class PeerConnectionIntegrationTestWithFakeClock
123 : public FakeClockForTest,
124 public PeerConnectionIntegrationTest {};
125
Seth Hampson2f0d7022018-02-20 11:54:42 -0800126class PeerConnectionIntegrationTestPlanB
127 : public PeerConnectionIntegrationBaseTest {
128 protected:
129 PeerConnectionIntegrationTestPlanB()
130 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
131};
132
133class PeerConnectionIntegrationTestUnifiedPlan
134 : public PeerConnectionIntegrationBaseTest {
135 protected:
136 PeerConnectionIntegrationTestUnifiedPlan()
137 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
138};
139
deadbeef1dcb1642017-03-29 21:08:16 -0700140// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
141// includes testing that the callback is invoked if an observer is connected
142// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800143TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -0700144 RtpReceiverObserverOnFirstPacketReceived) {
145 ASSERT_TRUE(CreatePeerConnectionWrappers());
146 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800147 caller()->AddAudioVideoTracks();
148 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700149 // Start offer/answer exchange and wait for it to complete.
150 caller()->CreateAndSetAndSignalOffer();
151 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
152 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200153 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
154 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -0700155 // Wait for all "first packet received" callbacks to be fired.
156 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -0800157 absl::c_all_of(caller()->rtp_receiver_observers(),
158 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
159 return o->first_packet_received();
160 }),
deadbeef1dcb1642017-03-29 21:08:16 -0700161 kMaxWaitForFramesMs);
162 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -0800163 absl::c_all_of(callee()->rtp_receiver_observers(),
164 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
165 return o->first_packet_received();
166 }),
deadbeef1dcb1642017-03-29 21:08:16 -0700167 kMaxWaitForFramesMs);
168 // If new observers are set after the first packet was already received, the
169 // callback should still be invoked.
170 caller()->ResetRtpReceiverObservers();
171 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200172 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
173 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -0700174 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -0800175 absl::c_all_of(caller()->rtp_receiver_observers(),
176 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
177 return o->first_packet_received();
178 }));
deadbeef1dcb1642017-03-29 21:08:16 -0700179 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -0800180 absl::c_all_of(callee()->rtp_receiver_observers(),
181 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
182 return o->first_packet_received();
183 }));
deadbeef1dcb1642017-03-29 21:08:16 -0700184}
185
186class DummyDtmfObserver : public DtmfSenderObserverInterface {
187 public:
188 DummyDtmfObserver() : completed_(false) {}
189
190 // Implements DtmfSenderObserverInterface.
191 void OnToneChange(const std::string& tone) override {
192 tones_.push_back(tone);
193 if (tone.empty()) {
194 completed_ = true;
195 }
196 }
197
198 const std::vector<std::string>& tones() const { return tones_; }
199 bool completed() const { return completed_; }
200
201 private:
202 bool completed_;
203 std::vector<std::string> tones_;
204};
205
Artem Titov880fa812021-07-30 22:30:23 +0200206// Assumes `sender` already has an audio track added and the offer/answer
deadbeef1dcb1642017-03-29 21:08:16 -0700207// exchange is done.
Harald Alvestrand39993842021-02-17 09:05:31 +0000208void TestDtmfFromSenderToReceiver(PeerConnectionIntegrationWrapper* sender,
209 PeerConnectionIntegrationWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -0800210 // We should be able to get a DTMF sender from the local sender.
211 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
212 sender->pc()->GetSenders().at(0)->GetDtmfSender();
213 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -0700214 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -0700215 dtmf_sender->RegisterObserver(&observer);
216
217 // Test the DtmfSender object just created.
218 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
219 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
220
221 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
222 std::vector<std::string> tones = {"1", "a", ""};
223 EXPECT_EQ(tones, observer.tones());
224 dtmf_sender->UnregisterObserver();
225 // TODO(deadbeef): Verify the tones were actually received end-to-end.
226}
227
228// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
229// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800230TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -0700231 ASSERT_TRUE(CreatePeerConnectionWrappers());
232 ConnectFakeSignaling();
233 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -0800234 caller()->AddAudioTrack();
235 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700236 caller()->CreateAndSetAndSignalOffer();
237 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -0700238 // DTLS must finish before the DTMF sender can be used reliably.
239 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -0700240 TestDtmfFromSenderToReceiver(caller(), callee());
241 TestDtmfFromSenderToReceiver(callee(), caller());
242}
243
244// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
245// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800246TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -0700247 ASSERT_TRUE(CreatePeerConnectionWrappers());
248 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +0100249
deadbeef1dcb1642017-03-29 21:08:16 -0700250 // Do normal offer/answer and wait for some frames to be received in each
251 // direction.
Steve Anton15324772018-01-16 10:26:49 -0800252 caller()->AddAudioVideoTracks();
253 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700254 caller()->CreateAndSetAndSignalOffer();
255 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800256 MediaExpectations media_expectations;
257 media_expectations.ExpectBidirectionalAudioAndVideo();
258 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Ying Wangef3998f2019-12-09 13:06:53 +0100259 EXPECT_METRIC_LE(
260 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
261 webrtc::kEnumCounterKeyProtocolDtls));
262 EXPECT_METRIC_EQ(
263 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
264 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -0700265}
266
Artem Titov880fa812021-07-30 22:30:23 +0200267// Basic end-to-end test specifying the `enable_encrypted_rtp_header_extensions`
Steve Anton9a44b2d2019-07-12 12:58:30 -0700268// option to offer encrypted versions of all header extensions alongside the
269// unencrypted versions.
270TEST_P(PeerConnectionIntegrationTest,
271 EndToEndCallWithEncryptedRtpHeaderExtensions) {
272 CryptoOptions crypto_options;
273 crypto_options.srtp.enable_encrypted_rtp_header_extensions = true;
274 PeerConnectionInterface::RTCConfiguration config;
275 config.crypto_options = crypto_options;
276 // Note: This allows offering >14 RTP header extensions.
277 config.offer_extmap_allow_mixed = true;
278 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
279 ConnectFakeSignaling();
280
281 // Do normal offer/answer and wait for some frames to be received in each
282 // direction.
283 caller()->AddAudioVideoTracks();
284 callee()->AddAudioVideoTracks();
285 caller()->CreateAndSetAndSignalOffer();
286 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
287 MediaExpectations media_expectations;
288 media_expectations.ExpectBidirectionalAudioAndVideo();
289 ASSERT_TRUE(ExpectNewFrames(media_expectations));
290}
291
deadbeef1dcb1642017-03-29 21:08:16 -0700292// This test sets up a call between two parties with a source resolution of
293// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800294TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -0700295 Send1280By720ResolutionAndReceive16To9AspectRatio) {
296 ASSERT_TRUE(CreatePeerConnectionWrappers());
297 ConnectFakeSignaling();
298
Niels Möller5c7efe72018-05-11 10:34:46 +0200299 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
300 webrtc::FakePeriodicVideoSource::Config config;
301 config.width = 1280;
302 config.height = 720;
Johannes Kron965e7942018-09-13 15:36:20 +0200303 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +0200304 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
305 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -0700306
307 // Do normal offer/answer and wait for at least one frame to be received in
308 // each direction.
309 caller()->CreateAndSetAndSignalOffer();
310 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
311 callee()->min_video_frames_received_per_track() > 0,
312 kMaxWaitForFramesMs);
313
314 // Check rendered aspect ratio.
315 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
316 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
317 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
318 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
319}
320
321// This test sets up an one-way call, with media only from caller to
322// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800323TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -0700324 ASSERT_TRUE(CreatePeerConnectionWrappers());
325 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800326 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700327 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800328 MediaExpectations media_expectations;
329 media_expectations.CalleeExpectsSomeAudioAndVideo();
330 media_expectations.CallerExpectsNoAudio();
331 media_expectations.CallerExpectsNoVideo();
332 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700333}
334
Johannes Kron3e983682020-03-29 22:17:00 +0200335// Tests that send only works without the caller having a decoder factory and
336// the callee having an encoder factory.
337TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSendOnlyVideo) {
338 ASSERT_TRUE(
339 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
340 ConnectFakeSignaling();
341 // Add one-directional video, from caller to callee.
342 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
343 caller()->CreateLocalVideoTrack();
344 caller()->AddTrack(caller_track);
345 PeerConnectionInterface::RTCOfferAnswerOptions options;
346 options.offer_to_receive_video = 0;
347 caller()->SetOfferAnswerOptions(options);
348 caller()->CreateAndSetAndSignalOffer();
349 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
350 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
351
352 // Expect video to be received in one direction.
353 MediaExpectations media_expectations;
354 media_expectations.CallerExpectsNoVideo();
355 media_expectations.CalleeExpectsSomeVideo();
356
357 EXPECT_TRUE(ExpectNewFrames(media_expectations));
358}
359
360// Tests that receive only works without the caller having an encoder factory
361// and the callee having a decoder factory.
362TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithReceiveOnlyVideo) {
363 ASSERT_TRUE(
364 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/false));
365 ConnectFakeSignaling();
366 // Add one-directional video, from callee to caller.
367 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
368 callee()->CreateLocalVideoTrack();
369 callee()->AddTrack(callee_track);
370 PeerConnectionInterface::RTCOfferAnswerOptions options;
371 options.offer_to_receive_video = 1;
372 caller()->SetOfferAnswerOptions(options);
373 caller()->CreateAndSetAndSignalOffer();
374 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
375 ASSERT_EQ(caller()->pc()->GetReceivers().size(), 1u);
376
377 // Expect video to be received in one direction.
378 MediaExpectations media_expectations;
379 media_expectations.CallerExpectsSomeVideo();
380 media_expectations.CalleeExpectsNoVideo();
381
382 EXPECT_TRUE(ExpectNewFrames(media_expectations));
383}
384
385TEST_P(PeerConnectionIntegrationTest,
386 EndToEndCallAddReceiveVideoToSendOnlyCall) {
387 ASSERT_TRUE(CreatePeerConnectionWrappers());
388 ConnectFakeSignaling();
389 // Add one-directional video, from caller to callee.
390 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
391 caller()->CreateLocalVideoTrack();
392 caller()->AddTrack(caller_track);
393 caller()->CreateAndSetAndSignalOffer();
394 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
395
396 // Add receive video.
397 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
398 callee()->CreateLocalVideoTrack();
399 callee()->AddTrack(callee_track);
400 caller()->CreateAndSetAndSignalOffer();
401 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
402
403 // Ensure that video frames are received end-to-end.
404 MediaExpectations media_expectations;
405 media_expectations.ExpectBidirectionalVideo();
406 ASSERT_TRUE(ExpectNewFrames(media_expectations));
407}
408
409TEST_P(PeerConnectionIntegrationTest,
410 EndToEndCallAddSendVideoToReceiveOnlyCall) {
411 ASSERT_TRUE(CreatePeerConnectionWrappers());
412 ConnectFakeSignaling();
413 // Add one-directional video, from callee to caller.
414 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
415 callee()->CreateLocalVideoTrack();
416 callee()->AddTrack(callee_track);
417 caller()->CreateAndSetAndSignalOffer();
418 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
419
420 // Add send video.
421 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
422 caller()->CreateLocalVideoTrack();
423 caller()->AddTrack(caller_track);
424 caller()->CreateAndSetAndSignalOffer();
425 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
426
427 // Expect video to be received in one direction.
428 MediaExpectations media_expectations;
429 media_expectations.ExpectBidirectionalVideo();
430 ASSERT_TRUE(ExpectNewFrames(media_expectations));
431}
432
433TEST_P(PeerConnectionIntegrationTest,
434 EndToEndCallRemoveReceiveVideoFromSendReceiveCall) {
435 ASSERT_TRUE(CreatePeerConnectionWrappers());
436 ConnectFakeSignaling();
437 // Add send video, from caller to callee.
438 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
439 caller()->CreateLocalVideoTrack();
440 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
441 caller()->AddTrack(caller_track);
442 // Add receive video, from callee to caller.
443 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
444 callee()->CreateLocalVideoTrack();
445
446 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
447 callee()->AddTrack(callee_track);
448 caller()->CreateAndSetAndSignalOffer();
449 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
450
451 // Remove receive video (i.e., callee sender track).
452 callee()->pc()->RemoveTrack(callee_sender);
453
454 caller()->CreateAndSetAndSignalOffer();
455 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
456
457 // Expect one-directional video.
458 MediaExpectations media_expectations;
459 media_expectations.CallerExpectsNoVideo();
460 media_expectations.CalleeExpectsSomeVideo();
461
462 ASSERT_TRUE(ExpectNewFrames(media_expectations));
463}
464
465TEST_P(PeerConnectionIntegrationTest,
466 EndToEndCallRemoveSendVideoFromSendReceiveCall) {
467 ASSERT_TRUE(CreatePeerConnectionWrappers());
468 ConnectFakeSignaling();
469 // Add send video, from caller to callee.
470 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
471 caller()->CreateLocalVideoTrack();
472 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
473 caller()->AddTrack(caller_track);
474 // Add receive video, from callee to caller.
475 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
476 callee()->CreateLocalVideoTrack();
477
478 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
479 callee()->AddTrack(callee_track);
480 caller()->CreateAndSetAndSignalOffer();
481 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
482
483 // Remove send video (i.e., caller sender track).
484 caller()->pc()->RemoveTrack(caller_sender);
485
486 caller()->CreateAndSetAndSignalOffer();
487 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
488
489 // Expect one-directional video.
490 MediaExpectations media_expectations;
491 media_expectations.CalleeExpectsNoVideo();
492 media_expectations.CallerExpectsSomeVideo();
493
494 ASSERT_TRUE(ExpectNewFrames(media_expectations));
495}
496
deadbeef1dcb1642017-03-29 21:08:16 -0700497// This test sets up a audio call initially, with the callee rejecting video
498// initially. Then later the callee decides to upgrade to audio/video, and
499// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800500TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -0700501 ASSERT_TRUE(CreatePeerConnectionWrappers());
502 ConnectFakeSignaling();
503 // Initially, offer an audio/video stream from the caller, but refuse to
504 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -0800505 caller()->AddAudioVideoTracks();
506 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800507 if (sdp_semantics_ == SdpSemantics::kPlanB) {
508 PeerConnectionInterface::RTCOfferAnswerOptions options;
509 options.offer_to_receive_video = 0;
510 callee()->SetOfferAnswerOptions(options);
511 } else {
512 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200513 callee()
514 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
515 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800516 });
517 }
deadbeef1dcb1642017-03-29 21:08:16 -0700518 // Do offer/answer and make sure audio is still received end-to-end.
519 caller()->CreateAndSetAndSignalOffer();
520 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800521 {
522 MediaExpectations media_expectations;
523 media_expectations.ExpectBidirectionalAudio();
524 media_expectations.ExpectNoVideo();
525 ASSERT_TRUE(ExpectNewFrames(media_expectations));
526 }
deadbeef1dcb1642017-03-29 21:08:16 -0700527 // Sanity check that the callee's description has a rejected video section.
528 ASSERT_NE(nullptr, callee()->pc()->local_description());
529 const ContentInfo* callee_video_content =
530 GetFirstVideoContent(callee()->pc()->local_description()->description());
531 ASSERT_NE(nullptr, callee_video_content);
532 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800533
deadbeef1dcb1642017-03-29 21:08:16 -0700534 // Now negotiate with video and ensure negotiation succeeds, with video
535 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -0800536 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800537 if (sdp_semantics_ == SdpSemantics::kPlanB) {
538 PeerConnectionInterface::RTCOfferAnswerOptions options;
539 options.offer_to_receive_video = 1;
540 callee()->SetOfferAnswerOptions(options);
541 } else {
542 callee()->SetRemoteOfferHandler(nullptr);
543 caller()->SetRemoteOfferHandler([this] {
544 // The caller creates a new transceiver to receive video on when receiving
545 // the offer, but by default it is send only.
546 auto transceivers = caller()->pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +0200547 ASSERT_EQ(2U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800548 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
Harald Alvestrand6060df52020-08-11 09:54:02 +0200549 transceivers[1]->receiver()->media_type());
550 transceivers[1]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
551 transceivers[1]->SetDirectionWithError(
552 RtpTransceiverDirection::kSendRecv);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800553 });
554 }
deadbeef1dcb1642017-03-29 21:08:16 -0700555 callee()->CreateAndSetAndSignalOffer();
556 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800557 {
558 // Expect additional audio frames to be received after the upgrade.
559 MediaExpectations media_expectations;
560 media_expectations.ExpectBidirectionalAudioAndVideo();
561 ASSERT_TRUE(ExpectNewFrames(media_expectations));
562 }
deadbeef1dcb1642017-03-29 21:08:16 -0700563}
564
deadbeef4389b4d2017-09-07 09:07:36 -0700565// Simpler than the above test; just add an audio track to an established
566// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800567TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -0700568 ASSERT_TRUE(CreatePeerConnectionWrappers());
569 ConnectFakeSignaling();
570 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -0800571 caller()->AddVideoTrack();
572 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700573 caller()->CreateAndSetAndSignalOffer();
574 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
575 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -0800576 caller()->AddAudioTrack();
577 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700578 caller()->CreateAndSetAndSignalOffer();
579 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
580 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800581 MediaExpectations media_expectations;
582 media_expectations.ExpectBidirectionalAudioAndVideo();
583 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -0700584}
585
deadbeef1dcb1642017-03-29 21:08:16 -0700586// This test sets up a call that's transferred to a new caller with a different
587// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800588TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -0700589 ASSERT_TRUE(CreatePeerConnectionWrappers());
590 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800591 caller()->AddAudioVideoTracks();
592 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700593 caller()->CreateAndSetAndSignalOffer();
594 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
595
596 // Keep the original peer around which will still send packets to the
597 // receiving client. These SRTP packets will be dropped.
Harald Alvestrand39993842021-02-17 09:05:31 +0000598 std::unique_ptr<PeerConnectionIntegrationWrapper> original_peer(
deadbeef1dcb1642017-03-29 21:08:16 -0700599 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -0800600 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -0700601 // TODO(deadbeef): Why do we call Close here? That goes against the comment
602 // directly above.
603 original_peer->pc()->Close();
604
605 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800606 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700607 caller()->CreateAndSetAndSignalOffer();
608 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
609 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800610 MediaExpectations media_expectations;
611 media_expectations.ExpectBidirectionalAudioAndVideo();
612 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700613}
614
615// This test sets up a call that's transferred to a new callee with a different
616// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800617TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -0700618 ASSERT_TRUE(CreatePeerConnectionWrappers());
619 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800620 caller()->AddAudioVideoTracks();
621 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700622 caller()->CreateAndSetAndSignalOffer();
623 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
624
625 // Keep the original peer around which will still send packets to the
626 // receiving client. These SRTP packets will be dropped.
Harald Alvestrand39993842021-02-17 09:05:31 +0000627 std::unique_ptr<PeerConnectionIntegrationWrapper> original_peer(
deadbeef1dcb1642017-03-29 21:08:16 -0700628 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -0800629 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -0700630 // TODO(deadbeef): Why do we call Close here? That goes against the comment
631 // directly above.
632 original_peer->pc()->Close();
633
634 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800635 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700636 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
637 caller()->CreateAndSetAndSignalOffer();
638 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
639 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800640 MediaExpectations media_expectations;
641 media_expectations.ExpectBidirectionalAudioAndVideo();
642 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700643}
644
645// This test sets up a non-bundled call and negotiates bundling at the same
646// time as starting an ICE restart. When bundling is in effect in the restart,
647// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800648TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -0700649 ASSERT_TRUE(CreatePeerConnectionWrappers());
650 ConnectFakeSignaling();
651
Steve Anton15324772018-01-16 10:26:49 -0800652 caller()->AddAudioVideoTracks();
653 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700654 // Remove the bundle group from the SDP received by the callee.
655 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
656 desc->RemoveGroupByName("BUNDLE");
657 });
658 caller()->CreateAndSetAndSignalOffer();
659 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800660 {
661 MediaExpectations media_expectations;
662 media_expectations.ExpectBidirectionalAudioAndVideo();
663 ASSERT_TRUE(ExpectNewFrames(media_expectations));
664 }
deadbeef1dcb1642017-03-29 21:08:16 -0700665 // Now stop removing the BUNDLE group, and trigger an ICE restart.
666 callee()->SetReceivedSdpMunger(nullptr);
667 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
668 caller()->CreateAndSetAndSignalOffer();
669 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
670
671 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800672 {
673 MediaExpectations media_expectations;
674 media_expectations.ExpectBidirectionalAudioAndVideo();
675 ASSERT_TRUE(ExpectNewFrames(media_expectations));
676 }
deadbeef1dcb1642017-03-29 21:08:16 -0700677}
678
679// Test CVO (Coordination of Video Orientation). If a video source is rotated
680// and both peers support the CVO RTP header extension, the actual video frames
681// don't need to be encoded in different resolutions, since the rotation is
682// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800683TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700684 ASSERT_TRUE(CreatePeerConnectionWrappers());
685 ConnectFakeSignaling();
686 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800687 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700688 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800689 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700690 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
691
692 // Wait for video frames to be received by both sides.
693 caller()->CreateAndSetAndSignalOffer();
694 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
695 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
696 callee()->min_video_frames_received_per_track() > 0,
697 kMaxWaitForFramesMs);
698
699 // Ensure that the aspect ratio is unmodified.
700 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
701 // not just assumed.
702 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
703 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
704 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
705 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
706 // Ensure that the CVO bits were surfaced to the renderer.
707 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
708 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
709}
710
711// Test that when the CVO extension isn't supported, video is rotated the
712// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800713TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700714 ASSERT_TRUE(CreatePeerConnectionWrappers());
715 ConnectFakeSignaling();
716 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800717 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700718 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800719 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700720 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
721
722 // Remove the CVO extension from the offered SDP.
723 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
724 cricket::VideoContentDescription* video =
725 GetFirstVideoContentDescription(desc);
726 video->ClearRtpHeaderExtensions();
727 });
728 // Wait for video frames to be received by both sides.
729 caller()->CreateAndSetAndSignalOffer();
730 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
731 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
732 callee()->min_video_frames_received_per_track() > 0,
733 kMaxWaitForFramesMs);
734
735 // Expect that the aspect ratio is inversed to account for the 90/270 degree
736 // rotation.
737 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
738 // not just assumed.
739 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
740 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
741 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
742 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
743 // Expect that each endpoint is unaware of the rotation of the other endpoint.
744 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
745 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
746}
747
deadbeef1dcb1642017-03-29 21:08:16 -0700748// Test that if the answerer rejects the audio m= section, no audio is sent or
749// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800750TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700751 ASSERT_TRUE(CreatePeerConnectionWrappers());
752 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800753 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800754 if (sdp_semantics_ == SdpSemantics::kPlanB) {
755 // Only add video track for callee, and set offer_to_receive_audio to 0, so
756 // it will reject the audio m= section completely.
757 PeerConnectionInterface::RTCOfferAnswerOptions options;
758 options.offer_to_receive_audio = 0;
759 callee()->SetOfferAnswerOptions(options);
760 } else {
761 // Stopping the audio RtpTransceiver will cause the media section to be
762 // rejected in the answer.
763 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200764 callee()
765 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
766 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800767 });
768 }
Steve Anton15324772018-01-16 10:26:49 -0800769 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700770 // Do offer/answer and wait for successful end-to-end video frames.
771 caller()->CreateAndSetAndSignalOffer();
772 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800773 MediaExpectations media_expectations;
774 media_expectations.ExpectBidirectionalVideo();
775 media_expectations.ExpectNoAudio();
776 ASSERT_TRUE(ExpectNewFrames(media_expectations));
777
deadbeef1dcb1642017-03-29 21:08:16 -0700778 // Sanity check that the callee's description has a rejected audio section.
779 ASSERT_NE(nullptr, callee()->pc()->local_description());
780 const ContentInfo* callee_audio_content =
781 GetFirstAudioContent(callee()->pc()->local_description()->description());
782 ASSERT_NE(nullptr, callee_audio_content);
783 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800784 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200785 // The caller's transceiver should have stopped after receiving the answer,
786 // and thus no longer listed in transceivers.
787 EXPECT_EQ(nullptr,
788 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800789 }
deadbeef1dcb1642017-03-29 21:08:16 -0700790}
791
792// Test that if the answerer rejects the video m= section, no video is sent or
793// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800794TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700795 ASSERT_TRUE(CreatePeerConnectionWrappers());
796 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800797 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800798 if (sdp_semantics_ == SdpSemantics::kPlanB) {
799 // Only add audio track for callee, and set offer_to_receive_video to 0, so
800 // it will reject the video m= section completely.
801 PeerConnectionInterface::RTCOfferAnswerOptions options;
802 options.offer_to_receive_video = 0;
803 callee()->SetOfferAnswerOptions(options);
804 } else {
805 // Stopping the video RtpTransceiver will cause the media section to be
806 // rejected in the answer.
807 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200808 callee()
809 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
810 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800811 });
812 }
Steve Anton15324772018-01-16 10:26:49 -0800813 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700814 // Do offer/answer and wait for successful end-to-end audio frames.
815 caller()->CreateAndSetAndSignalOffer();
816 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800817 MediaExpectations media_expectations;
818 media_expectations.ExpectBidirectionalAudio();
819 media_expectations.ExpectNoVideo();
820 ASSERT_TRUE(ExpectNewFrames(media_expectations));
821
deadbeef1dcb1642017-03-29 21:08:16 -0700822 // Sanity check that the callee's description has a rejected video section.
823 ASSERT_NE(nullptr, callee()->pc()->local_description());
824 const ContentInfo* callee_video_content =
825 GetFirstVideoContent(callee()->pc()->local_description()->description());
826 ASSERT_NE(nullptr, callee_video_content);
827 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800828 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200829 // The caller's transceiver should have stopped after receiving the answer,
830 // and thus is no longer present.
831 EXPECT_EQ(nullptr,
832 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800833 }
deadbeef1dcb1642017-03-29 21:08:16 -0700834}
835
836// Test that if the answerer rejects both audio and video m= sections, nothing
837// bad happens.
838// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
839// test anything but the fact that negotiation succeeds, which doesn't mean
840// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800841TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -0700842 ASSERT_TRUE(CreatePeerConnectionWrappers());
843 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800844 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800845 if (sdp_semantics_ == SdpSemantics::kPlanB) {
846 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
847 // will reject both audio and video m= sections.
848 PeerConnectionInterface::RTCOfferAnswerOptions options;
849 options.offer_to_receive_audio = 0;
850 options.offer_to_receive_video = 0;
851 callee()->SetOfferAnswerOptions(options);
852 } else {
853 callee()->SetRemoteOfferHandler([this] {
854 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +0100855 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200856 transceiver->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800857 }
858 });
859 }
deadbeef1dcb1642017-03-29 21:08:16 -0700860 // Do offer/answer and wait for stable signaling state.
861 caller()->CreateAndSetAndSignalOffer();
862 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800863
deadbeef1dcb1642017-03-29 21:08:16 -0700864 // Sanity check that the callee's description has rejected m= sections.
865 ASSERT_NE(nullptr, callee()->pc()->local_description());
866 const ContentInfo* callee_audio_content =
867 GetFirstAudioContent(callee()->pc()->local_description()->description());
868 ASSERT_NE(nullptr, callee_audio_content);
869 EXPECT_TRUE(callee_audio_content->rejected);
870 const ContentInfo* callee_video_content =
871 GetFirstVideoContent(callee()->pc()->local_description()->description());
872 ASSERT_NE(nullptr, callee_video_content);
873 EXPECT_TRUE(callee_video_content->rejected);
874}
875
876// This test sets up an audio and video call between two parties. After the
877// call runs for a while, the caller sends an updated offer with video being
878// rejected. Once the re-negotiation is done, the video flow should stop and
879// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800880TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700881 ASSERT_TRUE(CreatePeerConnectionWrappers());
882 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800883 caller()->AddAudioVideoTracks();
884 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700885 caller()->CreateAndSetAndSignalOffer();
886 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800887 {
888 MediaExpectations media_expectations;
889 media_expectations.ExpectBidirectionalAudioAndVideo();
890 ASSERT_TRUE(ExpectNewFrames(media_expectations));
891 }
deadbeef1dcb1642017-03-29 21:08:16 -0700892 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800893 if (sdp_semantics_ == SdpSemantics::kPlanB) {
894 caller()->SetGeneratedSdpMunger(
895 [](cricket::SessionDescription* description) {
896 for (cricket::ContentInfo& content : description->contents()) {
897 if (cricket::IsVideoContent(&content)) {
898 content.rejected = true;
899 }
900 }
901 });
902 } else {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200903 caller()
904 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
905 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800906 }
deadbeef1dcb1642017-03-29 21:08:16 -0700907 caller()->CreateAndSetAndSignalOffer();
908 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
909
910 // Sanity check that the caller's description has a rejected video section.
911 ASSERT_NE(nullptr, caller()->pc()->local_description());
912 const ContentInfo* caller_video_content =
913 GetFirstVideoContent(caller()->pc()->local_description()->description());
914 ASSERT_NE(nullptr, caller_video_content);
915 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -0700916 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800917 {
918 MediaExpectations media_expectations;
919 media_expectations.ExpectBidirectionalAudio();
920 media_expectations.ExpectNoVideo();
921 ASSERT_TRUE(ExpectNewFrames(media_expectations));
922 }
deadbeef1dcb1642017-03-29 21:08:16 -0700923}
924
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700925// Do one offer/answer with audio, another that disables it (rejecting the m=
926// section), and another that re-enables it. Regression test for:
927// bugs.webrtc.org/6023
928TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
929 ASSERT_TRUE(CreatePeerConnectionWrappers());
930 ConnectFakeSignaling();
931
932 // Add audio track, do normal offer/answer.
933 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
934 caller()->CreateLocalAudioTrack();
935 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
936 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
937 caller()->CreateAndSetAndSignalOffer();
938 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
939
940 // Remove audio track, and set offer_to_receive_audio to false to cause the
941 // m= section to be completely disabled, not just "recvonly".
942 caller()->pc()->RemoveTrack(sender);
943 PeerConnectionInterface::RTCOfferAnswerOptions options;
944 options.offer_to_receive_audio = 0;
945 caller()->SetOfferAnswerOptions(options);
946 caller()->CreateAndSetAndSignalOffer();
947 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
948
949 // Add the audio track again, expecting negotiation to succeed and frames to
950 // flow.
951 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
952 options.offer_to_receive_audio = 1;
953 caller()->SetOfferAnswerOptions(options);
954 caller()->CreateAndSetAndSignalOffer();
955 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
956
957 MediaExpectations media_expectations;
958 media_expectations.CalleeExpectsSomeAudio();
959 EXPECT_TRUE(ExpectNewFrames(media_expectations));
960}
961
deadbeef1dcb1642017-03-29 21:08:16 -0700962// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
963// is needed to support legacy endpoints.
964// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
965// add a test for an end-to-end test without MID signaling either (basically,
966// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800967TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -0700968 ASSERT_TRUE(CreatePeerConnectionWrappers());
969 ConnectFakeSignaling();
970 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -0800971 caller()->AddAudioVideoTracks();
972 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -0700973 // Remove SSRCs and MSIDs from the received offer SDP.
974 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -0700975 caller()->CreateAndSetAndSignalOffer();
976 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800977 MediaExpectations media_expectations;
978 media_expectations.ExpectBidirectionalAudioAndVideo();
979 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700980}
981
Seth Hampson5897a6e2018-04-03 11:16:33 -0700982// Basic end-to-end test, without SSRC signaling. This means that the track
983// was created properly and frames are delivered when the MSIDs are communicated
984// with a=msid lines and no a=ssrc lines.
985TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
986 EndToEndCallWithoutSsrcSignaling) {
987 const char kStreamId[] = "streamId";
988 ASSERT_TRUE(CreatePeerConnectionWrappers());
989 ConnectFakeSignaling();
990 // Add just audio tracks.
991 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
992 callee()->AddAudioTrack();
993
994 // Remove SSRCs from the received offer SDP.
995 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
996 caller()->CreateAndSetAndSignalOffer();
997 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
998 MediaExpectations media_expectations;
999 media_expectations.ExpectBidirectionalAudio();
1000 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1001}
1002
Johannes Kron3e983682020-03-29 22:17:00 +02001003TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1004 EndToEndCallAddReceiveVideoToSendOnlyCall) {
1005 ASSERT_TRUE(CreatePeerConnectionWrappers());
1006 ConnectFakeSignaling();
1007 // Add one-directional video, from caller to callee.
1008 rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
1009 caller()->CreateLocalVideoTrack();
1010
1011 RtpTransceiverInit video_transceiver_init;
1012 video_transceiver_init.stream_ids = {"video1"};
1013 video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly;
1014 auto video_sender =
1015 caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue();
1016 caller()->CreateAndSetAndSignalOffer();
1017 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1018
1019 // Add receive direction.
Harald Alvestrand6060df52020-08-11 09:54:02 +02001020 video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);
Johannes Kron3e983682020-03-29 22:17:00 +02001021
1022 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
1023 callee()->CreateLocalVideoTrack();
1024
1025 callee()->AddTrack(callee_track);
1026 caller()->CreateAndSetAndSignalOffer();
1027 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1028 // Ensure that video frames are received end-to-end.
1029 MediaExpectations media_expectations;
1030 media_expectations.ExpectBidirectionalVideo();
1031 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1032}
1033
Steve Antondf527fd2018-04-27 15:52:03 -07001034// Tests that video flows between multiple video tracks when SSRCs are not
1035// signaled. This exercises the MID RTP header extension which is needed to
1036// demux the incoming video tracks.
1037TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1038 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
1039 ASSERT_TRUE(CreatePeerConnectionWrappers());
1040 ConnectFakeSignaling();
1041 caller()->AddVideoTrack();
1042 caller()->AddVideoTrack();
1043 callee()->AddVideoTrack();
1044 callee()->AddVideoTrack();
1045
1046 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1047 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1048 caller()->CreateAndSetAndSignalOffer();
1049 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1050 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1051 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1052
1053 // Expect video to be received in both directions on both tracks.
1054 MediaExpectations media_expectations;
1055 media_expectations.ExpectBidirectionalVideo();
1056 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1057}
1058
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -07001059// Used for the test below.
1060void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
1061 RemoveSsrcsAndKeepMsids(desc);
1062 desc->RemoveGroupByName("BUNDLE");
1063 for (ContentInfo& content : desc->contents()) {
1064 cricket::MediaContentDescription* media = content.media_description();
1065 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1066 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1067 [](const RtpExtension& extension) {
1068 return extension.uri ==
1069 RtpExtension::kMidUri;
1070 }),
1071 extensions.end());
1072 media->set_rtp_header_extensions(extensions);
1073 }
1074}
1075
1076// Tests that video flows between multiple video tracks when BUNDLE is not used,
1077// SSRCs are not signaled and the MID RTP header extension is not used. This
1078// relies on demuxing by payload type, which normally doesn't work if you have
1079// multiple media sections using the same payload type, but which should work as
1080// long as the media sections aren't bundled.
1081// Regression test for: http://crbug.com/webrtc/12023
1082TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1083 EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid) {
1084 ASSERT_TRUE(CreatePeerConnectionWrappers());
1085 ConnectFakeSignaling();
1086 caller()->AddVideoTrack();
1087 caller()->AddVideoTrack();
1088 callee()->AddVideoTrack();
1089 callee()->AddVideoTrack();
1090 caller()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1091 callee()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1092 caller()->CreateAndSetAndSignalOffer();
1093 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1094 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1095 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1096 // Make sure we are not bundled.
1097 ASSERT_NE(caller()->pc()->GetSenders()[0]->dtls_transport(),
1098 caller()->pc()->GetSenders()[1]->dtls_transport());
1099
1100 // Expect video to be received in both directions on both tracks.
1101 MediaExpectations media_expectations;
1102 media_expectations.ExpectBidirectionalVideo();
1103 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1104}
1105
1106// Used for the test below.
1107void ModifyPayloadTypesAndRemoveMidExtension(
1108 cricket::SessionDescription* desc) {
1109 int pt = 96;
1110 for (ContentInfo& content : desc->contents()) {
1111 cricket::MediaContentDescription* media = content.media_description();
1112 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1113 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1114 [](const RtpExtension& extension) {
1115 return extension.uri ==
1116 RtpExtension::kMidUri;
1117 }),
1118 extensions.end());
1119 media->set_rtp_header_extensions(extensions);
1120 cricket::VideoContentDescription* video = media->as_video();
1121 ASSERT_TRUE(video != nullptr);
1122 std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
1123 video->set_codecs(codecs);
1124 }
1125}
1126
1127// Tests that two video tracks can be demultiplexed by payload type alone, by
1128// using different payload types for the same codec in different m= sections.
1129// This practice is discouraged but historically has been supported.
1130// Regression test for: http://crbug.com/webrtc/12029
1131TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1132 EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType) {
1133 ASSERT_TRUE(CreatePeerConnectionWrappers());
1134 ConnectFakeSignaling();
1135 caller()->AddVideoTrack();
1136 caller()->AddVideoTrack();
1137 callee()->AddVideoTrack();
1138 callee()->AddVideoTrack();
1139 caller()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1140 callee()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1141 // We can't remove SSRCs from the generated SDP because then no send streams
1142 // would be created.
1143 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1144 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1145 caller()->CreateAndSetAndSignalOffer();
1146 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1147 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1148 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1149 // Make sure we are bundled.
1150 ASSERT_EQ(caller()->pc()->GetSenders()[0]->dtls_transport(),
1151 caller()->pc()->GetSenders()[1]->dtls_transport());
1152
1153 // Expect video to be received in both directions on both tracks.
1154 MediaExpectations media_expectations;
1155 media_expectations.ExpectBidirectionalVideo();
1156 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1157}
1158
Henrik Boström5b147782018-12-04 11:25:05 +01001159TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
1160 ASSERT_TRUE(CreatePeerConnectionWrappers());
1161 ConnectFakeSignaling();
1162 caller()->AddAudioTrack();
1163 caller()->AddVideoTrack();
1164 caller()->CreateAndSetAndSignalOffer();
1165 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1166 auto callee_receivers = callee()->pc()->GetReceivers();
1167 ASSERT_EQ(2u, callee_receivers.size());
1168 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
1169 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
1170}
1171
1172TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
1173 ASSERT_TRUE(CreatePeerConnectionWrappers());
1174 ConnectFakeSignaling();
1175 caller()->AddAudioTrack();
1176 caller()->AddVideoTrack();
1177 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1178 caller()->CreateAndSetAndSignalOffer();
1179 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1180 auto callee_receivers = callee()->pc()->GetReceivers();
1181 ASSERT_EQ(2u, callee_receivers.size());
1182 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
1183 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
1184 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
1185 callee_receivers[1]->stream_ids()[0]);
1186 EXPECT_EQ(callee_receivers[0]->streams()[0],
1187 callee_receivers[1]->streams()[0]);
1188}
1189
deadbeef1dcb1642017-03-29 21:08:16 -07001190// Test that if two video tracks are sent (from caller to callee, in this test),
1191// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001192TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07001193 ASSERT_TRUE(CreatePeerConnectionWrappers());
1194 ConnectFakeSignaling();
1195 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08001196 caller()->AddAudioVideoTracks();
1197 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001198 caller()->CreateAndSetAndSignalOffer();
1199 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08001200 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08001201
1202 MediaExpectations media_expectations;
1203 media_expectations.CalleeExpectsSomeAudioAndVideo();
1204 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001205}
1206
1207static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
1208 bool first = true;
1209 for (cricket::ContentInfo& content : desc->contents()) {
1210 if (first) {
1211 first = false;
1212 continue;
1213 }
1214 content.bundle_only = true;
1215 }
1216 first = true;
1217 for (cricket::TransportInfo& transport : desc->transport_infos()) {
1218 if (first) {
1219 first = false;
1220 continue;
1221 }
1222 transport.description.ice_ufrag.clear();
1223 transport.description.ice_pwd.clear();
1224 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
1225 transport.description.identity_fingerprint.reset(nullptr);
1226 }
1227}
1228
1229// Test that if applying a true "max bundle" offer, which uses ports of 0,
1230// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
1231// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
1232// successfully and media flows.
1233// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
1234// TODO(deadbeef): Won't need this test once we start generating actual
1235// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001236TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001237 EndToEndCallWithSpecCompliantMaxBundleOffer) {
1238 ASSERT_TRUE(CreatePeerConnectionWrappers());
1239 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001240 caller()->AddAudioVideoTracks();
1241 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001242 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
1243 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
1244 // but the first m= section.
1245 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
1246 caller()->CreateAndSetAndSignalOffer();
1247 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001248 MediaExpectations media_expectations;
1249 media_expectations.ExpectBidirectionalAudioAndVideo();
1250 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001251}
1252
1253// Test that we can receive the audio output level from a remote audio track.
1254// TODO(deadbeef): Use a fake audio source and verify that the output level is
1255// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001256TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001257 ASSERT_TRUE(CreatePeerConnectionWrappers());
1258 ConnectFakeSignaling();
1259 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001260 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001261 caller()->CreateAndSetAndSignalOffer();
1262 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1263
1264 // Get the audio output level stats. Note that the level is not available
1265 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07001266 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001267 kMaxWaitForFramesMs);
1268}
1269
1270// Test that an audio input level is reported.
1271// TODO(deadbeef): Use a fake audio source and verify that the input level is
1272// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001273TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001274 ASSERT_TRUE(CreatePeerConnectionWrappers());
1275 ConnectFakeSignaling();
1276 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001277 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001278 caller()->CreateAndSetAndSignalOffer();
1279 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1280
1281 // Get the audio input level stats. The level should be available very
1282 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07001283 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001284 kMaxWaitForStatsMs);
1285}
1286
1287// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001288TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001289 ASSERT_TRUE(CreatePeerConnectionWrappers());
1290 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001291 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001292 // Do offer/answer, wait for the callee to receive some frames.
1293 caller()->CreateAndSetAndSignalOffer();
1294 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001295
1296 MediaExpectations media_expectations;
1297 media_expectations.CalleeExpectsSomeAudioAndVideo();
1298 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001299
1300 // Get a handle to the remote tracks created, so they can be used as GetStats
1301 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01001302 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08001303 // We received frames, so we definitely should have nonzero "received bytes"
1304 // stats at this point.
1305 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
1306 0);
1307 }
deadbeef1dcb1642017-03-29 21:08:16 -07001308}
1309
1310// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001311TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001312 ASSERT_TRUE(CreatePeerConnectionWrappers());
1313 ConnectFakeSignaling();
1314 auto audio_track = caller()->CreateLocalAudioTrack();
1315 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08001316 caller()->AddTrack(audio_track);
1317 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07001318 // Do offer/answer, wait for the callee to receive some frames.
1319 caller()->CreateAndSetAndSignalOffer();
1320 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001321 MediaExpectations media_expectations;
1322 media_expectations.CalleeExpectsSomeAudioAndVideo();
1323 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001324
1325 // The callee received frames, so we definitely should have nonzero "sent
1326 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07001327 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
1328 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
1329}
1330
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001331// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001332TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001333 ASSERT_TRUE(CreatePeerConnectionWrappers());
1334 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001335 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001336
Steve Anton15324772018-01-16 10:26:49 -08001337 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001338
1339 // Do offer/answer, wait for the callee to receive some frames.
1340 caller()->CreateAndSetAndSignalOffer();
1341 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1342
1343 // Get the remote audio track created on the receiver, so they can be used as
1344 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08001345 auto receivers = callee()->pc()->GetReceivers();
1346 ASSERT_EQ(1u, receivers.size());
1347 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001348
1349 // Get the audio output level stats. Note that the level is not available
1350 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07001351 EXPECT_TRUE_WAIT(
1352 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
1353 0,
1354 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001355}
1356
Steve Antona41959e2018-11-28 11:15:33 -08001357// Test that the track ID is associated with all local and remote SSRC stats
1358// using the old GetStats() and more than 1 audio and more than 1 video track.
1359// This is a regression test for crbug.com/906988
1360TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1361 OldGetStatsAssociatesTrackIdForManyMediaSections) {
1362 ASSERT_TRUE(CreatePeerConnectionWrappers());
1363 ConnectFakeSignaling();
1364 auto audio_sender_1 = caller()->AddAudioTrack();
1365 auto video_sender_1 = caller()->AddVideoTrack();
1366 auto audio_sender_2 = caller()->AddAudioTrack();
1367 auto video_sender_2 = caller()->AddVideoTrack();
1368 caller()->CreateAndSetAndSignalOffer();
1369 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1370
1371 MediaExpectations media_expectations;
1372 media_expectations.CalleeExpectsSomeAudioAndVideo();
1373 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1374
1375 std::vector<std::string> track_ids = {
1376 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1377 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1378
1379 auto caller_stats = caller()->OldGetStats();
1380 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1381 auto callee_stats = callee()->OldGetStats();
1382 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1383}
1384
Steve Antonffa6ce42018-11-30 09:26:08 -08001385// Test that the new GetStats() returns stats for all outgoing/incoming streams
1386// with the correct track IDs if there are more than one audio and more than one
1387// video senders/receivers.
1388TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
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 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
1407 caller()->NewGetStats();
1408 ASSERT_TRUE(caller_report);
1409 auto outbound_stream_stats =
1410 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
Henrik Boströma0ff50c2020-05-05 15:54:46 +02001411 ASSERT_EQ(outbound_stream_stats.size(), 4u);
Steve Antonffa6ce42018-11-30 09:26:08 -08001412 std::vector<std::string> outbound_track_ids;
1413 for (const auto& stat : outbound_stream_stats) {
1414 ASSERT_TRUE(stat->bytes_sent.is_defined());
1415 EXPECT_LT(0u, *stat->bytes_sent);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001416 if (*stat->kind == "video") {
1417 ASSERT_TRUE(stat->key_frames_encoded.is_defined());
1418 EXPECT_GT(*stat->key_frames_encoded, 0u);
1419 ASSERT_TRUE(stat->frames_encoded.is_defined());
1420 EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
1421 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001422 ASSERT_TRUE(stat->track_id.is_defined());
1423 const auto* track_stat =
1424 caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1425 ASSERT_TRUE(track_stat);
1426 outbound_track_ids.push_back(*track_stat->track_identifier);
1427 }
1428 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
1429
1430 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
1431 callee()->NewGetStats();
1432 ASSERT_TRUE(callee_report);
1433 auto inbound_stream_stats =
1434 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1435 ASSERT_EQ(4u, inbound_stream_stats.size());
1436 std::vector<std::string> inbound_track_ids;
1437 for (const auto& stat : inbound_stream_stats) {
1438 ASSERT_TRUE(stat->bytes_received.is_defined());
1439 EXPECT_LT(0u, *stat->bytes_received);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001440 if (*stat->kind == "video") {
1441 ASSERT_TRUE(stat->key_frames_decoded.is_defined());
1442 EXPECT_GT(*stat->key_frames_decoded, 0u);
1443 ASSERT_TRUE(stat->frames_decoded.is_defined());
1444 EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
1445 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001446 ASSERT_TRUE(stat->track_id.is_defined());
1447 const auto* track_stat =
1448 callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1449 ASSERT_TRUE(track_stat);
1450 inbound_track_ids.push_back(*track_stat->track_identifier);
1451 }
1452 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
1453}
1454
1455// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07001456// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
1457// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001458TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07001459 GetStatsForUnsignaledStreamWithNewStatsApi) {
1460 ASSERT_TRUE(CreatePeerConnectionWrappers());
1461 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001462 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07001463 // Remove SSRCs and MSIDs from the received offer SDP.
1464 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1465 caller()->CreateAndSetAndSignalOffer();
1466 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001467 MediaExpectations media_expectations;
1468 media_expectations.CalleeExpectsSomeAudio(1);
1469 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07001470
1471 // We received a frame, so we should have nonzero "bytes received" stats for
1472 // the unsignaled stream, if stats are working for it.
1473 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1474 callee()->NewGetStats();
1475 ASSERT_NE(nullptr, report);
1476 auto inbound_stream_stats =
1477 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1478 ASSERT_EQ(1U, inbound_stream_stats.size());
1479 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
1480 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07001481 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
1482}
1483
Taylor Brandstettera4653442018-06-19 09:44:26 -07001484// Same as above but for the legacy stats implementation.
1485TEST_P(PeerConnectionIntegrationTest,
1486 GetStatsForUnsignaledStreamWithOldStatsApi) {
1487 ASSERT_TRUE(CreatePeerConnectionWrappers());
1488 ConnectFakeSignaling();
1489 caller()->AddAudioTrack();
1490 // Remove SSRCs and MSIDs from the received offer SDP.
1491 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1492 caller()->CreateAndSetAndSignalOffer();
1493 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1494
1495 // Note that, since the old stats implementation associates SSRCs with tracks
1496 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
1497 // associated track ID. So we can't use the track "selector" argument.
1498 //
1499 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
1500 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001501 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07001502 kDefaultTimeout);
1503}
1504
zhihuangf8164932017-05-19 13:09:47 -07001505// Test that we can successfully get the media related stats (audio level
1506// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001507TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07001508 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
1509 ASSERT_TRUE(CreatePeerConnectionWrappers());
1510 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001511 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07001512 // Remove SSRCs and MSIDs from the received offer SDP.
1513 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1514 caller()->CreateAndSetAndSignalOffer();
1515 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001516 MediaExpectations media_expectations;
1517 media_expectations.CalleeExpectsSomeAudio(1);
1518 media_expectations.CalleeExpectsSomeVideo(1);
1519 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07001520
1521 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1522 callee()->NewGetStats();
1523 ASSERT_NE(nullptr, report);
1524
1525 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1526 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
1527 ASSERT_GE(audio_index, 0);
1528 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07001529}
1530
deadbeef4e2deab2017-09-20 13:56:21 -07001531// Helper for test below.
1532void ModifySsrcs(cricket::SessionDescription* desc) {
1533 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07001534 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08001535 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07001536 for (uint32_t& ssrc : stream.ssrcs) {
1537 ssrc = rtc::CreateRandomId();
1538 }
1539 }
1540 }
1541}
1542
1543// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
1544// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
1545// This should result in two "RTCInboundRTPStreamStats", but only one
1546// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
1547// being reset to 0 once the SSRC change occurs.
1548//
1549// Regression test for this bug:
1550// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
1551//
1552// The bug causes the track stats to only represent one of the two streams:
1553// whichever one has the higher SSRC. So with this bug, there was a 50% chance
1554// that the track stat counters would reset to 0 when the new stream is
1555// received, and a 50% chance that they'll stop updating (while
1556// "concealed_samples" continues increasing, due to silence being generated for
1557// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001558TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08001559 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07001560 ASSERT_TRUE(CreatePeerConnectionWrappers());
1561 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001562 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07001563 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
1564 // that doesn't signal SSRCs (from the callee's perspective).
1565 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1566 caller()->CreateAndSetAndSignalOffer();
1567 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1568 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001569 {
1570 MediaExpectations media_expectations;
1571 media_expectations.CalleeExpectsSomeAudio(50);
1572 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1573 }
deadbeef4e2deab2017-09-20 13:56:21 -07001574 // Some audio frames were received, so we should have nonzero "samples
1575 // received" for the track.
1576 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1577 callee()->NewGetStats();
1578 ASSERT_NE(nullptr, report);
1579 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1580 ASSERT_EQ(1U, track_stats.size());
1581 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1582 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
1583 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
1584
1585 // Create a new offer and munge it to cause the caller to use a new SSRC.
1586 caller()->SetGeneratedSdpMunger(ModifySsrcs);
1587 caller()->CreateAndSetAndSignalOffer();
1588 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1589 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
1590 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001591 {
1592 MediaExpectations media_expectations;
1593 media_expectations.CalleeExpectsSomeAudio(25);
1594 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1595 }
deadbeef4e2deab2017-09-20 13:56:21 -07001596
1597 report = callee()->NewGetStats();
1598 ASSERT_NE(nullptr, report);
1599 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1600 ASSERT_EQ(1U, track_stats.size());
1601 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1602 // The "total samples received" stat should only be greater than it was
1603 // before.
1604 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
1605 // Right now, the new SSRC will cause the counters to reset to 0.
1606 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
1607
1608 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08001609 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07001610 // good sign that we're seeing stats from the old stream that's no longer
1611 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08001612 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07001613 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
1614 EXPECT_LT(*track_stats[0]->concealed_samples,
1615 *track_stats[0]->total_samples_received *
1616 kAcceptableConcealedSamplesPercentage);
1617
1618 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
1619 // sanity check that the SSRC really changed.
1620 // TODO(deadbeef): This isn't working right now, because we're not returning
1621 // *any* stats for the inactive stream. Uncomment when the bug is completely
1622 // fixed.
1623 // auto inbound_stream_stats =
1624 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1625 // ASSERT_EQ(2U, inbound_stream_stats.size());
1626}
1627
deadbeef1dcb1642017-03-29 21:08:16 -07001628// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001629TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001630 PeerConnectionFactory::Options dtls_10_options;
1631 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1632 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1633 dtls_10_options));
1634 ConnectFakeSignaling();
1635 // Do normal offer/answer and wait for some frames to be received in each
1636 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001637 caller()->AddAudioVideoTracks();
1638 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001639 caller()->CreateAndSetAndSignalOffer();
1640 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001641 MediaExpectations media_expectations;
1642 media_expectations.ExpectBidirectionalAudioAndVideo();
1643 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001644}
1645
1646// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001647TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001648 PeerConnectionFactory::Options dtls_10_options;
1649 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1650 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1651 dtls_10_options));
1652 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001653 caller()->AddAudioVideoTracks();
1654 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001655 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001656 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001657 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001658 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001659 kDefaultTimeout);
1660 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001661 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001662 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001663 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1664 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1665 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001666}
1667
1668// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001669TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001670 PeerConnectionFactory::Options dtls_12_options;
1671 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1672 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
1673 dtls_12_options));
1674 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001675 caller()->AddAudioVideoTracks();
1676 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001677 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001678 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001679 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001680 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001681 kDefaultTimeout);
1682 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001683 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001684 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001685 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1686 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1687 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001688}
1689
1690// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
1691// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001692TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001693 PeerConnectionFactory::Options caller_options;
1694 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1695 PeerConnectionFactory::Options callee_options;
1696 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1697 ASSERT_TRUE(
1698 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1699 ConnectFakeSignaling();
1700 // Do normal offer/answer and wait for some frames to be received in each
1701 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001702 caller()->AddAudioVideoTracks();
1703 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001704 caller()->CreateAndSetAndSignalOffer();
1705 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001706 MediaExpectations media_expectations;
1707 media_expectations.ExpectBidirectionalAudioAndVideo();
1708 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001709}
1710
1711// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
1712// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001713TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07001714 PeerConnectionFactory::Options caller_options;
1715 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1716 PeerConnectionFactory::Options callee_options;
1717 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1718 ASSERT_TRUE(
1719 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1720 ConnectFakeSignaling();
1721 // Do normal offer/answer and wait for some frames to be received in each
1722 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001723 caller()->AddAudioVideoTracks();
1724 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001725 caller()->CreateAndSetAndSignalOffer();
1726 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001727 MediaExpectations media_expectations;
1728 media_expectations.ExpectBidirectionalAudioAndVideo();
1729 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001730}
1731
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001732// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
1733// works as expected; the cipher should only be used if enabled by both sides.
1734TEST_P(PeerConnectionIntegrationTest,
1735 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
1736 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001737 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001738 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001739 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1740 false;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001741 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001742 TestNegotiatedCipherSuite(caller_options, callee_options,
1743 expected_cipher_suite);
1744}
1745
1746TEST_P(PeerConnectionIntegrationTest,
1747 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
1748 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001749 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1750 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001751 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001752 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001753 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001754 TestNegotiatedCipherSuite(caller_options, callee_options,
1755 expected_cipher_suite);
1756}
1757
1758TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
1759 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001760 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001761 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001762 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001763 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_32;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001764 TestNegotiatedCipherSuite(caller_options, callee_options,
1765 expected_cipher_suite);
1766}
1767
deadbeef1dcb1642017-03-29 21:08:16 -07001768// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001769TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001770 bool local_gcm_enabled = false;
1771 bool remote_gcm_enabled = false;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001772 bool aes_ctr_enabled = true;
deadbeef1dcb1642017-03-29 21:08:16 -07001773 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
1774 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001775 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001776}
1777
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001778// Test that a GCM cipher is used if both ends support it and non-GCM is
1779// disabled.
1780TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001781 bool local_gcm_enabled = true;
1782 bool remote_gcm_enabled = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001783 bool aes_ctr_enabled = false;
deadbeef1dcb1642017-03-29 21:08:16 -07001784 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
1785 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001786 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001787}
1788
deadbeef7914b8c2017-04-21 03:23:33 -07001789// Verify that media can be transmitted end-to-end when GCM crypto suites are
1790// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
1791// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
1792// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001793TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07001794 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001795 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001796 gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false;
deadbeef7914b8c2017-04-21 03:23:33 -07001797 ASSERT_TRUE(
1798 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
1799 ConnectFakeSignaling();
1800 // Do normal offer/answer and wait for some frames to be received in each
1801 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001802 caller()->AddAudioVideoTracks();
1803 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07001804 caller()->CreateAndSetAndSignalOffer();
1805 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001806 MediaExpectations media_expectations;
1807 media_expectations.ExpectBidirectionalAudioAndVideo();
1808 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07001809}
1810
deadbeef1dcb1642017-03-29 21:08:16 -07001811// Test that the ICE connection and gathering states eventually reach
1812// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08001813TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07001814 ASSERT_TRUE(CreatePeerConnectionWrappers());
1815 ConnectFakeSignaling();
1816 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001817 caller()->AddAudioVideoTracks();
1818 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001819 caller()->CreateAndSetAndSignalOffer();
1820 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1821 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1822 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
1823 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1824 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
1825 // After the best candidate pair is selected and all candidates are signaled,
1826 // the ICE connection state should reach "complete".
1827 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
1828 // answerer/"callee" by default) only reaches "connected". When this is
1829 // fixed, this test should be updated.
1830 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1831 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00001832 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1833 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001834}
1835
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001836#if !defined(THREAD_SANITIZER)
1837// This test provokes TSAN errors. See bugs.webrtc.org/3608
1838
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001839constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
1840 cricket::PORTALLOCATOR_DISABLE_RELAY |
1841 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001842
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001843// Use a mock resolver to resolve the hostname back to the original IP on both
1844// sides and check that the ICE connection connects.
Markus Handell56910532021-04-10 11:23:14 +00001845// TODO(bugs.webrtc.org/12590): Flaky on Windows and on Linux MSAN.
1846#if defined(WEBRTC_WIN) || defined(WEBRTC_LINUX)
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001847#define MAYBE_IceStatesReachCompletionWithRemoteHostname \
1848 DISABLED_IceStatesReachCompletionWithRemoteHostname
1849#else
1850#define MAYBE_IceStatesReachCompletionWithRemoteHostname \
1851 IceStatesReachCompletionWithRemoteHostname
1852#endif
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001853TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001854 MAYBE_IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001855 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001856 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001857 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001858 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001859 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
1860 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001861
1862 // This also verifies that the injected AsyncResolverFactory is used by
1863 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001864 EXPECT_CALL(*caller_resolver_factory, Create())
1865 .WillOnce(Return(&caller_async_resolver));
1866 webrtc::PeerConnectionDependencies caller_deps(nullptr);
1867 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
1868
1869 EXPECT_CALL(*callee_resolver_factory, Create())
1870 .WillOnce(Return(&callee_async_resolver));
1871 webrtc::PeerConnectionDependencies callee_deps(nullptr);
1872 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
1873
1874 PeerConnectionInterface::RTCConfiguration config;
1875 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
1876 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
1877
1878 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
1879 config, std::move(caller_deps), config, std::move(callee_deps)));
1880
1881 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
1882 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
1883
1884 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07001885 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001886 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07001887 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001888 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001889
1890 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001891
1892 ConnectFakeSignaling();
1893 caller()->AddAudioVideoTracks();
1894 callee()->AddAudioVideoTracks();
1895 caller()->CreateAndSetAndSignalOffer();
1896 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1897 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1898 caller()->ice_connection_state(), kDefaultTimeout);
1899 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1900 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08001901
Ying Wangef3998f2019-12-09 13:06:53 +01001902 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1903 "WebRTC.PeerConnection.CandidatePairType_UDP",
1904 webrtc::kIceCandidatePairHostNameHostName));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001905}
1906
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001907#endif // !defined(THREAD_SANITIZER)
1908
Steve Antonede9ca52017-10-16 13:04:27 -07001909// Test that firewalling the ICE connection causes the clients to identify the
1910// disconnected state and then removing the firewall causes them to reconnect.
1911class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08001912 : public PeerConnectionIntegrationBaseTest,
1913 public ::testing::WithParamInterface<
1914 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07001915 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001916 PeerConnectionIntegrationIceStatesTest()
1917 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
1918 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07001919 }
1920
1921 void StartStunServer(const SocketAddress& server_address) {
1922 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01001923 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07001924 }
1925
1926 bool TestIPv6() {
1927 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
1928 }
1929
1930 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001931 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
1932 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07001933 }
1934
1935 std::vector<SocketAddress> CallerAddresses() {
1936 std::vector<SocketAddress> addresses;
1937 addresses.push_back(SocketAddress("1.1.1.1", 0));
1938 if (TestIPv6()) {
1939 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
1940 }
1941 return addresses;
1942 }
1943
1944 std::vector<SocketAddress> CalleeAddresses() {
1945 std::vector<SocketAddress> addresses;
1946 addresses.push_back(SocketAddress("2.2.2.2", 0));
1947 if (TestIPv6()) {
1948 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
1949 }
1950 return addresses;
1951 }
1952
1953 void SetUpNetworkInterfaces() {
1954 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07001955 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
1956 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07001957
1958 // Add network addresses for test.
1959 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001960 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001961 }
1962 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001963 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001964 }
1965 }
1966
1967 private:
1968 uint32_t port_allocator_flags_;
1969 std::unique_ptr<cricket::TestStunServer> stun_server_;
1970};
1971
Yves Gerey100fe632020-01-17 19:15:53 +01001972// Ensure FakeClockForTest is constructed first (see class for rationale).
1973class PeerConnectionIntegrationIceStatesTestWithFakeClock
1974 : public FakeClockForTest,
1975 public PeerConnectionIntegrationIceStatesTest {};
1976
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001977#if !defined(THREAD_SANITIZER)
1978// This test provokes TSAN errors. bugs.webrtc.org/11282
1979
Steve Antonede9ca52017-10-16 13:04:27 -07001980// Tests that the PeerConnection goes through all the ICE gathering/connection
1981// states over the duration of the call. This includes Disconnected and Failed
1982// states, induced by putting a firewall between the peers and waiting for them
1983// to time out.
Yves Gerey100fe632020-01-17 19:15:53 +01001984TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock, VerifyIceStates) {
Steve Antonede9ca52017-10-16 13:04:27 -07001985 const SocketAddress kStunServerAddress =
1986 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
1987 StartStunServer(kStunServerAddress);
1988
1989 PeerConnectionInterface::RTCConfiguration config;
1990 PeerConnectionInterface::IceServer ice_stun_server;
1991 ice_stun_server.urls.push_back(
1992 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
1993 kStunServerAddress.PortAsString());
1994 config.servers.push_back(ice_stun_server);
1995
1996 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
1997 ConnectFakeSignaling();
1998 SetPortAllocatorFlags();
1999 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08002000 caller()->AddAudioVideoTracks();
2001 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002002
2003 // Initial state before anything happens.
2004 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
2005 caller()->ice_gathering_state());
2006 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
2007 caller()->ice_connection_state());
Jonas Olsson7a6739e2019-01-15 16:31:55 +01002008 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
2009 caller()->standardized_ice_connection_state());
Steve Antonede9ca52017-10-16 13:04:27 -07002010
2011 // Start the call by creating the offer, setting it as the local description,
2012 // then sending it to the peer who will respond with an answer. This happens
2013 // asynchronously so that we can watch the states as it runs in the
2014 // background.
2015 caller()->CreateAndSetAndSignalOffer();
2016
Steve Antona9b67ce2020-01-16 14:00:44 -08002017 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2018 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002019 FakeClock());
Steve Antona9b67ce2020-01-16 14:00:44 -08002020 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2021 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002022 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002023
2024 // Verify that the observer was notified of the intermediate transitions.
2025 EXPECT_THAT(caller()->ice_connection_state_history(),
2026 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
2027 PeerConnectionInterface::kIceConnectionConnected,
2028 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olssonacd8ae72019-02-25 15:26:24 +01002029 EXPECT_THAT(caller()->standardized_ice_connection_state_history(),
2030 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
2031 PeerConnectionInterface::kIceConnectionConnected,
2032 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olsson635474e2018-10-18 15:58:17 +02002033 EXPECT_THAT(
2034 caller()->peer_connection_state_history(),
2035 ElementsAre(PeerConnectionInterface::PeerConnectionState::kConnecting,
Jonas Olsson635474e2018-10-18 15:58:17 +02002036 PeerConnectionInterface::PeerConnectionState::kConnected));
Steve Antonede9ca52017-10-16 13:04:27 -07002037 EXPECT_THAT(caller()->ice_gathering_state_history(),
2038 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
2039 PeerConnectionInterface::kIceGatheringComplete));
2040
2041 // Block connections to/from the caller and wait for ICE to become
2042 // disconnected.
2043 for (const auto& caller_address : CallerAddresses()) {
2044 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
2045 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01002046 RTC_LOG(LS_INFO) << "Firewall rules applied";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002047 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
2048 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002049 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002050 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
2051 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002052 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002053
2054 // Let ICE re-establish by removing the firewall rules.
2055 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01002056 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002057 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2058 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002059 FakeClock());
Jonas Olssonacd8ae72019-02-25 15:26:24 +01002060 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002061 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002062 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002063
2064 // According to RFC7675, if there is no response within 30 seconds then the
2065 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08002066 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07002067 constexpr int kConsentTimeout = 30000;
2068 for (const auto& caller_address : CallerAddresses()) {
2069 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
2070 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01002071 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002072 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
2073 caller()->ice_connection_state(), kConsentTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002074 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002075 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
2076 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002077 kConsentTimeout, FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002078}
2079
2080// Tests that if the connection doesn't get set up properly we eventually reach
2081// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01002082TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
2083 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002084 // Block connections to/from the caller and wait for ICE to become
2085 // disconnected.
2086 for (const auto& caller_address : CallerAddresses()) {
2087 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
2088 }
2089
2090 ASSERT_TRUE(CreatePeerConnectionWrappers());
2091 ConnectFakeSignaling();
2092 SetPortAllocatorFlags();
2093 SetUpNetworkInterfaces();
2094 caller()->AddAudioVideoTracks();
2095 caller()->CreateAndSetAndSignalOffer();
2096
2097 // According to RFC7675, if there is no response within 30 seconds then the
2098 // peer should consider the other side to have rejected the connection. This
2099 // is signaled by the state transitioning to "failed".
2100 constexpr int kConsentTimeout = 30000;
2101 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
2102 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002103 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002104}
2105
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002106#endif // !defined(THREAD_SANITIZER)
2107
Steve Antonede9ca52017-10-16 13:04:27 -07002108// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
2109// and that the statistics in the metric observers are updated correctly.
Rasmus Brandt32af25b2021-03-17 13:40:21 +01002110// TODO(bugs.webrtc.org/12591): Flaky on Windows.
2111#if defined(WEBRTC_WIN)
2112#define MAYBE_VerifyBestConnection DISABLED_VerifyBestConnection
2113#else
2114#define MAYBE_VerifyBestConnection VerifyBestConnection
2115#endif
2116TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
Steve Antonede9ca52017-10-16 13:04:27 -07002117 ASSERT_TRUE(CreatePeerConnectionWrappers());
2118 ConnectFakeSignaling();
2119 SetPortAllocatorFlags();
2120 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08002121 caller()->AddAudioVideoTracks();
2122 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002123 caller()->CreateAndSetAndSignalOffer();
2124
2125 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08002126 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2127 caller()->ice_connection_state(), kDefaultTimeout);
2128 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2129 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07002130
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002131 // TODO(bugs.webrtc.org/9456): Fix it.
2132 const int num_best_ipv4 = webrtc::metrics::NumEvents(
2133 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
2134 const int num_best_ipv6 = webrtc::metrics::NumEvents(
2135 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07002136 if (TestIPv6()) {
2137 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
2138 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01002139 EXPECT_METRIC_EQ(0, num_best_ipv4);
2140 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07002141 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01002142 EXPECT_METRIC_EQ(1, num_best_ipv4);
2143 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07002144 }
2145
Ying Wangef3998f2019-12-09 13:06:53 +01002146 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
2147 "WebRTC.PeerConnection.CandidatePairType_UDP",
2148 webrtc::kIceCandidatePairHostHost));
2149 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
2150 "WebRTC.PeerConnection.CandidatePairType_UDP",
2151 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07002152}
2153
2154constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
2155 cricket::PORTALLOCATOR_DISABLE_STUN |
2156 cricket::PORTALLOCATOR_DISABLE_RELAY;
2157constexpr uint32_t kFlagsIPv6NoStun =
2158 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
2159 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
2160constexpr uint32_t kFlagsIPv4Stun =
2161 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
2162
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002163INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002164 PeerConnectionIntegrationTest,
2165 PeerConnectionIntegrationIceStatesTest,
2166 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
2167 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2168 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2169 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07002170
Yves Gerey100fe632020-01-17 19:15:53 +01002171INSTANTIATE_TEST_SUITE_P(
2172 PeerConnectionIntegrationTest,
2173 PeerConnectionIntegrationIceStatesTestWithFakeClock,
2174 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
2175 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2176 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2177 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
2178
deadbeef1dcb1642017-03-29 21:08:16 -07002179// This test sets up a call between two parties with audio and video.
2180// During the call, the caller restarts ICE and the test verifies that
2181// new ICE candidates are generated and audio and video still can flow, and the
2182// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002183TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07002184 ASSERT_TRUE(CreatePeerConnectionWrappers());
2185 ConnectFakeSignaling();
2186 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08002187 caller()->AddAudioVideoTracks();
2188 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002189 caller()->CreateAndSetAndSignalOffer();
2190 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2191 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2192 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002193 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2194 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07002195
2196 // To verify that the ICE restart actually occurs, get
2197 // ufrag/password/candidates before and after restart.
2198 // Create an SDP string of the first audio candidate for both clients.
2199 const webrtc::IceCandidateCollection* audio_candidates_caller =
2200 caller()->pc()->local_description()->candidates(0);
2201 const webrtc::IceCandidateCollection* audio_candidates_callee =
2202 callee()->pc()->local_description()->candidates(0);
2203 ASSERT_GT(audio_candidates_caller->count(), 0u);
2204 ASSERT_GT(audio_candidates_callee->count(), 0u);
2205 std::string caller_candidate_pre_restart;
2206 ASSERT_TRUE(
2207 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
2208 std::string callee_candidate_pre_restart;
2209 ASSERT_TRUE(
2210 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
2211 const cricket::SessionDescription* desc =
2212 caller()->pc()->local_description()->description();
2213 std::string caller_ufrag_pre_restart =
2214 desc->transport_infos()[0].description.ice_ufrag;
2215 desc = callee()->pc()->local_description()->description();
2216 std::string callee_ufrag_pre_restart =
2217 desc->transport_infos()[0].description.ice_ufrag;
2218
Alex Drake00c7ecf2019-08-06 10:54:47 -07002219 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002220 // Have the caller initiate an ICE restart.
2221 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2222 caller()->CreateAndSetAndSignalOffer();
2223 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2224 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2225 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002226 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07002227 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2228
2229 // Grab the ufrags/candidates again.
2230 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
2231 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
2232 ASSERT_GT(audio_candidates_caller->count(), 0u);
2233 ASSERT_GT(audio_candidates_callee->count(), 0u);
2234 std::string caller_candidate_post_restart;
2235 ASSERT_TRUE(
2236 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
2237 std::string callee_candidate_post_restart;
2238 ASSERT_TRUE(
2239 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
2240 desc = caller()->pc()->local_description()->description();
2241 std::string caller_ufrag_post_restart =
2242 desc->transport_infos()[0].description.ice_ufrag;
2243 desc = callee()->pc()->local_description()->description();
2244 std::string callee_ufrag_post_restart =
2245 desc->transport_infos()[0].description.ice_ufrag;
2246 // Sanity check that an ICE restart was actually negotiated in SDP.
2247 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
2248 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
2249 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
2250 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07002251 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002252
2253 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002254 MediaExpectations media_expectations;
2255 media_expectations.ExpectBidirectionalAudioAndVideo();
2256 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002257}
2258
2259// Verify that audio/video can be received end-to-end when ICE renomination is
2260// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002261TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07002262 PeerConnectionInterface::RTCConfiguration config;
2263 config.enable_ice_renomination = true;
2264 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2265 ConnectFakeSignaling();
2266 // Do normal offer/answer and wait for some frames to be received in each
2267 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002268 caller()->AddAudioVideoTracks();
2269 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002270 caller()->CreateAndSetAndSignalOffer();
2271 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2272 // Sanity check that ICE renomination was actually negotiated.
2273 const cricket::SessionDescription* desc =
2274 caller()->pc()->local_description()->description();
2275 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002276 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002277 }
2278 desc = callee()->pc()->local_description()->description();
2279 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002280 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002281 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08002282 MediaExpectations media_expectations;
2283 media_expectations.ExpectBidirectionalAudioAndVideo();
2284 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002285}
2286
Steve Anton6f25b092017-10-23 09:39:20 -07002287// With a max bundle policy and RTCP muxing, adding a new media description to
2288// the connection should not affect ICE at all because the new media will use
2289// the existing connection.
Rasmus Brandt685be142021-03-15 14:03:38 +01002290// TODO(bugs.webrtc.org/12538): Fails on tsan.
2291#if defined(THREAD_SANITIZER)
2292#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2293 DISABLED_AddMediaToConnectedBundleDoesNotRestartIce
2294#else
2295#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2296 AddMediaToConnectedBundleDoesNotRestartIce
2297#endif
Seth Hampson2f0d7022018-02-20 11:54:42 -08002298TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt685be142021-03-15 14:03:38 +01002299 MAYBE_AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07002300 PeerConnectionInterface::RTCConfiguration config;
2301 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
2302 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
2303 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
2304 config, PeerConnectionInterface::RTCConfiguration()));
2305 ConnectFakeSignaling();
2306
Steve Anton15324772018-01-16 10:26:49 -08002307 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002308 caller()->CreateAndSetAndSignalOffer();
2309 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07002310 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2311 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07002312
2313 caller()->clear_ice_connection_state_history();
2314
Steve Anton15324772018-01-16 10:26:49 -08002315 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002316 caller()->CreateAndSetAndSignalOffer();
2317 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2318
2319 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
2320}
2321
deadbeef1dcb1642017-03-29 21:08:16 -07002322// This test sets up a call between two parties with audio and video. It then
2323// renegotiates setting the video m-line to "port 0", then later renegotiates
2324// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002325TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002326 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
2327 ASSERT_TRUE(CreatePeerConnectionWrappers());
2328 ConnectFakeSignaling();
2329
2330 // Do initial negotiation, only sending media from the caller. Will result in
2331 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08002332 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002333 caller()->CreateAndSetAndSignalOffer();
2334 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2335
2336 // Negotiate again, disabling the video "m=" section (the callee will set the
2337 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002338 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2339 PeerConnectionInterface::RTCOfferAnswerOptions options;
2340 options.offer_to_receive_video = 0;
2341 callee()->SetOfferAnswerOptions(options);
2342 } else {
2343 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002344 callee()
2345 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2346 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002347 });
2348 }
deadbeef1dcb1642017-03-29 21:08:16 -07002349 caller()->CreateAndSetAndSignalOffer();
2350 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2351 // Sanity check that video "m=" section was actually rejected.
2352 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
2353 callee()->pc()->local_description()->description());
2354 ASSERT_NE(nullptr, answer_video_content);
2355 ASSERT_TRUE(answer_video_content->rejected);
2356
2357 // Enable video and do negotiation again, making sure video is received
2358 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002359 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2360 PeerConnectionInterface::RTCOfferAnswerOptions options;
2361 options.offer_to_receive_video = 1;
2362 callee()->SetOfferAnswerOptions(options);
2363 } else {
2364 // The caller's transceiver is stopped, so we need to add another track.
2365 auto caller_transceiver =
2366 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002367 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002368 caller()->AddVideoTrack();
2369 }
2370 callee()->AddVideoTrack();
2371 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07002372 caller()->CreateAndSetAndSignalOffer();
2373 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002374
deadbeef1dcb1642017-03-29 21:08:16 -07002375 // Verify the caller receives frames from the newly added stream, and the
2376 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002377 MediaExpectations media_expectations;
2378 media_expectations.CalleeExpectsSomeAudio();
2379 media_expectations.ExpectBidirectionalVideo();
2380 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002381}
2382
deadbeef1dcb1642017-03-29 21:08:16 -07002383// This tests that if we negotiate after calling CreateSender but before we
2384// have a track, then set a track later, frames from the newly-set track are
2385// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002386TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07002387 MediaFlowsAfterEarlyWarmupWithCreateSender) {
2388 ASSERT_TRUE(CreatePeerConnectionWrappers());
2389 ConnectFakeSignaling();
2390 auto caller_audio_sender =
2391 caller()->pc()->CreateSender("audio", "caller_stream");
2392 auto caller_video_sender =
2393 caller()->pc()->CreateSender("video", "caller_stream");
2394 auto callee_audio_sender =
2395 callee()->pc()->CreateSender("audio", "callee_stream");
2396 auto callee_video_sender =
2397 callee()->pc()->CreateSender("video", "callee_stream");
2398 caller()->CreateAndSetAndSignalOffer();
2399 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2400 // Wait for ICE to complete, without any tracks being set.
2401 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2402 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2403 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2404 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2405 // Now set the tracks, and expect frames to immediately start flowing.
2406 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
2407 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
2408 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
2409 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002410 MediaExpectations media_expectations;
2411 media_expectations.ExpectBidirectionalAudioAndVideo();
2412 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2413}
2414
2415// This tests that if we negotiate after calling AddTransceiver but before we
2416// have a track, then set a track later, frames from the newly-set tracks are
2417// received end-to-end.
2418TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2419 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
2420 ASSERT_TRUE(CreatePeerConnectionWrappers());
2421 ConnectFakeSignaling();
2422 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
2423 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
2424 auto caller_audio_sender = audio_result.MoveValue()->sender();
2425 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
2426 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
2427 auto caller_video_sender = video_result.MoveValue()->sender();
2428 callee()->SetRemoteOfferHandler([this] {
2429 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02002430 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002431 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002432 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002433 RtpTransceiverDirection::kSendRecv);
2434 });
2435 caller()->CreateAndSetAndSignalOffer();
2436 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2437 // Wait for ICE to complete, without any tracks being set.
2438 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2439 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2440 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2441 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2442 // Now set the tracks, and expect frames to immediately start flowing.
2443 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
2444 auto callee_video_sender = callee()->pc()->GetSenders()[1];
2445 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
2446 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
2447 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
2448 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
2449 MediaExpectations media_expectations;
2450 media_expectations.ExpectBidirectionalAudioAndVideo();
2451 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002452}
2453
2454// This test verifies that a remote video track can be added via AddStream,
2455// and sent end-to-end. For this particular test, it's simply echoed back
2456// from the caller to the callee, rather than being forwarded to a third
2457// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002458TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07002459 ASSERT_TRUE(CreatePeerConnectionWrappers());
2460 ConnectFakeSignaling();
2461 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08002462 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002463 caller()->CreateAndSetAndSignalOffer();
2464 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002465 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07002466
2467 // Echo the stream back, and do a new offer/anwer (initiated by callee this
2468 // time).
2469 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
2470 callee()->CreateAndSetAndSignalOffer();
2471 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2472
Seth Hampson2f0d7022018-02-20 11:54:42 -08002473 MediaExpectations media_expectations;
2474 media_expectations.ExpectBidirectionalVideo();
2475 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002476}
2477
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002478#if !defined(THREAD_SANITIZER)
2479// This test provokes TSAN errors. bugs.webrtc.org/11282
2480
deadbeef1dcb1642017-03-29 21:08:16 -07002481// Test that we achieve the expected end-to-end connection time, using a
2482// fake clock and simulated latency on the media and signaling paths.
2483// We use a TURN<->TURN connection because this is usually the quickest to
2484// set up initially, especially when we're confident the connection will work
2485// and can start sending media before we get a STUN response.
2486//
2487// With various optimizations enabled, here are the network delays we expect to
2488// be on the critical path:
2489// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
2490// signaling answer (with DTLS fingerprint).
2491// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
2492// using TURN<->TURN pair, and DTLS exchange is 4 packets,
2493// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01002494TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2495 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07002496 static constexpr int media_hop_delay_ms = 50;
2497 static constexpr int signaling_trip_delay_ms = 500;
2498 // For explanation of these values, see comment above.
2499 static constexpr int required_media_hops = 9;
2500 static constexpr int required_signaling_trips = 2;
2501 // For internal delays (such as posting an event asychronously).
2502 static constexpr int allowed_internal_delay_ms = 20;
2503 static constexpr int total_connection_time_ms =
2504 media_hop_delay_ms * required_media_hops +
2505 signaling_trip_delay_ms * required_signaling_trips +
2506 allowed_internal_delay_ms;
2507
2508 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2509 3478};
2510 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2511 0};
2512 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2513 3478};
2514 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2515 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002516 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
2517 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002518
Seth Hampsonaed71642018-06-11 07:41:32 -07002519 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
2520 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07002521 // Bypass permission check on received packets so media can be sent before
2522 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07002523 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
2524 turn_server_1->set_enable_permission_checks(false);
2525 });
2526 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
2527 turn_server_2->set_enable_permission_checks(false);
2528 });
deadbeef1dcb1642017-03-29 21:08:16 -07002529
2530 PeerConnectionInterface::RTCConfiguration client_1_config;
2531 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2532 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2533 ice_server_1.username = "test";
2534 ice_server_1.password = "test";
2535 client_1_config.servers.push_back(ice_server_1);
2536 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2537 client_1_config.presume_writable_when_fully_relayed = true;
2538
2539 PeerConnectionInterface::RTCConfiguration client_2_config;
2540 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2541 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2542 ice_server_2.username = "test";
2543 ice_server_2.password = "test";
2544 client_2_config.servers.push_back(ice_server_2);
2545 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2546 client_2_config.presume_writable_when_fully_relayed = true;
2547
2548 ASSERT_TRUE(
2549 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2550 // Set up the simulated delays.
2551 SetSignalingDelayMs(signaling_trip_delay_ms);
2552 ConnectFakeSignaling();
2553 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
2554 virtual_socket_server()->UpdateDelayDistribution();
2555
2556 // Set "offer to receive audio/video" without adding any tracks, so we just
2557 // set up ICE/DTLS with no media.
2558 PeerConnectionInterface::RTCOfferAnswerOptions options;
2559 options.offer_to_receive_audio = 1;
2560 options.offer_to_receive_video = 1;
2561 caller()->SetOfferAnswerOptions(options);
2562 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07002563 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01002564 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07002565 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
2566 // If this is not done a DCHECK can be hit in ports.cc, because a large
2567 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07002568 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07002569}
2570
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002571#endif // !defined(THREAD_SANITIZER)
2572
Jonas Orelandbdcee282017-10-10 14:01:40 +02002573// Verify that a TurnCustomizer passed in through RTCConfiguration
2574// is actually used by the underlying TURN candidate pair.
2575// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002576TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02002577 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2578 3478};
2579 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2580 0};
2581 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2582 3478};
2583 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2584 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002585 CreateTurnServer(turn_server_1_internal_address,
2586 turn_server_1_external_address);
2587 CreateTurnServer(turn_server_2_internal_address,
2588 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002589
2590 PeerConnectionInterface::RTCConfiguration client_1_config;
2591 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2592 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2593 ice_server_1.username = "test";
2594 ice_server_1.password = "test";
2595 client_1_config.servers.push_back(ice_server_1);
2596 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002597 auto* customizer1 = CreateTurnCustomizer();
2598 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002599
2600 PeerConnectionInterface::RTCConfiguration client_2_config;
2601 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2602 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2603 ice_server_2.username = "test";
2604 ice_server_2.password = "test";
2605 client_2_config.servers.push_back(ice_server_2);
2606 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002607 auto* customizer2 = CreateTurnCustomizer();
2608 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002609
2610 ASSERT_TRUE(
2611 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2612 ConnectFakeSignaling();
2613
2614 // Set "offer to receive audio/video" without adding any tracks, so we just
2615 // set up ICE/DTLS with no media.
2616 PeerConnectionInterface::RTCOfferAnswerOptions options;
2617 options.offer_to_receive_audio = 1;
2618 options.offer_to_receive_video = 1;
2619 caller()->SetOfferAnswerOptions(options);
2620 caller()->CreateAndSetAndSignalOffer();
2621 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2622
Seth Hampsonaed71642018-06-11 07:41:32 -07002623 ExpectTurnCustomizerCountersIncremented(customizer1);
2624 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002625}
2626
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002627// Verifies that you can use TCP instead of UDP to connect to a TURN server and
2628// send media between the caller and the callee.
2629TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
2630 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2631 3478};
2632 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2633
2634 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07002635 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2636 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002637
2638 webrtc::PeerConnectionInterface::IceServer ice_server;
2639 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
2640 ice_server.username = "test";
2641 ice_server.password = "test";
2642
2643 PeerConnectionInterface::RTCConfiguration client_1_config;
2644 client_1_config.servers.push_back(ice_server);
2645 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2646
2647 PeerConnectionInterface::RTCConfiguration client_2_config;
2648 client_2_config.servers.push_back(ice_server);
2649 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2650
2651 ASSERT_TRUE(
2652 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2653
2654 // Do normal offer/answer and wait for ICE to complete.
2655 ConnectFakeSignaling();
2656 caller()->AddAudioVideoTracks();
2657 callee()->AddAudioVideoTracks();
2658 caller()->CreateAndSetAndSignalOffer();
2659 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2660 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2661 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2662
2663 MediaExpectations media_expectations;
2664 media_expectations.ExpectBidirectionalAudioAndVideo();
2665 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2666}
2667
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002668// Verify that a SSLCertificateVerifier passed in through
2669// PeerConnectionDependencies is actually used by the underlying SSL
2670// implementation to determine whether a certificate presented by the TURN
2671// server is accepted by the client. Note that openssladapter_unittest.cc
2672// contains more detailed, lower-level tests.
2673TEST_P(PeerConnectionIntegrationTest,
2674 SSLCertificateVerifierUsedForTurnConnections) {
2675 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2676 3478};
2677 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2678
2679 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2680 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002681 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2682 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002683
2684 webrtc::PeerConnectionInterface::IceServer ice_server;
2685 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2686 ice_server.username = "test";
2687 ice_server.password = "test";
2688
2689 PeerConnectionInterface::RTCConfiguration client_1_config;
2690 client_1_config.servers.push_back(ice_server);
2691 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2692
2693 PeerConnectionInterface::RTCConfiguration client_2_config;
2694 client_2_config.servers.push_back(ice_server);
2695 // Setting the type to kRelay forces the connection to go through a TURN
2696 // server.
2697 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2698
2699 // Get a copy to the pointer so we can verify calls later.
2700 rtc::TestCertificateVerifier* client_1_cert_verifier =
2701 new rtc::TestCertificateVerifier();
2702 client_1_cert_verifier->verify_certificate_ = true;
2703 rtc::TestCertificateVerifier* client_2_cert_verifier =
2704 new rtc::TestCertificateVerifier();
2705 client_2_cert_verifier->verify_certificate_ = true;
2706
2707 // Create the dependencies with the test certificate verifier.
2708 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2709 client_1_deps.tls_cert_verifier =
2710 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2711 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2712 client_2_deps.tls_cert_verifier =
2713 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2714
2715 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2716 client_1_config, std::move(client_1_deps), client_2_config,
2717 std::move(client_2_deps)));
2718 ConnectFakeSignaling();
2719
2720 // Set "offer to receive audio/video" without adding any tracks, so we just
2721 // set up ICE/DTLS with no media.
2722 PeerConnectionInterface::RTCOfferAnswerOptions options;
2723 options.offer_to_receive_audio = 1;
2724 options.offer_to_receive_video = 1;
2725 caller()->SetOfferAnswerOptions(options);
2726 caller()->CreateAndSetAndSignalOffer();
2727 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2728
2729 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2730 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002731}
2732
2733TEST_P(PeerConnectionIntegrationTest,
2734 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
2735 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2736 3478};
2737 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2738
2739 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2740 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002741 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2742 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002743
2744 webrtc::PeerConnectionInterface::IceServer ice_server;
2745 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2746 ice_server.username = "test";
2747 ice_server.password = "test";
2748
2749 PeerConnectionInterface::RTCConfiguration client_1_config;
2750 client_1_config.servers.push_back(ice_server);
2751 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2752
2753 PeerConnectionInterface::RTCConfiguration client_2_config;
2754 client_2_config.servers.push_back(ice_server);
2755 // Setting the type to kRelay forces the connection to go through a TURN
2756 // server.
2757 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2758
2759 // Get a copy to the pointer so we can verify calls later.
2760 rtc::TestCertificateVerifier* client_1_cert_verifier =
2761 new rtc::TestCertificateVerifier();
2762 client_1_cert_verifier->verify_certificate_ = false;
2763 rtc::TestCertificateVerifier* client_2_cert_verifier =
2764 new rtc::TestCertificateVerifier();
2765 client_2_cert_verifier->verify_certificate_ = false;
2766
2767 // Create the dependencies with the test certificate verifier.
2768 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2769 client_1_deps.tls_cert_verifier =
2770 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2771 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2772 client_2_deps.tls_cert_verifier =
2773 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2774
2775 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2776 client_1_config, std::move(client_1_deps), client_2_config,
2777 std::move(client_2_deps)));
2778 ConnectFakeSignaling();
2779
2780 // Set "offer to receive audio/video" without adding any tracks, so we just
2781 // set up ICE/DTLS with no media.
2782 PeerConnectionInterface::RTCOfferAnswerOptions options;
2783 options.offer_to_receive_audio = 1;
2784 options.offer_to_receive_video = 1;
2785 caller()->SetOfferAnswerOptions(options);
2786 caller()->CreateAndSetAndSignalOffer();
2787 bool wait_res = true;
2788 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
2789 // properly, should be able to just wait for a state of "failed" instead of
2790 // waiting a fixed 10 seconds.
2791 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
2792 ASSERT_FALSE(wait_res);
2793
2794 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2795 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002796}
2797
Qingsi Wang25ec8882019-11-15 12:33:05 -08002798// Test that the injected ICE transport factory is used to create ICE transports
2799// for WebRTC connections.
2800TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
2801 PeerConnectionInterface::RTCConfiguration default_config;
2802 PeerConnectionDependencies dependencies(nullptr);
2803 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
2804 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
2805 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02002806 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
2807 std::move(dependencies), nullptr,
2808 /*reset_encoder_factory=*/false,
2809 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08002810 ASSERT_TRUE(wrapper);
2811 wrapper->CreateDataChannel();
Tommi87f70902021-04-27 14:43:08 +02002812 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Qingsi Wang25ec8882019-11-15 12:33:05 -08002813 wrapper->pc()->SetLocalDescription(observer,
2814 wrapper->CreateOfferAndWait().release());
2815}
2816
deadbeefc964d0b2017-04-03 10:03:35 -07002817// Test that audio and video flow end-to-end when codec names don't use the
2818// expected casing, given that they're supposed to be case insensitive. To test
2819// this, all but one codec is removed from each media description, and its
2820// casing is changed.
2821//
2822// In the past, this has regressed and caused crashes/black video, due to the
2823// fact that code at some layers was doing case-insensitive comparisons and
2824// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002825TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07002826 ASSERT_TRUE(CreatePeerConnectionWrappers());
2827 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002828 caller()->AddAudioVideoTracks();
2829 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07002830
2831 // Remove all but one audio/video codec (opus and VP8), and change the
2832 // casing of the caller's generated offer.
2833 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
2834 cricket::AudioContentDescription* audio =
2835 GetFirstAudioContentDescription(description);
2836 ASSERT_NE(nullptr, audio);
2837 auto audio_codecs = audio->codecs();
2838 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
2839 [](const cricket::AudioCodec& codec) {
2840 return codec.name != "opus";
2841 }),
2842 audio_codecs.end());
2843 ASSERT_EQ(1u, audio_codecs.size());
2844 audio_codecs[0].name = "OpUs";
2845 audio->set_codecs(audio_codecs);
2846
2847 cricket::VideoContentDescription* video =
2848 GetFirstVideoContentDescription(description);
2849 ASSERT_NE(nullptr, video);
2850 auto video_codecs = video->codecs();
2851 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
2852 [](const cricket::VideoCodec& codec) {
2853 return codec.name != "VP8";
2854 }),
2855 video_codecs.end());
2856 ASSERT_EQ(1u, video_codecs.size());
2857 video_codecs[0].name = "vP8";
2858 video->set_codecs(video_codecs);
2859 });
2860
2861 caller()->CreateAndSetAndSignalOffer();
2862 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2863
2864 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002865 MediaExpectations media_expectations;
2866 media_expectations.ExpectBidirectionalAudioAndVideo();
2867 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07002868}
2869
Jonas Oreland49ac5952018-09-26 16:04:32 +02002870TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07002871 ASSERT_TRUE(CreatePeerConnectionWrappers());
2872 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002873 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07002874 caller()->CreateAndSetAndSignalOffer();
2875 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07002876 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002877 MediaExpectations media_expectations;
2878 media_expectations.CalleeExpectsSomeAudio(1);
2879 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02002880 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07002881 auto receiver = callee()->pc()->GetReceivers()[0];
2882 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002883 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07002884 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
2885 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02002886 sources[0].source_id());
2887 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
2888}
2889
2890TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
2891 ASSERT_TRUE(CreatePeerConnectionWrappers());
2892 ConnectFakeSignaling();
2893 caller()->AddVideoTrack();
2894 caller()->CreateAndSetAndSignalOffer();
2895 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2896 // Wait for one video frame to be received by the callee.
2897 MediaExpectations media_expectations;
2898 media_expectations.CalleeExpectsSomeVideo(1);
2899 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2900 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2901 auto receiver = callee()->pc()->GetReceivers()[0];
2902 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
2903 auto sources = receiver->GetSources();
2904 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02002905 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002906 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
2907 sources[0].source_id());
2908 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07002909}
2910
deadbeef2f425aa2017-04-14 10:41:32 -07002911// Test that if a track is removed and added again with a different stream ID,
2912// the new stream ID is successfully communicated in SDP and media continues to
2913// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002914// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
2915// it will not reuse a transceiver that has already been sending. After creating
2916// a new transceiver it tries to create an offer with two senders of the same
2917// track ids and it fails.
2918TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07002919 ASSERT_TRUE(CreatePeerConnectionWrappers());
2920 ConnectFakeSignaling();
2921
deadbeef2f425aa2017-04-14 10:41:32 -07002922 // Add track using stream 1, do offer/answer.
2923 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2924 caller()->CreateLocalAudioTrack();
2925 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07002926 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07002927 caller()->CreateAndSetAndSignalOffer();
2928 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002929 {
2930 MediaExpectations media_expectations;
2931 media_expectations.CalleeExpectsSomeAudio(1);
2932 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2933 }
deadbeef2f425aa2017-04-14 10:41:32 -07002934 // Remove the sender, and create a new one with the new stream.
2935 caller()->pc()->RemoveTrack(sender);
Steve Antond78323f2018-07-11 11:13:44 -07002936 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07002937 caller()->CreateAndSetAndSignalOffer();
2938 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2939 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002940 {
2941 MediaExpectations media_expectations;
2942 media_expectations.CalleeExpectsSomeAudio();
2943 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2944 }
deadbeef2f425aa2017-04-14 10:41:32 -07002945}
2946
Seth Hampson2f0d7022018-02-20 11:54:42 -08002947TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02002948 ASSERT_TRUE(CreatePeerConnectionWrappers());
2949 ConnectFakeSignaling();
2950
Mirko Bonadei317a1f02019-09-17 17:06:18 +02002951 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002952 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
2953 ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true));
Elad Alon99c3fe52017-10-13 16:29:40 +02002954 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01002955 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
2956 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02002957
Steve Anton15324772018-01-16 10:26:49 -08002958 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02002959 caller()->CreateAndSetAndSignalOffer();
2960 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2961}
2962
Steve Antonede9ca52017-10-16 13:04:27 -07002963// Test that if candidates are only signaled by applying full session
2964// descriptions (instead of using AddIceCandidate), the peers can connect to
2965// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002966TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07002967 ASSERT_TRUE(CreatePeerConnectionWrappers());
2968 // Each side will signal the session descriptions but not candidates.
2969 ConnectFakeSignalingForSdpOnly();
2970
2971 // Add audio video track and exchange the initial offer/answer with media
2972 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08002973 caller()->AddAudioVideoTracks();
2974 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002975 caller()->CreateAndSetAndSignalOffer();
2976
2977 // Wait for all candidates to be gathered on both the caller and callee.
2978 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2979 caller()->ice_gathering_state(), kDefaultTimeout);
2980 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2981 callee()->ice_gathering_state(), kDefaultTimeout);
2982
2983 // The candidates will now be included in the session description, so
2984 // signaling them will start the ICE connection.
2985 caller()->CreateAndSetAndSignalOffer();
2986 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2987
2988 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002989 MediaExpectations media_expectations;
2990 media_expectations.ExpectBidirectionalAudioAndVideo();
2991 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07002992}
2993
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002994#if !defined(THREAD_SANITIZER)
2995// These tests provokes TSAN errors. See bugs.webrtc.org/11305.
2996
henrika5f6bf242017-11-01 11:06:56 +01002997// Test that SetAudioPlayout can be used to disable audio playout from the
2998// start, then later enable it. This may be useful, for example, if the caller
2999// needs to play a local ringtone until some event occurs, after which it
3000// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003001TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01003002 ASSERT_TRUE(CreatePeerConnectionWrappers());
3003 ConnectFakeSignaling();
3004
3005 // Set up audio-only call where audio playout is disabled on caller's side.
3006 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08003007 caller()->AddAudioTrack();
3008 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01003009 caller()->CreateAndSetAndSignalOffer();
3010 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3011
3012 // Pump messages for a second.
3013 WAIT(false, 1000);
3014 // Since audio playout is disabled, the caller shouldn't have received
3015 // anything (at the playout level, at least).
3016 EXPECT_EQ(0, caller()->audio_frames_received());
3017 // As a sanity check, make sure the callee (for which playout isn't disabled)
3018 // did still see frames on its audio level.
3019 ASSERT_GT(callee()->audio_frames_received(), 0);
3020
3021 // Enable playout again, and ensure audio starts flowing.
3022 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003023 MediaExpectations media_expectations;
3024 media_expectations.ExpectBidirectionalAudio();
3025 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01003026}
3027
Harald Alvestrand39993842021-02-17 09:05:31 +00003028double GetAudioEnergyStat(PeerConnectionIntegrationWrapper* pc) {
henrika5f6bf242017-11-01 11:06:56 +01003029 auto report = pc->NewGetStats();
3030 auto track_stats_list =
3031 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3032 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
3033 for (const auto* track_stats : track_stats_list) {
3034 if (track_stats->remote_source.is_defined() &&
3035 *track_stats->remote_source) {
3036 remote_track_stats = track_stats;
3037 break;
3038 }
3039 }
3040
3041 if (!remote_track_stats->total_audio_energy.is_defined()) {
3042 return 0.0;
3043 }
3044 return *remote_track_stats->total_audio_energy;
3045}
3046
3047// Test that if audio playout is disabled via the SetAudioPlayout() method, then
3048// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003049TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01003050 DisableAudioPlayoutStillGeneratesAudioStats) {
3051 ASSERT_TRUE(CreatePeerConnectionWrappers());
3052 ConnectFakeSignaling();
3053
3054 // Set up audio-only call where playout is disabled but audio-processing is
3055 // still active.
Steve Anton15324772018-01-16 10:26:49 -08003056 caller()->AddAudioTrack();
3057 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01003058 caller()->pc()->SetAudioPlayout(false);
3059
3060 caller()->CreateAndSetAndSignalOffer();
3061 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3062
3063 // Wait for the callee to receive audio stats.
3064 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
3065}
3066
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00003067#endif // !defined(THREAD_SANITIZER)
3068
henrika4f167df2017-11-01 14:45:55 +01003069// Test that SetAudioRecording can be used to disable audio recording from the
3070// start, then later enable it. This may be useful, for example, if the caller
3071// wants to ensure that no audio resources are active before a certain state
3072// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003073TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01003074 ASSERT_TRUE(CreatePeerConnectionWrappers());
3075 ConnectFakeSignaling();
3076
3077 // Set up audio-only call where audio recording is disabled on caller's side.
3078 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08003079 caller()->AddAudioTrack();
3080 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01003081 caller()->CreateAndSetAndSignalOffer();
3082 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3083
3084 // Pump messages for a second.
3085 WAIT(false, 1000);
3086 // Since caller has disabled audio recording, the callee shouldn't have
3087 // received anything.
3088 EXPECT_EQ(0, callee()->audio_frames_received());
3089 // As a sanity check, make sure the caller did still see frames on its
3090 // audio level since audio recording is enabled on the calle side.
3091 ASSERT_GT(caller()->audio_frames_received(), 0);
3092
3093 // Enable audio recording again, and ensure audio starts flowing.
3094 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003095 MediaExpectations media_expectations;
3096 media_expectations.ExpectBidirectionalAudio();
3097 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01003098}
3099
Qingsi Wang7685e862018-06-11 20:15:46 -07003100TEST_P(PeerConnectionIntegrationTest,
3101 IceEventsGeneratedAndLoggedInRtcEventLog) {
3102 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
3103 ConnectFakeSignaling();
3104 PeerConnectionInterface::RTCOfferAnswerOptions options;
3105 options.offer_to_receive_audio = 1;
3106 caller()->SetOfferAnswerOptions(options);
3107 caller()->CreateAndSetAndSignalOffer();
3108 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3109 ASSERT_NE(nullptr, caller()->event_log_factory());
3110 ASSERT_NE(nullptr, callee()->event_log_factory());
3111 webrtc::FakeRtcEventLog* caller_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01003112 caller()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07003113 webrtc::FakeRtcEventLog* callee_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01003114 callee()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07003115 ASSERT_NE(nullptr, caller_event_log);
3116 ASSERT_NE(nullptr, callee_event_log);
3117 int caller_ice_config_count = caller_event_log->GetEventCount(
3118 webrtc::RtcEvent::Type::IceCandidatePairConfig);
3119 int caller_ice_event_count = caller_event_log->GetEventCount(
3120 webrtc::RtcEvent::Type::IceCandidatePairEvent);
3121 int callee_ice_config_count = callee_event_log->GetEventCount(
3122 webrtc::RtcEvent::Type::IceCandidatePairConfig);
3123 int callee_ice_event_count = callee_event_log->GetEventCount(
3124 webrtc::RtcEvent::Type::IceCandidatePairEvent);
3125 EXPECT_LT(0, caller_ice_config_count);
3126 EXPECT_LT(0, caller_ice_event_count);
3127 EXPECT_LT(0, callee_ice_config_count);
3128 EXPECT_LT(0, callee_ice_event_count);
3129}
3130
Qingsi Wangc129c352019-04-18 10:41:58 -07003131TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07003132 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3133 3478};
3134 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3135
3136 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3137
3138 webrtc::PeerConnectionInterface::IceServer ice_server;
3139 ice_server.urls.push_back("turn:88.88.88.0:3478");
3140 ice_server.username = "test";
3141 ice_server.password = "test";
3142
3143 PeerConnectionInterface::RTCConfiguration caller_config;
3144 caller_config.servers.push_back(ice_server);
3145 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3146 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07003147 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07003148
3149 PeerConnectionInterface::RTCConfiguration callee_config;
3150 callee_config.servers.push_back(ice_server);
3151 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3152 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07003153 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07003154
3155 ASSERT_TRUE(
3156 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3157
3158 // Do normal offer/answer and wait for ICE to complete.
3159 ConnectFakeSignaling();
3160 caller()->AddAudioVideoTracks();
3161 callee()->AddAudioVideoTracks();
3162 caller()->CreateAndSetAndSignalOffer();
3163 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3164 // Since we are doing continual gathering, the ICE transport does not reach
3165 // kIceGatheringComplete (see
3166 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
3167 // kIceConnectionComplete.
3168 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3169 caller()->ice_connection_state(), kDefaultTimeout);
3170 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3171 callee()->ice_connection_state(), kDefaultTimeout);
3172 // Note that we cannot use the metric
Artem Titovcfea2182021-08-10 01:22:31 +02003173 // `WebRTC.PeerConnection.CandidatePairType_UDP` in this test since this
Qingsi Wangc129c352019-04-18 10:41:58 -07003174 // metric is only populated when we reach kIceConnectionComplete in the
3175 // current implementation.
3176 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3177 caller()->last_candidate_gathered().type());
3178 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3179 callee()->last_candidate_gathered().type());
3180
3181 // Loosen the caller's candidate filter.
3182 caller_config = caller()->pc()->GetConfiguration();
3183 caller_config.type = webrtc::PeerConnectionInterface::kAll;
3184 caller()->pc()->SetConfiguration(caller_config);
3185 // We should have gathered a new host candidate.
3186 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3187 caller()->last_candidate_gathered().type(), kDefaultTimeout);
3188
3189 // Loosen the callee's candidate filter.
3190 callee_config = callee()->pc()->GetConfiguration();
3191 callee_config.type = webrtc::PeerConnectionInterface::kAll;
3192 callee()->pc()->SetConfiguration(callee_config);
3193 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3194 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02003195
3196 // Create an offer and verify that it does not contain an ICE restart (i.e new
3197 // ice credentials).
3198 std::string caller_ufrag_pre_offer = caller()
3199 ->pc()
3200 ->local_description()
3201 ->description()
3202 ->transport_infos()[0]
3203 .description.ice_ufrag;
3204 caller()->CreateAndSetAndSignalOffer();
3205 std::string caller_ufrag_post_offer = caller()
3206 ->pc()
3207 ->local_description()
3208 ->description()
3209 ->transport_infos()[0]
3210 .description.ice_ufrag;
3211 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07003212}
3213
Eldar Relloda13ea22019-06-01 12:23:43 +03003214TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03003215 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3216 3478};
3217 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3218
3219 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3220
3221 webrtc::PeerConnectionInterface::IceServer ice_server;
3222 ice_server.urls.push_back("turn:88.88.88.0:3478");
3223 ice_server.username = "test";
3224 ice_server.password = "123";
3225
3226 PeerConnectionInterface::RTCConfiguration caller_config;
3227 caller_config.servers.push_back(ice_server);
3228 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3229 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3230
3231 PeerConnectionInterface::RTCConfiguration callee_config;
3232 callee_config.servers.push_back(ice_server);
3233 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3234 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3235
3236 ASSERT_TRUE(
3237 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3238
3239 // Do normal offer/answer and wait for ICE to complete.
3240 ConnectFakeSignaling();
3241 caller()->AddAudioVideoTracks();
3242 callee()->AddAudioVideoTracks();
3243 caller()->CreateAndSetAndSignalOffer();
3244 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3245 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
3246 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
3247 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02003248 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03003249}
3250
Eldar Rellofa8019c2020-05-14 11:59:33 +03003251TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
3252 webrtc::PeerConnectionInterface::IceServer ice_server;
3253 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
3254 ice_server.username = "test";
3255 ice_server.password = "test";
3256
3257 PeerConnectionInterface::RTCConfiguration caller_config;
3258 caller_config.servers.push_back(ice_server);
3259 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3260 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3261
3262 PeerConnectionInterface::RTCConfiguration callee_config;
3263 callee_config.servers.push_back(ice_server);
3264 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3265 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3266
3267 ASSERT_TRUE(
3268 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3269
3270 // Do normal offer/answer and wait for ICE to complete.
3271 ConnectFakeSignaling();
3272 caller()->AddAudioVideoTracks();
3273 callee()->AddAudioVideoTracks();
3274 caller()->CreateAndSetAndSignalOffer();
3275 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3276 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
3277 EXPECT_EQ(caller()->error_event().address, "");
3278}
3279
Eldar Rello5ab79e62019-10-09 18:29:44 +03003280TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3281 AudioKeepsFlowingAfterImplicitRollback) {
3282 PeerConnectionInterface::RTCConfiguration config;
3283 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3284 config.enable_implicit_rollback = true;
3285 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3286 ConnectFakeSignaling();
3287 caller()->AddAudioTrack();
3288 callee()->AddAudioTrack();
3289 caller()->CreateAndSetAndSignalOffer();
3290 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3291 MediaExpectations media_expectations;
3292 media_expectations.ExpectBidirectionalAudio();
3293 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3294 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
3295 caller()->AddVideoTrack();
3296 callee()->AddVideoTrack();
Tommi87f70902021-04-27 14:43:08 +02003297 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003298 callee()->pc()->SetLocalDescription(observer,
3299 callee()->CreateOfferAndWait().release());
3300 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3301 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
3302 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3303 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3304}
3305
3306TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3307 ImplicitRollbackVisitsStableState) {
3308 RTCConfiguration config;
3309 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3310 config.enable_implicit_rollback = true;
3311
3312 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3313
Tommi87f70902021-04-27 14:43:08 +02003314 auto sld_observer =
3315 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003316 callee()->pc()->SetLocalDescription(sld_observer,
3317 callee()->CreateOfferAndWait().release());
3318 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
3319 EXPECT_EQ(sld_observer->error(), "");
3320
Tommi87f70902021-04-27 14:43:08 +02003321 auto srd_observer =
3322 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003323 callee()->pc()->SetRemoteDescription(
3324 srd_observer, caller()->CreateOfferAndWait().release());
3325 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
3326 EXPECT_EQ(srd_observer->error(), "");
3327
3328 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
3329 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
3330 PeerConnectionInterface::kStable,
3331 PeerConnectionInterface::kHaveRemoteOffer));
3332}
3333
Eldar Rellobd9c33a2020-10-01 17:52:45 +03003334TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3335 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
3336 ASSERT_TRUE(CreatePeerConnectionWrappers());
3337 ConnectFakeSignaling();
3338 caller()->AddVideoTrack();
3339 callee()->AddVideoTrack();
3340 auto munger = [](cricket::SessionDescription* desc) {
3341 cricket::VideoContentDescription* video =
3342 GetFirstVideoContentDescription(desc);
3343 auto codecs = video->codecs();
3344 for (auto&& codec : codecs) {
3345 if (codec.name == "H264") {
3346 std::string value;
3347 // The parameter is not supposed to be present in SDP by default.
3348 EXPECT_FALSE(
3349 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3350 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
3351 std::string(""));
3352 }
3353 }
3354 video->set_codecs(codecs);
3355 };
3356 // Munge local offer for SLD.
3357 caller()->SetGeneratedSdpMunger(munger);
3358 // Munge remote answer for SRD.
3359 caller()->SetReceivedSdpMunger(munger);
3360 caller()->CreateAndSetAndSignalOffer();
3361 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3362 // Observe that after munging the parameter is present in generated SDP.
3363 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
3364 cricket::VideoContentDescription* video =
3365 GetFirstVideoContentDescription(desc);
3366 for (auto&& codec : video->codecs()) {
3367 if (codec.name == "H264") {
3368 std::string value;
3369 EXPECT_TRUE(
3370 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3371 }
3372 }
3373 });
3374 caller()->CreateOfferAndWait();
3375}
3376
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003377TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00003378 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003379 PeerConnectionInterface::RTCConfiguration config;
3380 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3381 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3382 ConnectFakeSignaling();
3383 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3384
3385 caller()->CreateAndSetAndSignalOffer();
3386 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3387 int current_size = caller()->pc()->GetTransceivers().size();
3388 // Add more tracks until we get close to having issues.
3389 // Issues have been seen at:
3390 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003391 // - 16 tracks on android_arm_dbg (flaky)
3392 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003393 // Double the number of tracks
3394 for (int i = 0; i < current_size; i++) {
3395 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3396 }
3397 current_size = caller()->pc()->GetTransceivers().size();
3398 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3399 auto start_time_ms = rtc::TimeMillis();
3400 caller()->CreateAndSetAndSignalOffer();
3401 // We want to stop when the time exceeds one second.
3402 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3403 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3404 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3405 ASSERT_GT(1000, elapsed_time_ms)
3406 << "Audio transceivers: Negotiation took too long after "
3407 << current_size << " tracks added";
3408 }
3409}
3410
3411TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3412 RenegotiateManyVideoTransceivers) {
3413 PeerConnectionInterface::RTCConfiguration config;
3414 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3415 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3416 ConnectFakeSignaling();
3417 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3418
3419 caller()->CreateAndSetAndSignalOffer();
3420 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3421 int current_size = caller()->pc()->GetTransceivers().size();
3422 // Add more tracks until we get close to having issues.
3423 // Issues have been seen at:
3424 // - 96 on a Linux workstation
3425 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
3426 // - 32 on android_arm64_rel and linux_dbg bots
Harald Alvestrand785e23b2021-03-15 21:26:27 +00003427 // - 16 on Android 64 (Nexus 5x)
3428 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003429 // Double the number of tracks
3430 for (int i = 0; i < current_size; i++) {
3431 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3432 }
3433 current_size = caller()->pc()->GetTransceivers().size();
3434 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3435 auto start_time_ms = rtc::TimeMillis();
3436 caller()->CreateAndSetAndSignalOffer();
3437 // We want to stop when the time exceeds one second.
3438 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3439 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3440 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3441 ASSERT_GT(1000, elapsed_time_ms)
3442 << "Video transceivers: Negotiation took too long after "
3443 << current_size << " tracks added";
3444 }
3445}
3446
Harald Alvestrand94324f22021-01-13 12:31:53 +00003447TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3448 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
3449 PeerConnectionInterface::RTCConfiguration config;
3450 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3451 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3452 ConnectFakeSignaling();
3453 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003454 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003455 caller()->CreateAndSetAndSignalOffer();
3456 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3457 // Wait until we can see the audio flowing.
3458 MediaExpectations media_expectations;
3459 media_expectations.CalleeExpectsSomeAudio();
3460 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3461
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003462 // Get the baseline numbers for audio_packets and audio_delay
3463 // in both directions.
3464 caller()->StartWatchingDelayStats();
3465 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003466
3467 int current_size = caller()->pc()->GetTransceivers().size();
3468 // Add more tracks until we get close to having issues.
3469 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003470 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00003471 // Double the number of tracks
3472 for (int i = 0; i < current_size; i++) {
3473 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3474 }
3475 current_size = caller()->pc()->GetTransceivers().size();
3476 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3477 auto start_time_ms = rtc::TimeMillis();
3478 caller()->CreateAndSetAndSignalOffer();
3479 // We want to stop when the time exceeds one second.
3480 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3481 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3482 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3483 // This is a guard against the test using excessive amounts of time.
3484 ASSERT_GT(5000, elapsed_time_ms)
3485 << "Video transceivers: Negotiation took too long after "
3486 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003487 caller()->UpdateDelayStats("caller reception", current_size);
3488 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00003489 }
3490}
3491
Mirko Bonadeic84f6612019-01-31 12:20:57 +01003492INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
3493 PeerConnectionIntegrationTest,
3494 Values(SdpSemantics::kPlanB,
3495 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-17 17:41:02 -08003496
Yves Gerey100fe632020-01-17 19:15:53 +01003497INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
3498 PeerConnectionIntegrationTestWithFakeClock,
3499 Values(SdpSemantics::kPlanB,
3500 SdpSemantics::kUnifiedPlan));
3501
Steve Anton74255ff2018-01-24 18:32:57 -08003502// Tests that verify interoperability between Plan B and Unified Plan
3503// PeerConnections.
3504class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003505 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08003506 public ::testing::WithParamInterface<
3507 std::tuple<SdpSemantics, SdpSemantics>> {
3508 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003509 // Setting the SdpSemantics for the base test to kDefault does not matter
3510 // because we specify not to use the test semantics when creating
Harald Alvestrand39993842021-02-17 09:05:31 +00003511 // PeerConnectionIntegrationWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08003512 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07003513 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08003514 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08003515 callee_semantics_(std::get<1>(GetParam())) {}
3516
3517 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07003518 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
3519 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08003520 }
3521
3522 const SdpSemantics caller_semantics_;
3523 const SdpSemantics callee_semantics_;
3524};
3525
3526TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
3527 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3528 ConnectFakeSignaling();
3529
3530 caller()->CreateAndSetAndSignalOffer();
3531 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3532}
3533
3534TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
3535 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3536 ConnectFakeSignaling();
3537 auto audio_sender = caller()->AddAudioTrack();
3538
3539 caller()->CreateAndSetAndSignalOffer();
3540 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3541
3542 // Verify that one audio receiver has been created on the remote and that it
3543 // has the same track ID as the sending track.
3544 auto receivers = callee()->pc()->GetReceivers();
3545 ASSERT_EQ(1u, receivers.size());
3546 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
3547 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
3548
Seth Hampson2f0d7022018-02-20 11:54:42 -08003549 MediaExpectations media_expectations;
3550 media_expectations.CalleeExpectsSomeAudio();
3551 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003552}
3553
3554TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
3555 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3556 ConnectFakeSignaling();
3557 auto video_sender = caller()->AddVideoTrack();
3558 auto audio_sender = caller()->AddAudioTrack();
3559
3560 caller()->CreateAndSetAndSignalOffer();
3561 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3562
3563 // Verify that one audio and one video receiver have been created on the
3564 // remote and that they have the same track IDs as the sending tracks.
3565 auto audio_receivers =
3566 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
3567 ASSERT_EQ(1u, audio_receivers.size());
3568 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
3569 auto video_receivers =
3570 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
3571 ASSERT_EQ(1u, video_receivers.size());
3572 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
3573
Seth Hampson2f0d7022018-02-20 11:54:42 -08003574 MediaExpectations media_expectations;
3575 media_expectations.CalleeExpectsSomeAudioAndVideo();
3576 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003577}
3578
3579TEST_P(PeerConnectionIntegrationInteropTest,
3580 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
3581 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3582 ConnectFakeSignaling();
3583 caller()->AddAudioVideoTracks();
3584 callee()->AddAudioVideoTracks();
3585
3586 caller()->CreateAndSetAndSignalOffer();
3587 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3588
Seth Hampson2f0d7022018-02-20 11:54:42 -08003589 MediaExpectations media_expectations;
3590 media_expectations.ExpectBidirectionalAudioAndVideo();
3591 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003592}
3593
3594TEST_P(PeerConnectionIntegrationInteropTest,
3595 ReverseRolesOneAudioLocalToOneVideoRemote) {
3596 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3597 ConnectFakeSignaling();
3598 caller()->AddAudioTrack();
3599 callee()->AddVideoTrack();
3600
3601 caller()->CreateAndSetAndSignalOffer();
3602 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3603
3604 // Verify that only the audio track has been negotiated.
3605 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
3606 // Might also check that the callee's NegotiationNeeded flag is set.
3607
3608 // Reverse roles.
3609 callee()->CreateAndSetAndSignalOffer();
3610 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3611
Seth Hampson2f0d7022018-02-20 11:54:42 -08003612 MediaExpectations media_expectations;
3613 media_expectations.CallerExpectsSomeVideo();
3614 media_expectations.CalleeExpectsSomeAudio();
3615 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003616}
3617
Taylor Brandstetter1c7ecef2021-08-11 12:38:35 -07003618TEST_P(PeerConnectionIntegrationTest, NewTracksDoNotCauseNewCandidates) {
3619 ASSERT_TRUE(CreatePeerConnectionWrappers());
3620 ConnectFakeSignaling();
3621 caller()->AddAudioVideoTracks();
3622 caller()->CreateAndSetAndSignalOffer();
3623 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3624 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3625 caller()->ExpectCandidates(0);
3626 callee()->ExpectCandidates(0);
3627 caller()->AddAudioTrack();
3628 caller()->CreateAndSetAndSignalOffer();
3629 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3630}
3631
Mirko Bonadeic84f6612019-01-31 12:20:57 +01003632INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07003633 PeerConnectionIntegrationTest,
3634 PeerConnectionIntegrationInteropTest,
3635 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3636 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
3637
3638// Test that if the Unified Plan side offers two video tracks then the Plan B
3639// side will only see the first one and ignore the second.
3640TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07003641 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
3642 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08003643 ConnectFakeSignaling();
3644 auto first_sender = caller()->AddVideoTrack();
3645 caller()->AddVideoTrack();
3646
3647 caller()->CreateAndSetAndSignalOffer();
3648 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3649
3650 // Verify that there is only one receiver and it corresponds to the first
3651 // added track.
3652 auto receivers = callee()->pc()->GetReceivers();
3653 ASSERT_EQ(1u, receivers.size());
3654 EXPECT_TRUE(receivers[0]->track()->enabled());
3655 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
3656
Seth Hampson2f0d7022018-02-20 11:54:42 -08003657 MediaExpectations media_expectations;
3658 media_expectations.CalleeExpectsSomeVideo();
3659 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003660}
3661
Steve Anton2bed3972019-01-04 17:04:30 -08003662// Test that if the initial offer tagged BUNDLE section is rejected due to its
3663// associated RtpTransceiver being stopped and another transceiver is added,
3664// then renegotiation causes the callee to receive the new video track without
3665// error.
3666// This is a regression test for bugs.webrtc.org/9954
3667TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3668 ReOfferWithStoppedBundleTaggedTransceiver) {
3669 RTCConfiguration config;
3670 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3671 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3672 ConnectFakeSignaling();
3673 auto audio_transceiver_or_error =
3674 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3675 ASSERT_TRUE(audio_transceiver_or_error.ok());
3676 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3677
3678 caller()->CreateAndSetAndSignalOffer();
3679 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3680 {
3681 MediaExpectations media_expectations;
3682 media_expectations.CalleeExpectsSomeAudio();
3683 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3684 }
3685
Harald Alvestrand6060df52020-08-11 09:54:02 +02003686 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08003687 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3688
3689 caller()->CreateAndSetAndSignalOffer();
3690 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3691 {
3692 MediaExpectations media_expectations;
3693 media_expectations.CalleeExpectsSomeVideo();
3694 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3695 }
3696}
3697
Harald Alvestrandbedb6052020-08-20 14:50:10 +02003698TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3699 StopTransceiverRemovesDtlsTransports) {
3700 RTCConfiguration config;
3701 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3702 ConnectFakeSignaling();
3703 auto audio_transceiver_or_error =
3704 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3705 ASSERT_TRUE(audio_transceiver_or_error.ok());
3706 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3707
3708 caller()->CreateAndSetAndSignalOffer();
3709 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3710
3711 audio_transceiver->StopStandard();
3712 caller()->CreateAndSetAndSignalOffer();
3713 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3714 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
3715 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
3716 caller()->pc()->ice_gathering_state());
3717 EXPECT_THAT(caller()->ice_gathering_state_history(),
3718 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3719 PeerConnectionInterface::kIceGatheringComplete,
3720 PeerConnectionInterface::kIceGatheringNew));
3721}
3722
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003723TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00003724 StopTransceiverStopsAndRemovesTransceivers) {
3725 RTCConfiguration config;
3726 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3727 ConnectFakeSignaling();
3728 auto audio_transceiver_or_error =
3729 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3730 ASSERT_TRUE(audio_transceiver_or_error.ok());
3731 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
3732
3733 caller()->CreateAndSetAndSignalOffer();
3734 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3735 caller_transceiver->StopStandard();
3736
3737 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
3738 caller()->CreateAndSetAndSignalOffer();
3739 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3740 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
3741 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
3742 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
3743 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
3744 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
3745 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
3746 EXPECT_TRUE(caller_transceiver->stopped());
3747 EXPECT_TRUE(callee_transceiver->stopped());
3748}
3749
3750TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003751 StopTransceiverEndsIncomingAudioTrack) {
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 audio_transceiver = audio_transceiver_or_error.MoveValue();
3759
3760 caller()->CreateAndSetAndSignalOffer();
3761 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3762 auto caller_track = audio_transceiver->receiver()->track();
3763 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3764 audio_transceiver->StopStandard();
3765 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3766 caller_track->state());
3767 caller()->CreateAndSetAndSignalOffer();
3768 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3769 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3770 callee_track->state());
3771}
3772
3773TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3774 StopTransceiverEndsIncomingVideoTrack) {
3775 RTCConfiguration config;
3776 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3777 ConnectFakeSignaling();
3778 auto audio_transceiver_or_error =
3779 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3780 ASSERT_TRUE(audio_transceiver_or_error.ok());
3781 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3782
3783 caller()->CreateAndSetAndSignalOffer();
3784 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3785 auto caller_track = audio_transceiver->receiver()->track();
3786 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3787 audio_transceiver->StopStandard();
3788 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3789 caller_track->state());
3790 caller()->CreateAndSetAndSignalOffer();
3791 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3792 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3793 callee_track->state());
3794}
3795
Harald Alvestrand89c40e22021-02-17 08:58:35 +00003796} // namespace
Harald Alvestrand39993842021-02-17 09:05:31 +00003797
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01003798} // namespace webrtc