blob: 1e17fa18696e7c8e58b80dd2b112707565515706 [file] [log] [blame]
deadbeef1dcb1642017-03-29 21:08:16 -07001/*
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Harald Alvestrand39993842021-02-17 09:05:31 +000011#include <stdint.h>
deadbeef1dcb1642017-03-29 21:08:16 -070012
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -070013#include <algorithm>
deadbeef1dcb1642017-03-29 21:08:16 -070014#include <memory>
Harald Alvestrand39993842021-02-17 09:05:31 +000015#include <string>
16#include <tuple>
Harald Alvestrandc24a2182022-02-23 13:44:59 +000017#include <type_traits>
deadbeef1dcb1642017-03-29 21:08:16 -070018#include <utility>
19#include <vector>
20
Steve Anton64b626b2019-01-28 17:25:26 -080021#include "absl/algorithm/container.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000022#include "absl/types/optional.h"
23#include "api/async_resolver_factory.h"
24#include "api/candidate.h"
25#include "api/crypto/crypto_options.h"
26#include "api/dtmf_sender_interface.h"
27#include "api/ice_transport_interface.h"
28#include "api/jsep.h"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "api/media_stream_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000030#include "api/media_types.h"
Steve Anton10542f22019-01-11 09:11:00 -080031#include "api/peer_connection_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000032#include "api/rtc_error.h"
33#include "api/rtc_event_log/rtc_event.h"
34#include "api/rtc_event_log/rtc_event_log.h"
35#include "api/rtc_event_log_output.h"
36#include "api/rtp_parameters.h"
Steve Anton10542f22019-01-11 09:11:00 -080037#include "api/rtp_receiver_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000038#include "api/rtp_sender_interface.h"
39#include "api/rtp_transceiver_direction.h"
40#include "api/rtp_transceiver_interface.h"
41#include "api/scoped_refptr.h"
42#include "api/stats/rtc_stats.h"
43#include "api/stats/rtc_stats_report.h"
44#include "api/stats/rtcstats_objects.h"
45#include "api/transport/rtp/rtp_source.h"
Steve Anton10542f22019-01-11 09:11:00 -080046#include "api/uma_metrics.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000047#include "api/units/time_delta.h"
48#include "api/video/video_rotation.h"
49#include "logging/rtc_event_log/fake_rtc_event_log.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070050#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000051#include "media/base/codec.h"
52#include "media/base/media_constants.h"
53#include "media/base/stream_params.h"
Steve Anton10542f22019-01-11 09:11:00 -080054#include "p2p/base/mock_async_resolver.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000055#include "p2p/base/port.h"
56#include "p2p/base/port_allocator.h"
Steve Anton10542f22019-01-11 09:11:00 -080057#include "p2p/base/port_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000058#include "p2p/base/stun_server.h"
Steve Anton10542f22019-01-11 09:11:00 -080059#include "p2p/base/test_stun_server.h"
60#include "p2p/base/test_turn_customizer.h"
61#include "p2p/base/test_turn_server.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000062#include "p2p/base/transport_description.h"
63#include "p2p/base/transport_info.h"
Steve Anton10542f22019-01-11 09:11:00 -080064#include "pc/media_session.h"
65#include "pc/peer_connection.h"
66#include "pc/peer_connection_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080067#include "pc/session_description.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000068#include "pc/test/fake_periodic_video_source.h"
69#include "pc/test/integration_test_helpers.h"
Steve Anton10542f22019-01-11 09:11:00 -080070#include "pc/test/mock_peer_connection_observers.h"
Jonas Olssonb75d9e92019-02-22 10:33:29 +010071#include "rtc_base/fake_clock.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070072#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080073#include "rtc_base/fake_network.h"
74#include "rtc_base/firewall_socket_server.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020075#include "rtc_base/gunit.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000076#include "rtc_base/helpers.h"
77#include "rtc_base/location.h"
78#include "rtc_base/logging.h"
79#include "rtc_base/ref_counted_object.h"
80#include "rtc_base/socket_address.h"
81#include "rtc_base/ssl_certificate.h"
82#include "rtc_base/ssl_fingerprint.h"
83#include "rtc_base/ssl_identity.h"
84#include "rtc_base/ssl_stream_adapter.h"
Steve Anton10542f22019-01-11 09:11:00 -080085#include "rtc_base/test_certificate_verifier.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000086#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080087#include "rtc_base/time_utils.h"
88#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020089#include "system_wrappers/include/metrics.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000090#include "test/gmock.h"
91#include "test/gtest.h"
deadbeef1dcb1642017-03-29 21:08:16 -070092
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010093namespace webrtc {
Harald Alvestrand39993842021-02-17 09:05:31 +000094
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010095namespace {
96
Seth Hampson2f0d7022018-02-20 11:54:42 -080097class PeerConnectionIntegrationTest
98 : public PeerConnectionIntegrationBaseTest,
Evan Shrubsole7619b7c2022-03-01 10:42:44 +010099 public ::testing::WithParamInterface<
100 std::tuple<SdpSemantics, std::string>> {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800101 protected:
102 PeerConnectionIntegrationTest()
Evan Shrubsole7619b7c2022-03-01 10:42:44 +0100103 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam()),
104 std::get<1>(GetParam())) {}
Seth Hampson2f0d7022018-02-20 11:54:42 -0800105};
106
Yves Gerey100fe632020-01-17 19:15:53 +0100107// Fake clock must be set before threads are started to prevent race on
108// Set/GetClockForTesting().
109// To achieve that, multiple inheritance is used as a mixin pattern
110// where order of construction is finely controlled.
111// This also ensures peerconnection is closed before switching back to non-fake
112// clock, avoiding other races and DCHECK failures such as in rtp_sender.cc.
113class FakeClockForTest : public rtc::ScopedFakeClock {
114 protected:
115 FakeClockForTest() {
116 // Some things use a time of "0" as a special value, so we need to start out
117 // the fake clock at a nonzero time.
118 // TODO(deadbeef): Fix this.
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100119 AdvanceTime(webrtc::TimeDelta::Seconds(1));
Yves Gerey100fe632020-01-17 19:15:53 +0100120 }
121
122 // Explicit handle.
123 ScopedFakeClock& FakeClock() { return *this; }
124};
125
126// Ensure FakeClockForTest is constructed first (see class for rationale).
127class PeerConnectionIntegrationTestWithFakeClock
128 : public FakeClockForTest,
129 public PeerConnectionIntegrationTest {};
130
Seth Hampson2f0d7022018-02-20 11:54:42 -0800131class PeerConnectionIntegrationTestPlanB
132 : public PeerConnectionIntegrationBaseTest {
133 protected:
134 PeerConnectionIntegrationTestPlanB()
135 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
136};
137
138class PeerConnectionIntegrationTestUnifiedPlan
139 : public PeerConnectionIntegrationBaseTest {
140 protected:
141 PeerConnectionIntegrationTestUnifiedPlan()
142 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
143};
144
deadbeef1dcb1642017-03-29 21:08:16 -0700145// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
146// includes testing that the callback is invoked if an observer is connected
147// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800148TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -0700149 RtpReceiverObserverOnFirstPacketReceived) {
150 ASSERT_TRUE(CreatePeerConnectionWrappers());
151 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800152 caller()->AddAudioVideoTracks();
153 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700154 // Start offer/answer exchange and wait for it to complete.
155 caller()->CreateAndSetAndSignalOffer();
156 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
157 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200158 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
159 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -0700160 // Wait for all "first packet received" callbacks to be fired.
161 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -0800162 absl::c_all_of(caller()->rtp_receiver_observers(),
163 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
164 return o->first_packet_received();
165 }),
deadbeef1dcb1642017-03-29 21:08:16 -0700166 kMaxWaitForFramesMs);
167 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -0800168 absl::c_all_of(callee()->rtp_receiver_observers(),
169 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
170 return o->first_packet_received();
171 }),
deadbeef1dcb1642017-03-29 21:08:16 -0700172 kMaxWaitForFramesMs);
173 // If new observers are set after the first packet was already received, the
174 // callback should still be invoked.
175 caller()->ResetRtpReceiverObservers();
176 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200177 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
178 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -0700179 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -0800180 absl::c_all_of(caller()->rtp_receiver_observers(),
181 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
182 return o->first_packet_received();
183 }));
deadbeef1dcb1642017-03-29 21:08:16 -0700184 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -0800185 absl::c_all_of(callee()->rtp_receiver_observers(),
186 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
187 return o->first_packet_received();
188 }));
deadbeef1dcb1642017-03-29 21:08:16 -0700189}
190
191class DummyDtmfObserver : public DtmfSenderObserverInterface {
192 public:
193 DummyDtmfObserver() : completed_(false) {}
194
195 // Implements DtmfSenderObserverInterface.
196 void OnToneChange(const std::string& tone) override {
197 tones_.push_back(tone);
198 if (tone.empty()) {
199 completed_ = true;
200 }
201 }
202
203 const std::vector<std::string>& tones() const { return tones_; }
204 bool completed() const { return completed_; }
205
206 private:
207 bool completed_;
208 std::vector<std::string> tones_;
209};
210
Artem Titov880fa812021-07-30 22:30:23 +0200211// Assumes `sender` already has an audio track added and the offer/answer
deadbeef1dcb1642017-03-29 21:08:16 -0700212// exchange is done.
Harald Alvestrand39993842021-02-17 09:05:31 +0000213void TestDtmfFromSenderToReceiver(PeerConnectionIntegrationWrapper* sender,
214 PeerConnectionIntegrationWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -0800215 // We should be able to get a DTMF sender from the local sender.
216 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
217 sender->pc()->GetSenders().at(0)->GetDtmfSender();
218 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -0700219 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -0700220 dtmf_sender->RegisterObserver(&observer);
221
222 // Test the DtmfSender object just created.
223 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
224 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
225
226 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
227 std::vector<std::string> tones = {"1", "a", ""};
228 EXPECT_EQ(tones, observer.tones());
229 dtmf_sender->UnregisterObserver();
230 // TODO(deadbeef): Verify the tones were actually received end-to-end.
231}
232
233// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
234// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800235TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -0700236 ASSERT_TRUE(CreatePeerConnectionWrappers());
237 ConnectFakeSignaling();
238 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -0800239 caller()->AddAudioTrack();
240 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700241 caller()->CreateAndSetAndSignalOffer();
242 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -0700243 // DTLS must finish before the DTMF sender can be used reliably.
244 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -0700245 TestDtmfFromSenderToReceiver(caller(), callee());
246 TestDtmfFromSenderToReceiver(callee(), caller());
247}
248
249// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
250// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800251TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -0700252 ASSERT_TRUE(CreatePeerConnectionWrappers());
253 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +0100254
deadbeef1dcb1642017-03-29 21:08:16 -0700255 // Do normal offer/answer and wait for some frames to be received in each
256 // direction.
Steve Anton15324772018-01-16 10:26:49 -0800257 caller()->AddAudioVideoTracks();
258 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700259 caller()->CreateAndSetAndSignalOffer();
260 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800261 MediaExpectations media_expectations;
262 media_expectations.ExpectBidirectionalAudioAndVideo();
263 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Ying Wangef3998f2019-12-09 13:06:53 +0100264 EXPECT_METRIC_LE(
265 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
266 webrtc::kEnumCounterKeyProtocolDtls));
267 EXPECT_METRIC_EQ(
268 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
269 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -0700270}
271
Harald Alvestrand50b95522021-11-18 10:01:06 +0000272// Uses SDES instead of DTLS for key agreement.
273TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
274 PeerConnectionInterface::RTCConfiguration sdes_config;
275 sdes_config.enable_dtls_srtp.emplace(false);
276 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
277 ConnectFakeSignaling();
278
279 // Do normal offer/answer and wait for some frames to be received in each
280 // direction.
281 caller()->AddAudioVideoTracks();
282 callee()->AddAudioVideoTracks();
283 caller()->CreateAndSetAndSignalOffer();
284 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
285 MediaExpectations media_expectations;
286 media_expectations.ExpectBidirectionalAudioAndVideo();
287 ASSERT_TRUE(ExpectNewFrames(media_expectations));
288 EXPECT_METRIC_LE(
289 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
290 webrtc::kEnumCounterKeyProtocolSdes));
291 EXPECT_METRIC_EQ(
292 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
293 webrtc::kEnumCounterKeyProtocolDtls));
294}
295
Artem Titov880fa812021-07-30 22:30:23 +0200296// Basic end-to-end test specifying the `enable_encrypted_rtp_header_extensions`
Steve Anton9a44b2d2019-07-12 12:58:30 -0700297// option to offer encrypted versions of all header extensions alongside the
298// unencrypted versions.
299TEST_P(PeerConnectionIntegrationTest,
300 EndToEndCallWithEncryptedRtpHeaderExtensions) {
301 CryptoOptions crypto_options;
302 crypto_options.srtp.enable_encrypted_rtp_header_extensions = true;
303 PeerConnectionInterface::RTCConfiguration config;
304 config.crypto_options = crypto_options;
305 // Note: This allows offering >14 RTP header extensions.
306 config.offer_extmap_allow_mixed = true;
307 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
308 ConnectFakeSignaling();
309
310 // Do normal offer/answer and wait for some frames to be received in each
311 // direction.
312 caller()->AddAudioVideoTracks();
313 callee()->AddAudioVideoTracks();
314 caller()->CreateAndSetAndSignalOffer();
315 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
316 MediaExpectations media_expectations;
317 media_expectations.ExpectBidirectionalAudioAndVideo();
318 ASSERT_TRUE(ExpectNewFrames(media_expectations));
319}
320
deadbeef1dcb1642017-03-29 21:08:16 -0700321// This test sets up a call between two parties with a source resolution of
322// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800323TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -0700324 Send1280By720ResolutionAndReceive16To9AspectRatio) {
325 ASSERT_TRUE(CreatePeerConnectionWrappers());
326 ConnectFakeSignaling();
327
Niels Möller5c7efe72018-05-11 10:34:46 +0200328 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
329 webrtc::FakePeriodicVideoSource::Config config;
330 config.width = 1280;
331 config.height = 720;
Johannes Kron965e7942018-09-13 15:36:20 +0200332 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +0200333 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
334 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -0700335
336 // Do normal offer/answer and wait for at least one frame to be received in
337 // each direction.
338 caller()->CreateAndSetAndSignalOffer();
339 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
340 callee()->min_video_frames_received_per_track() > 0,
341 kMaxWaitForFramesMs);
342
343 // Check rendered aspect ratio.
344 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
345 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
346 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
347 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
348}
349
350// This test sets up an one-way call, with media only from caller to
351// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800352TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -0700353 ASSERT_TRUE(CreatePeerConnectionWrappers());
354 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800355 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700356 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800357 MediaExpectations media_expectations;
358 media_expectations.CalleeExpectsSomeAudioAndVideo();
359 media_expectations.CallerExpectsNoAudio();
360 media_expectations.CallerExpectsNoVideo();
361 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700362}
363
Johannes Kron3e983682020-03-29 22:17:00 +0200364// Tests that send only works without the caller having a decoder factory and
365// the callee having an encoder factory.
366TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSendOnlyVideo) {
367 ASSERT_TRUE(
368 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
369 ConnectFakeSignaling();
370 // Add one-directional video, from caller to callee.
371 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
372 caller()->CreateLocalVideoTrack();
373 caller()->AddTrack(caller_track);
374 PeerConnectionInterface::RTCOfferAnswerOptions options;
375 options.offer_to_receive_video = 0;
376 caller()->SetOfferAnswerOptions(options);
377 caller()->CreateAndSetAndSignalOffer();
378 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
379 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
380
381 // Expect video to be received in one direction.
382 MediaExpectations media_expectations;
383 media_expectations.CallerExpectsNoVideo();
384 media_expectations.CalleeExpectsSomeVideo();
385
386 EXPECT_TRUE(ExpectNewFrames(media_expectations));
387}
388
389// Tests that receive only works without the caller having an encoder factory
390// and the callee having a decoder factory.
391TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithReceiveOnlyVideo) {
392 ASSERT_TRUE(
393 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/false));
394 ConnectFakeSignaling();
395 // Add one-directional video, from callee to caller.
396 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
397 callee()->CreateLocalVideoTrack();
398 callee()->AddTrack(callee_track);
399 PeerConnectionInterface::RTCOfferAnswerOptions options;
400 options.offer_to_receive_video = 1;
401 caller()->SetOfferAnswerOptions(options);
402 caller()->CreateAndSetAndSignalOffer();
403 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
404 ASSERT_EQ(caller()->pc()->GetReceivers().size(), 1u);
405
406 // Expect video to be received in one direction.
407 MediaExpectations media_expectations;
408 media_expectations.CallerExpectsSomeVideo();
409 media_expectations.CalleeExpectsNoVideo();
410
411 EXPECT_TRUE(ExpectNewFrames(media_expectations));
412}
413
414TEST_P(PeerConnectionIntegrationTest,
415 EndToEndCallAddReceiveVideoToSendOnlyCall) {
416 ASSERT_TRUE(CreatePeerConnectionWrappers());
417 ConnectFakeSignaling();
418 // Add one-directional video, from caller to callee.
419 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
420 caller()->CreateLocalVideoTrack();
421 caller()->AddTrack(caller_track);
422 caller()->CreateAndSetAndSignalOffer();
423 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
424
425 // Add receive video.
426 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
427 callee()->CreateLocalVideoTrack();
428 callee()->AddTrack(callee_track);
429 caller()->CreateAndSetAndSignalOffer();
430 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
431
432 // Ensure that video frames are received end-to-end.
433 MediaExpectations media_expectations;
434 media_expectations.ExpectBidirectionalVideo();
435 ASSERT_TRUE(ExpectNewFrames(media_expectations));
436}
437
438TEST_P(PeerConnectionIntegrationTest,
439 EndToEndCallAddSendVideoToReceiveOnlyCall) {
440 ASSERT_TRUE(CreatePeerConnectionWrappers());
441 ConnectFakeSignaling();
442 // Add one-directional video, from callee to caller.
443 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
444 callee()->CreateLocalVideoTrack();
445 callee()->AddTrack(callee_track);
446 caller()->CreateAndSetAndSignalOffer();
447 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
448
449 // Add send video.
450 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
451 caller()->CreateLocalVideoTrack();
452 caller()->AddTrack(caller_track);
453 caller()->CreateAndSetAndSignalOffer();
454 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
455
456 // Expect video to be received in one direction.
457 MediaExpectations media_expectations;
458 media_expectations.ExpectBidirectionalVideo();
459 ASSERT_TRUE(ExpectNewFrames(media_expectations));
460}
461
462TEST_P(PeerConnectionIntegrationTest,
463 EndToEndCallRemoveReceiveVideoFromSendReceiveCall) {
464 ASSERT_TRUE(CreatePeerConnectionWrappers());
465 ConnectFakeSignaling();
466 // Add send video, from caller to callee.
467 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
468 caller()->CreateLocalVideoTrack();
469 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
470 caller()->AddTrack(caller_track);
471 // Add receive video, from callee to caller.
472 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
473 callee()->CreateLocalVideoTrack();
474
475 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
476 callee()->AddTrack(callee_track);
477 caller()->CreateAndSetAndSignalOffer();
478 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
479
480 // Remove receive video (i.e., callee sender track).
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000481 callee()->pc()->RemoveTrackOrError(callee_sender);
Johannes Kron3e983682020-03-29 22:17:00 +0200482
483 caller()->CreateAndSetAndSignalOffer();
484 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
485
486 // Expect one-directional video.
487 MediaExpectations media_expectations;
488 media_expectations.CallerExpectsNoVideo();
489 media_expectations.CalleeExpectsSomeVideo();
490
491 ASSERT_TRUE(ExpectNewFrames(media_expectations));
492}
493
494TEST_P(PeerConnectionIntegrationTest,
495 EndToEndCallRemoveSendVideoFromSendReceiveCall) {
496 ASSERT_TRUE(CreatePeerConnectionWrappers());
497 ConnectFakeSignaling();
498 // Add send video, from caller to callee.
499 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
500 caller()->CreateLocalVideoTrack();
501 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
502 caller()->AddTrack(caller_track);
503 // Add receive video, from callee to caller.
504 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
505 callee()->CreateLocalVideoTrack();
506
507 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
508 callee()->AddTrack(callee_track);
509 caller()->CreateAndSetAndSignalOffer();
510 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
511
512 // Remove send video (i.e., caller sender track).
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000513 caller()->pc()->RemoveTrackOrError(caller_sender);
Johannes Kron3e983682020-03-29 22:17:00 +0200514
515 caller()->CreateAndSetAndSignalOffer();
516 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
517
518 // Expect one-directional video.
519 MediaExpectations media_expectations;
520 media_expectations.CalleeExpectsNoVideo();
521 media_expectations.CallerExpectsSomeVideo();
522
523 ASSERT_TRUE(ExpectNewFrames(media_expectations));
524}
525
deadbeef1dcb1642017-03-29 21:08:16 -0700526// This test sets up a audio call initially, with the callee rejecting video
527// initially. Then later the callee decides to upgrade to audio/video, and
528// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800529TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -0700530 ASSERT_TRUE(CreatePeerConnectionWrappers());
531 ConnectFakeSignaling();
532 // Initially, offer an audio/video stream from the caller, but refuse to
533 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -0800534 caller()->AddAudioVideoTracks();
535 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800536 if (sdp_semantics_ == SdpSemantics::kPlanB) {
537 PeerConnectionInterface::RTCOfferAnswerOptions options;
538 options.offer_to_receive_video = 0;
539 callee()->SetOfferAnswerOptions(options);
540 } else {
541 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200542 callee()
543 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
544 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800545 });
546 }
deadbeef1dcb1642017-03-29 21:08:16 -0700547 // Do offer/answer and make sure audio is still received end-to-end.
548 caller()->CreateAndSetAndSignalOffer();
549 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800550 {
551 MediaExpectations media_expectations;
552 media_expectations.ExpectBidirectionalAudio();
553 media_expectations.ExpectNoVideo();
554 ASSERT_TRUE(ExpectNewFrames(media_expectations));
555 }
deadbeef1dcb1642017-03-29 21:08:16 -0700556 // Sanity check that the callee's description has a rejected video section.
557 ASSERT_NE(nullptr, callee()->pc()->local_description());
558 const ContentInfo* callee_video_content =
559 GetFirstVideoContent(callee()->pc()->local_description()->description());
560 ASSERT_NE(nullptr, callee_video_content);
561 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800562
deadbeef1dcb1642017-03-29 21:08:16 -0700563 // Now negotiate with video and ensure negotiation succeeds, with video
564 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -0800565 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800566 if (sdp_semantics_ == SdpSemantics::kPlanB) {
567 PeerConnectionInterface::RTCOfferAnswerOptions options;
568 options.offer_to_receive_video = 1;
569 callee()->SetOfferAnswerOptions(options);
570 } else {
571 callee()->SetRemoteOfferHandler(nullptr);
572 caller()->SetRemoteOfferHandler([this] {
573 // The caller creates a new transceiver to receive video on when receiving
574 // the offer, but by default it is send only.
575 auto transceivers = caller()->pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +0200576 ASSERT_EQ(2U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800577 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
Harald Alvestrand6060df52020-08-11 09:54:02 +0200578 transceivers[1]->receiver()->media_type());
579 transceivers[1]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
580 transceivers[1]->SetDirectionWithError(
581 RtpTransceiverDirection::kSendRecv);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800582 });
583 }
deadbeef1dcb1642017-03-29 21:08:16 -0700584 callee()->CreateAndSetAndSignalOffer();
585 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800586 {
587 // Expect additional audio frames to be received after the upgrade.
588 MediaExpectations media_expectations;
589 media_expectations.ExpectBidirectionalAudioAndVideo();
590 ASSERT_TRUE(ExpectNewFrames(media_expectations));
591 }
deadbeef1dcb1642017-03-29 21:08:16 -0700592}
593
deadbeef4389b4d2017-09-07 09:07:36 -0700594// Simpler than the above test; just add an audio track to an established
595// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800596TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -0700597 ASSERT_TRUE(CreatePeerConnectionWrappers());
598 ConnectFakeSignaling();
599 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -0800600 caller()->AddVideoTrack();
601 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700602 caller()->CreateAndSetAndSignalOffer();
603 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
604 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -0800605 caller()->AddAudioTrack();
606 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700607 caller()->CreateAndSetAndSignalOffer();
608 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
609 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800610 MediaExpectations media_expectations;
611 media_expectations.ExpectBidirectionalAudioAndVideo();
612 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -0700613}
614
deadbeef1dcb1642017-03-29 21:08:16 -0700615// This test sets up a call that's transferred to a new caller with a different
616// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800617TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
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 SetCallerPcWrapperAndReturnCurrent(
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 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700636 caller()->CreateAndSetAndSignalOffer();
637 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
638 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800639 MediaExpectations media_expectations;
640 media_expectations.ExpectBidirectionalAudioAndVideo();
641 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700642}
643
644// This test sets up a call that's transferred to a new callee with a different
645// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800646TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -0700647 ASSERT_TRUE(CreatePeerConnectionWrappers());
648 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800649 caller()->AddAudioVideoTracks();
650 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700651 caller()->CreateAndSetAndSignalOffer();
652 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
653
654 // Keep the original peer around which will still send packets to the
655 // receiving client. These SRTP packets will be dropped.
Harald Alvestrand39993842021-02-17 09:05:31 +0000656 std::unique_ptr<PeerConnectionIntegrationWrapper> original_peer(
deadbeef1dcb1642017-03-29 21:08:16 -0700657 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -0800658 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -0700659 // TODO(deadbeef): Why do we call Close here? That goes against the comment
660 // directly above.
661 original_peer->pc()->Close();
662
663 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800664 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700665 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
666 caller()->CreateAndSetAndSignalOffer();
667 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
668 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800669 MediaExpectations media_expectations;
670 media_expectations.ExpectBidirectionalAudioAndVideo();
671 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700672}
673
674// This test sets up a non-bundled call and negotiates bundling at the same
675// time as starting an ICE restart. When bundling is in effect in the restart,
676// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800677TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -0700678 ASSERT_TRUE(CreatePeerConnectionWrappers());
679 ConnectFakeSignaling();
680
Steve Anton15324772018-01-16 10:26:49 -0800681 caller()->AddAudioVideoTracks();
682 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700683 // Remove the bundle group from the SDP received by the callee.
684 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
685 desc->RemoveGroupByName("BUNDLE");
686 });
687 caller()->CreateAndSetAndSignalOffer();
688 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800689 {
690 MediaExpectations media_expectations;
691 media_expectations.ExpectBidirectionalAudioAndVideo();
692 ASSERT_TRUE(ExpectNewFrames(media_expectations));
693 }
deadbeef1dcb1642017-03-29 21:08:16 -0700694 // Now stop removing the BUNDLE group, and trigger an ICE restart.
695 callee()->SetReceivedSdpMunger(nullptr);
696 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
697 caller()->CreateAndSetAndSignalOffer();
698 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
699
700 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800701 {
702 MediaExpectations media_expectations;
703 media_expectations.ExpectBidirectionalAudioAndVideo();
704 ASSERT_TRUE(ExpectNewFrames(media_expectations));
705 }
deadbeef1dcb1642017-03-29 21:08:16 -0700706}
707
708// Test CVO (Coordination of Video Orientation). If a video source is rotated
709// and both peers support the CVO RTP header extension, the actual video frames
710// don't need to be encoded in different resolutions, since the rotation is
711// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800712TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700713 ASSERT_TRUE(CreatePeerConnectionWrappers());
714 ConnectFakeSignaling();
715 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800716 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700717 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800718 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700719 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
720
721 // Wait for video frames to be received by both sides.
722 caller()->CreateAndSetAndSignalOffer();
723 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
724 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
725 callee()->min_video_frames_received_per_track() > 0,
726 kMaxWaitForFramesMs);
727
728 // Ensure that the aspect ratio is unmodified.
729 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
730 // not just assumed.
731 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
732 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
733 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
734 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
735 // Ensure that the CVO bits were surfaced to the renderer.
736 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
737 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
738}
739
740// Test that when the CVO extension isn't supported, video is rotated the
741// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800742TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700743 ASSERT_TRUE(CreatePeerConnectionWrappers());
744 ConnectFakeSignaling();
745 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800746 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700747 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800748 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700749 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
750
751 // Remove the CVO extension from the offered SDP.
752 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
753 cricket::VideoContentDescription* video =
754 GetFirstVideoContentDescription(desc);
755 video->ClearRtpHeaderExtensions();
756 });
757 // Wait for video frames to be received by both sides.
758 caller()->CreateAndSetAndSignalOffer();
759 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
760 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
761 callee()->min_video_frames_received_per_track() > 0,
762 kMaxWaitForFramesMs);
763
764 // Expect that the aspect ratio is inversed to account for the 90/270 degree
765 // rotation.
766 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
767 // not just assumed.
768 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
769 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
770 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
771 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
772 // Expect that each endpoint is unaware of the rotation of the other endpoint.
773 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
774 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
775}
776
deadbeef1dcb1642017-03-29 21:08:16 -0700777// Test that if the answerer rejects the audio m= section, no audio is sent or
778// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800779TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700780 ASSERT_TRUE(CreatePeerConnectionWrappers());
781 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800782 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800783 if (sdp_semantics_ == SdpSemantics::kPlanB) {
784 // Only add video track for callee, and set offer_to_receive_audio to 0, so
785 // it will reject the audio m= section completely.
786 PeerConnectionInterface::RTCOfferAnswerOptions options;
787 options.offer_to_receive_audio = 0;
788 callee()->SetOfferAnswerOptions(options);
789 } else {
790 // Stopping the audio RtpTransceiver will cause the media section to be
791 // rejected in the answer.
792 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200793 callee()
794 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
795 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800796 });
797 }
Steve Anton15324772018-01-16 10:26:49 -0800798 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700799 // Do offer/answer and wait for successful end-to-end video frames.
800 caller()->CreateAndSetAndSignalOffer();
801 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800802 MediaExpectations media_expectations;
803 media_expectations.ExpectBidirectionalVideo();
804 media_expectations.ExpectNoAudio();
805 ASSERT_TRUE(ExpectNewFrames(media_expectations));
806
deadbeef1dcb1642017-03-29 21:08:16 -0700807 // Sanity check that the callee's description has a rejected audio section.
808 ASSERT_NE(nullptr, callee()->pc()->local_description());
809 const ContentInfo* callee_audio_content =
810 GetFirstAudioContent(callee()->pc()->local_description()->description());
811 ASSERT_NE(nullptr, callee_audio_content);
812 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800813 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200814 // The caller's transceiver should have stopped after receiving the answer,
815 // and thus no longer listed in transceivers.
816 EXPECT_EQ(nullptr,
817 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800818 }
deadbeef1dcb1642017-03-29 21:08:16 -0700819}
820
821// Test that if the answerer rejects the video m= section, no video is sent or
822// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800823TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700824 ASSERT_TRUE(CreatePeerConnectionWrappers());
825 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800826 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800827 if (sdp_semantics_ == SdpSemantics::kPlanB) {
828 // Only add audio track for callee, and set offer_to_receive_video to 0, so
829 // it will reject the video m= section completely.
830 PeerConnectionInterface::RTCOfferAnswerOptions options;
831 options.offer_to_receive_video = 0;
832 callee()->SetOfferAnswerOptions(options);
833 } else {
834 // Stopping the video RtpTransceiver will cause the media section to be
835 // rejected in the answer.
836 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200837 callee()
838 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
839 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800840 });
841 }
Steve Anton15324772018-01-16 10:26:49 -0800842 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700843 // Do offer/answer and wait for successful end-to-end audio frames.
844 caller()->CreateAndSetAndSignalOffer();
845 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800846 MediaExpectations media_expectations;
847 media_expectations.ExpectBidirectionalAudio();
848 media_expectations.ExpectNoVideo();
849 ASSERT_TRUE(ExpectNewFrames(media_expectations));
850
deadbeef1dcb1642017-03-29 21:08:16 -0700851 // Sanity check that the callee's description has a rejected video section.
852 ASSERT_NE(nullptr, callee()->pc()->local_description());
853 const ContentInfo* callee_video_content =
854 GetFirstVideoContent(callee()->pc()->local_description()->description());
855 ASSERT_NE(nullptr, callee_video_content);
856 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800857 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200858 // The caller's transceiver should have stopped after receiving the answer,
859 // and thus is no longer present.
860 EXPECT_EQ(nullptr,
861 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800862 }
deadbeef1dcb1642017-03-29 21:08:16 -0700863}
864
865// Test that if the answerer rejects both audio and video m= sections, nothing
866// bad happens.
867// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
868// test anything but the fact that negotiation succeeds, which doesn't mean
869// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800870TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -0700871 ASSERT_TRUE(CreatePeerConnectionWrappers());
872 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800873 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800874 if (sdp_semantics_ == SdpSemantics::kPlanB) {
875 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
876 // will reject both audio and video m= sections.
877 PeerConnectionInterface::RTCOfferAnswerOptions options;
878 options.offer_to_receive_audio = 0;
879 options.offer_to_receive_video = 0;
880 callee()->SetOfferAnswerOptions(options);
881 } else {
882 callee()->SetRemoteOfferHandler([this] {
883 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +0100884 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200885 transceiver->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800886 }
887 });
888 }
deadbeef1dcb1642017-03-29 21:08:16 -0700889 // Do offer/answer and wait for stable signaling state.
890 caller()->CreateAndSetAndSignalOffer();
891 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800892
deadbeef1dcb1642017-03-29 21:08:16 -0700893 // Sanity check that the callee's description has rejected m= sections.
894 ASSERT_NE(nullptr, callee()->pc()->local_description());
895 const ContentInfo* callee_audio_content =
896 GetFirstAudioContent(callee()->pc()->local_description()->description());
897 ASSERT_NE(nullptr, callee_audio_content);
898 EXPECT_TRUE(callee_audio_content->rejected);
899 const ContentInfo* callee_video_content =
900 GetFirstVideoContent(callee()->pc()->local_description()->description());
901 ASSERT_NE(nullptr, callee_video_content);
902 EXPECT_TRUE(callee_video_content->rejected);
903}
904
905// This test sets up an audio and video call between two parties. After the
906// call runs for a while, the caller sends an updated offer with video being
907// rejected. Once the re-negotiation is done, the video flow should stop and
908// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800909TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700910 ASSERT_TRUE(CreatePeerConnectionWrappers());
911 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800912 caller()->AddAudioVideoTracks();
913 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700914 caller()->CreateAndSetAndSignalOffer();
915 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800916 {
917 MediaExpectations media_expectations;
918 media_expectations.ExpectBidirectionalAudioAndVideo();
919 ASSERT_TRUE(ExpectNewFrames(media_expectations));
920 }
deadbeef1dcb1642017-03-29 21:08:16 -0700921 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800922 if (sdp_semantics_ == SdpSemantics::kPlanB) {
923 caller()->SetGeneratedSdpMunger(
924 [](cricket::SessionDescription* description) {
925 for (cricket::ContentInfo& content : description->contents()) {
926 if (cricket::IsVideoContent(&content)) {
927 content.rejected = true;
928 }
929 }
930 });
931 } else {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200932 caller()
933 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
934 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800935 }
deadbeef1dcb1642017-03-29 21:08:16 -0700936 caller()->CreateAndSetAndSignalOffer();
937 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
938
939 // Sanity check that the caller's description has a rejected video section.
940 ASSERT_NE(nullptr, caller()->pc()->local_description());
941 const ContentInfo* caller_video_content =
942 GetFirstVideoContent(caller()->pc()->local_description()->description());
943 ASSERT_NE(nullptr, caller_video_content);
944 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -0700945 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800946 {
947 MediaExpectations media_expectations;
948 media_expectations.ExpectBidirectionalAudio();
949 media_expectations.ExpectNoVideo();
950 ASSERT_TRUE(ExpectNewFrames(media_expectations));
951 }
deadbeef1dcb1642017-03-29 21:08:16 -0700952}
953
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700954// Do one offer/answer with audio, another that disables it (rejecting the m=
955// section), and another that re-enables it. Regression test for:
956// bugs.webrtc.org/6023
957TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
958 ASSERT_TRUE(CreatePeerConnectionWrappers());
959 ConnectFakeSignaling();
960
961 // Add audio track, do normal offer/answer.
962 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
963 caller()->CreateLocalAudioTrack();
964 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
965 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
966 caller()->CreateAndSetAndSignalOffer();
967 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
968
969 // Remove audio track, and set offer_to_receive_audio to false to cause the
970 // m= section to be completely disabled, not just "recvonly".
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000971 caller()->pc()->RemoveTrackOrError(sender);
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700972 PeerConnectionInterface::RTCOfferAnswerOptions options;
973 options.offer_to_receive_audio = 0;
974 caller()->SetOfferAnswerOptions(options);
975 caller()->CreateAndSetAndSignalOffer();
976 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
977
978 // Add the audio track again, expecting negotiation to succeed and frames to
979 // flow.
980 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
981 options.offer_to_receive_audio = 1;
982 caller()->SetOfferAnswerOptions(options);
983 caller()->CreateAndSetAndSignalOffer();
984 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
985
986 MediaExpectations media_expectations;
987 media_expectations.CalleeExpectsSomeAudio();
988 EXPECT_TRUE(ExpectNewFrames(media_expectations));
989}
990
deadbeef1dcb1642017-03-29 21:08:16 -0700991// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
992// is needed to support legacy endpoints.
993// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
994// add a test for an end-to-end test without MID signaling either (basically,
995// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800996TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -0700997 ASSERT_TRUE(CreatePeerConnectionWrappers());
998 ConnectFakeSignaling();
999 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08001000 caller()->AddAudioVideoTracks();
1001 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07001002 // Remove SSRCs and MSIDs from the received offer SDP.
1003 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07001004 caller()->CreateAndSetAndSignalOffer();
1005 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001006 MediaExpectations media_expectations;
1007 media_expectations.ExpectBidirectionalAudioAndVideo();
1008 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001009}
1010
Seth Hampson5897a6e2018-04-03 11:16:33 -07001011// Basic end-to-end test, without SSRC signaling. This means that the track
1012// was created properly and frames are delivered when the MSIDs are communicated
1013// with a=msid lines and no a=ssrc lines.
1014TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1015 EndToEndCallWithoutSsrcSignaling) {
1016 const char kStreamId[] = "streamId";
1017 ASSERT_TRUE(CreatePeerConnectionWrappers());
1018 ConnectFakeSignaling();
1019 // Add just audio tracks.
1020 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
1021 callee()->AddAudioTrack();
1022
1023 // Remove SSRCs from the received offer SDP.
1024 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
1025 caller()->CreateAndSetAndSignalOffer();
1026 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1027 MediaExpectations media_expectations;
1028 media_expectations.ExpectBidirectionalAudio();
1029 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1030}
1031
Johannes Kron3e983682020-03-29 22:17:00 +02001032TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1033 EndToEndCallAddReceiveVideoToSendOnlyCall) {
1034 ASSERT_TRUE(CreatePeerConnectionWrappers());
1035 ConnectFakeSignaling();
1036 // Add one-directional video, from caller to callee.
1037 rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
1038 caller()->CreateLocalVideoTrack();
1039
1040 RtpTransceiverInit video_transceiver_init;
1041 video_transceiver_init.stream_ids = {"video1"};
1042 video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly;
1043 auto video_sender =
1044 caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue();
1045 caller()->CreateAndSetAndSignalOffer();
1046 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1047
1048 // Add receive direction.
Harald Alvestrand6060df52020-08-11 09:54:02 +02001049 video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);
Johannes Kron3e983682020-03-29 22:17:00 +02001050
1051 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
1052 callee()->CreateLocalVideoTrack();
1053
1054 callee()->AddTrack(callee_track);
1055 caller()->CreateAndSetAndSignalOffer();
1056 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1057 // Ensure that video frames are received end-to-end.
1058 MediaExpectations media_expectations;
1059 media_expectations.ExpectBidirectionalVideo();
1060 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1061}
1062
Steve Antondf527fd2018-04-27 15:52:03 -07001063// Tests that video flows between multiple video tracks when SSRCs are not
1064// signaled. This exercises the MID RTP header extension which is needed to
1065// demux the incoming video tracks.
1066TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1067 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
1068 ASSERT_TRUE(CreatePeerConnectionWrappers());
1069 ConnectFakeSignaling();
1070 caller()->AddVideoTrack();
1071 caller()->AddVideoTrack();
1072 callee()->AddVideoTrack();
1073 callee()->AddVideoTrack();
1074
1075 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1076 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1077 caller()->CreateAndSetAndSignalOffer();
1078 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1079 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1080 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1081
1082 // Expect video to be received in both directions on both tracks.
1083 MediaExpectations media_expectations;
1084 media_expectations.ExpectBidirectionalVideo();
1085 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1086}
1087
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -07001088// Used for the test below.
1089void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
1090 RemoveSsrcsAndKeepMsids(desc);
1091 desc->RemoveGroupByName("BUNDLE");
1092 for (ContentInfo& content : desc->contents()) {
1093 cricket::MediaContentDescription* media = content.media_description();
1094 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1095 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1096 [](const RtpExtension& extension) {
1097 return extension.uri ==
1098 RtpExtension::kMidUri;
1099 }),
1100 extensions.end());
1101 media->set_rtp_header_extensions(extensions);
1102 }
1103}
1104
1105// Tests that video flows between multiple video tracks when BUNDLE is not used,
1106// SSRCs are not signaled and the MID RTP header extension is not used. This
1107// relies on demuxing by payload type, which normally doesn't work if you have
1108// multiple media sections using the same payload type, but which should work as
1109// long as the media sections aren't bundled.
1110// Regression test for: http://crbug.com/webrtc/12023
1111TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1112 EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid) {
1113 ASSERT_TRUE(CreatePeerConnectionWrappers());
1114 ConnectFakeSignaling();
1115 caller()->AddVideoTrack();
1116 caller()->AddVideoTrack();
1117 callee()->AddVideoTrack();
1118 callee()->AddVideoTrack();
1119 caller()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1120 callee()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1121 caller()->CreateAndSetAndSignalOffer();
1122 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1123 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1124 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1125 // Make sure we are not bundled.
1126 ASSERT_NE(caller()->pc()->GetSenders()[0]->dtls_transport(),
1127 caller()->pc()->GetSenders()[1]->dtls_transport());
1128
1129 // Expect video to be received in both directions on both tracks.
1130 MediaExpectations media_expectations;
1131 media_expectations.ExpectBidirectionalVideo();
1132 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1133}
1134
1135// Used for the test below.
1136void ModifyPayloadTypesAndRemoveMidExtension(
1137 cricket::SessionDescription* desc) {
1138 int pt = 96;
1139 for (ContentInfo& content : desc->contents()) {
1140 cricket::MediaContentDescription* media = content.media_description();
1141 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1142 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1143 [](const RtpExtension& extension) {
1144 return extension.uri ==
1145 RtpExtension::kMidUri;
1146 }),
1147 extensions.end());
1148 media->set_rtp_header_extensions(extensions);
1149 cricket::VideoContentDescription* video = media->as_video();
1150 ASSERT_TRUE(video != nullptr);
1151 std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
1152 video->set_codecs(codecs);
1153 }
1154}
1155
1156// Tests that two video tracks can be demultiplexed by payload type alone, by
1157// using different payload types for the same codec in different m= sections.
1158// This practice is discouraged but historically has been supported.
1159// Regression test for: http://crbug.com/webrtc/12029
1160TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1161 EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType) {
1162 ASSERT_TRUE(CreatePeerConnectionWrappers());
1163 ConnectFakeSignaling();
1164 caller()->AddVideoTrack();
1165 caller()->AddVideoTrack();
1166 callee()->AddVideoTrack();
1167 callee()->AddVideoTrack();
1168 caller()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1169 callee()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1170 // We can't remove SSRCs from the generated SDP because then no send streams
1171 // would be created.
1172 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1173 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1174 caller()->CreateAndSetAndSignalOffer();
1175 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1176 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1177 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1178 // Make sure we are bundled.
1179 ASSERT_EQ(caller()->pc()->GetSenders()[0]->dtls_transport(),
1180 caller()->pc()->GetSenders()[1]->dtls_transport());
1181
1182 // Expect video to be received in both directions on both tracks.
1183 MediaExpectations media_expectations;
1184 media_expectations.ExpectBidirectionalVideo();
1185 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1186}
1187
Henrik Boström5b147782018-12-04 11:25:05 +01001188TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
1189 ASSERT_TRUE(CreatePeerConnectionWrappers());
1190 ConnectFakeSignaling();
1191 caller()->AddAudioTrack();
1192 caller()->AddVideoTrack();
1193 caller()->CreateAndSetAndSignalOffer();
1194 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1195 auto callee_receivers = callee()->pc()->GetReceivers();
1196 ASSERT_EQ(2u, callee_receivers.size());
1197 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
1198 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
1199}
1200
1201TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
1202 ASSERT_TRUE(CreatePeerConnectionWrappers());
1203 ConnectFakeSignaling();
1204 caller()->AddAudioTrack();
1205 caller()->AddVideoTrack();
1206 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1207 caller()->CreateAndSetAndSignalOffer();
1208 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1209 auto callee_receivers = callee()->pc()->GetReceivers();
1210 ASSERT_EQ(2u, callee_receivers.size());
1211 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
1212 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
1213 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
1214 callee_receivers[1]->stream_ids()[0]);
1215 EXPECT_EQ(callee_receivers[0]->streams()[0],
1216 callee_receivers[1]->streams()[0]);
1217}
1218
deadbeef1dcb1642017-03-29 21:08:16 -07001219// Test that if two video tracks are sent (from caller to callee, in this test),
1220// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001221TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07001222 ASSERT_TRUE(CreatePeerConnectionWrappers());
1223 ConnectFakeSignaling();
1224 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08001225 caller()->AddAudioVideoTracks();
1226 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001227 caller()->CreateAndSetAndSignalOffer();
1228 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08001229 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08001230
1231 MediaExpectations media_expectations;
1232 media_expectations.CalleeExpectsSomeAudioAndVideo();
1233 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001234}
1235
1236static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
1237 bool first = true;
1238 for (cricket::ContentInfo& content : desc->contents()) {
1239 if (first) {
1240 first = false;
1241 continue;
1242 }
1243 content.bundle_only = true;
1244 }
1245 first = true;
1246 for (cricket::TransportInfo& transport : desc->transport_infos()) {
1247 if (first) {
1248 first = false;
1249 continue;
1250 }
1251 transport.description.ice_ufrag.clear();
1252 transport.description.ice_pwd.clear();
1253 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
1254 transport.description.identity_fingerprint.reset(nullptr);
1255 }
1256}
1257
1258// Test that if applying a true "max bundle" offer, which uses ports of 0,
1259// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
1260// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
1261// successfully and media flows.
1262// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
1263// TODO(deadbeef): Won't need this test once we start generating actual
1264// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001265TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001266 EndToEndCallWithSpecCompliantMaxBundleOffer) {
1267 ASSERT_TRUE(CreatePeerConnectionWrappers());
1268 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001269 caller()->AddAudioVideoTracks();
1270 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001271 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
1272 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
1273 // but the first m= section.
1274 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
1275 caller()->CreateAndSetAndSignalOffer();
1276 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001277 MediaExpectations media_expectations;
1278 media_expectations.ExpectBidirectionalAudioAndVideo();
1279 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001280}
1281
1282// Test that we can receive the audio output level from a remote audio track.
1283// TODO(deadbeef): Use a fake audio source and verify that the output level is
1284// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001285TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001286 ASSERT_TRUE(CreatePeerConnectionWrappers());
1287 ConnectFakeSignaling();
1288 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001289 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001290 caller()->CreateAndSetAndSignalOffer();
1291 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1292
1293 // Get the audio output level stats. Note that the level is not available
1294 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07001295 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001296 kMaxWaitForFramesMs);
1297}
1298
1299// Test that an audio input level is reported.
1300// TODO(deadbeef): Use a fake audio source and verify that the input level is
1301// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001302TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001303 ASSERT_TRUE(CreatePeerConnectionWrappers());
1304 ConnectFakeSignaling();
1305 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001306 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001307 caller()->CreateAndSetAndSignalOffer();
1308 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1309
1310 // Get the audio input level stats. The level should be available very
1311 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07001312 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001313 kMaxWaitForStatsMs);
1314}
1315
1316// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001317TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001318 ASSERT_TRUE(CreatePeerConnectionWrappers());
1319 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001320 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001321 // Do offer/answer, wait for the callee to receive some frames.
1322 caller()->CreateAndSetAndSignalOffer();
1323 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001324
1325 MediaExpectations media_expectations;
1326 media_expectations.CalleeExpectsSomeAudioAndVideo();
1327 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001328
1329 // Get a handle to the remote tracks created, so they can be used as GetStats
1330 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01001331 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08001332 // We received frames, so we definitely should have nonzero "received bytes"
1333 // stats at this point.
1334 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
1335 0);
1336 }
deadbeef1dcb1642017-03-29 21:08:16 -07001337}
1338
1339// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001340TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001341 ASSERT_TRUE(CreatePeerConnectionWrappers());
1342 ConnectFakeSignaling();
1343 auto audio_track = caller()->CreateLocalAudioTrack();
1344 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08001345 caller()->AddTrack(audio_track);
1346 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07001347 // Do offer/answer, wait for the callee to receive some frames.
1348 caller()->CreateAndSetAndSignalOffer();
1349 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001350 MediaExpectations media_expectations;
1351 media_expectations.CalleeExpectsSomeAudioAndVideo();
1352 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001353
1354 // The callee received frames, so we definitely should have nonzero "sent
1355 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07001356 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
1357 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
1358}
1359
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001360// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001361TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001362 ASSERT_TRUE(CreatePeerConnectionWrappers());
1363 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001364 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001365
Steve Anton15324772018-01-16 10:26:49 -08001366 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001367
1368 // Do offer/answer, wait for the callee to receive some frames.
1369 caller()->CreateAndSetAndSignalOffer();
1370 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1371
1372 // Get the remote audio track created on the receiver, so they can be used as
1373 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08001374 auto receivers = callee()->pc()->GetReceivers();
1375 ASSERT_EQ(1u, receivers.size());
1376 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001377
1378 // Get the audio output level stats. Note that the level is not available
1379 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07001380 EXPECT_TRUE_WAIT(
1381 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
1382 0,
1383 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001384}
1385
Steve Antona41959e2018-11-28 11:15:33 -08001386// Test that the track ID is associated with all local and remote SSRC stats
1387// using the old GetStats() and more than 1 audio and more than 1 video track.
1388// This is a regression test for crbug.com/906988
1389TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1390 OldGetStatsAssociatesTrackIdForManyMediaSections) {
1391 ASSERT_TRUE(CreatePeerConnectionWrappers());
1392 ConnectFakeSignaling();
1393 auto audio_sender_1 = caller()->AddAudioTrack();
1394 auto video_sender_1 = caller()->AddVideoTrack();
1395 auto audio_sender_2 = caller()->AddAudioTrack();
1396 auto video_sender_2 = caller()->AddVideoTrack();
1397 caller()->CreateAndSetAndSignalOffer();
1398 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1399
1400 MediaExpectations media_expectations;
1401 media_expectations.CalleeExpectsSomeAudioAndVideo();
1402 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1403
1404 std::vector<std::string> track_ids = {
1405 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1406 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1407
1408 auto caller_stats = caller()->OldGetStats();
1409 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1410 auto callee_stats = callee()->OldGetStats();
1411 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1412}
1413
Steve Antonffa6ce42018-11-30 09:26:08 -08001414// Test that the new GetStats() returns stats for all outgoing/incoming streams
1415// with the correct track IDs if there are more than one audio and more than one
1416// video senders/receivers.
1417TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
1418 ASSERT_TRUE(CreatePeerConnectionWrappers());
1419 ConnectFakeSignaling();
1420 auto audio_sender_1 = caller()->AddAudioTrack();
1421 auto video_sender_1 = caller()->AddVideoTrack();
1422 auto audio_sender_2 = caller()->AddAudioTrack();
1423 auto video_sender_2 = caller()->AddVideoTrack();
1424 caller()->CreateAndSetAndSignalOffer();
1425 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1426
1427 MediaExpectations media_expectations;
1428 media_expectations.CalleeExpectsSomeAudioAndVideo();
1429 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1430
1431 std::vector<std::string> track_ids = {
1432 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1433 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1434
1435 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
1436 caller()->NewGetStats();
1437 ASSERT_TRUE(caller_report);
1438 auto outbound_stream_stats =
1439 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
Henrik Boströma0ff50c2020-05-05 15:54:46 +02001440 ASSERT_EQ(outbound_stream_stats.size(), 4u);
Steve Antonffa6ce42018-11-30 09:26:08 -08001441 std::vector<std::string> outbound_track_ids;
1442 for (const auto& stat : outbound_stream_stats) {
1443 ASSERT_TRUE(stat->bytes_sent.is_defined());
1444 EXPECT_LT(0u, *stat->bytes_sent);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001445 if (*stat->kind == "video") {
1446 ASSERT_TRUE(stat->key_frames_encoded.is_defined());
1447 EXPECT_GT(*stat->key_frames_encoded, 0u);
1448 ASSERT_TRUE(stat->frames_encoded.is_defined());
1449 EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
1450 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001451 ASSERT_TRUE(stat->track_id.is_defined());
1452 const auto* track_stat =
1453 caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1454 ASSERT_TRUE(track_stat);
1455 outbound_track_ids.push_back(*track_stat->track_identifier);
1456 }
1457 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
1458
1459 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
1460 callee()->NewGetStats();
1461 ASSERT_TRUE(callee_report);
1462 auto inbound_stream_stats =
1463 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1464 ASSERT_EQ(4u, inbound_stream_stats.size());
1465 std::vector<std::string> inbound_track_ids;
1466 for (const auto& stat : inbound_stream_stats) {
1467 ASSERT_TRUE(stat->bytes_received.is_defined());
1468 EXPECT_LT(0u, *stat->bytes_received);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001469 if (*stat->kind == "video") {
1470 ASSERT_TRUE(stat->key_frames_decoded.is_defined());
1471 EXPECT_GT(*stat->key_frames_decoded, 0u);
1472 ASSERT_TRUE(stat->frames_decoded.is_defined());
1473 EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
1474 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001475 ASSERT_TRUE(stat->track_id.is_defined());
1476 const auto* track_stat =
1477 callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1478 ASSERT_TRUE(track_stat);
1479 inbound_track_ids.push_back(*track_stat->track_identifier);
1480 }
1481 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
1482}
1483
1484// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07001485// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
1486// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001487TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07001488 GetStatsForUnsignaledStreamWithNewStatsApi) {
1489 ASSERT_TRUE(CreatePeerConnectionWrappers());
1490 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001491 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07001492 // Remove SSRCs and MSIDs from the received offer SDP.
1493 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1494 caller()->CreateAndSetAndSignalOffer();
1495 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001496 MediaExpectations media_expectations;
1497 media_expectations.CalleeExpectsSomeAudio(1);
1498 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07001499
1500 // We received a frame, so we should have nonzero "bytes received" stats for
1501 // the unsignaled stream, if stats are working for it.
1502 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1503 callee()->NewGetStats();
1504 ASSERT_NE(nullptr, report);
1505 auto inbound_stream_stats =
1506 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1507 ASSERT_EQ(1U, inbound_stream_stats.size());
1508 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
1509 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07001510 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
1511}
1512
Taylor Brandstettera4653442018-06-19 09:44:26 -07001513// Same as above but for the legacy stats implementation.
1514TEST_P(PeerConnectionIntegrationTest,
1515 GetStatsForUnsignaledStreamWithOldStatsApi) {
1516 ASSERT_TRUE(CreatePeerConnectionWrappers());
1517 ConnectFakeSignaling();
1518 caller()->AddAudioTrack();
1519 // Remove SSRCs and MSIDs from the received offer SDP.
1520 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1521 caller()->CreateAndSetAndSignalOffer();
1522 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1523
1524 // Note that, since the old stats implementation associates SSRCs with tracks
1525 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
1526 // associated track ID. So we can't use the track "selector" argument.
1527 //
1528 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
1529 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001530 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07001531 kDefaultTimeout);
1532}
1533
zhihuangf8164932017-05-19 13:09:47 -07001534// Test that we can successfully get the media related stats (audio level
1535// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001536TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07001537 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
1538 ASSERT_TRUE(CreatePeerConnectionWrappers());
1539 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001540 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07001541 // Remove SSRCs and MSIDs from the received offer SDP.
1542 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1543 caller()->CreateAndSetAndSignalOffer();
1544 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001545 MediaExpectations media_expectations;
1546 media_expectations.CalleeExpectsSomeAudio(1);
1547 media_expectations.CalleeExpectsSomeVideo(1);
1548 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07001549
1550 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1551 callee()->NewGetStats();
1552 ASSERT_NE(nullptr, report);
1553
1554 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1555 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
1556 ASSERT_GE(audio_index, 0);
1557 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07001558}
1559
deadbeef4e2deab2017-09-20 13:56:21 -07001560// Helper for test below.
1561void ModifySsrcs(cricket::SessionDescription* desc) {
1562 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07001563 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08001564 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07001565 for (uint32_t& ssrc : stream.ssrcs) {
1566 ssrc = rtc::CreateRandomId();
1567 }
1568 }
1569 }
1570}
1571
1572// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
1573// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
1574// This should result in two "RTCInboundRTPStreamStats", but only one
1575// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
1576// being reset to 0 once the SSRC change occurs.
1577//
1578// Regression test for this bug:
1579// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
1580//
1581// The bug causes the track stats to only represent one of the two streams:
1582// whichever one has the higher SSRC. So with this bug, there was a 50% chance
1583// that the track stat counters would reset to 0 when the new stream is
1584// received, and a 50% chance that they'll stop updating (while
1585// "concealed_samples" continues increasing, due to silence being generated for
1586// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001587TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08001588 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07001589 ASSERT_TRUE(CreatePeerConnectionWrappers());
1590 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001591 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07001592 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
1593 // that doesn't signal SSRCs (from the callee's perspective).
1594 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1595 caller()->CreateAndSetAndSignalOffer();
1596 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1597 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001598 {
1599 MediaExpectations media_expectations;
1600 media_expectations.CalleeExpectsSomeAudio(50);
1601 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1602 }
deadbeef4e2deab2017-09-20 13:56:21 -07001603 // Some audio frames were received, so we should have nonzero "samples
1604 // received" for the track.
1605 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1606 callee()->NewGetStats();
1607 ASSERT_NE(nullptr, report);
1608 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1609 ASSERT_EQ(1U, track_stats.size());
1610 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1611 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
1612 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
1613
1614 // Create a new offer and munge it to cause the caller to use a new SSRC.
1615 caller()->SetGeneratedSdpMunger(ModifySsrcs);
1616 caller()->CreateAndSetAndSignalOffer();
1617 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1618 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
1619 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001620 {
1621 MediaExpectations media_expectations;
1622 media_expectations.CalleeExpectsSomeAudio(25);
1623 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1624 }
deadbeef4e2deab2017-09-20 13:56:21 -07001625
1626 report = callee()->NewGetStats();
1627 ASSERT_NE(nullptr, report);
1628 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1629 ASSERT_EQ(1U, track_stats.size());
1630 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1631 // The "total samples received" stat should only be greater than it was
1632 // before.
1633 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
1634 // Right now, the new SSRC will cause the counters to reset to 0.
1635 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
1636
1637 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08001638 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07001639 // good sign that we're seeing stats from the old stream that's no longer
1640 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08001641 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07001642 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
1643 EXPECT_LT(*track_stats[0]->concealed_samples,
1644 *track_stats[0]->total_samples_received *
1645 kAcceptableConcealedSamplesPercentage);
1646
1647 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
1648 // sanity check that the SSRC really changed.
1649 // TODO(deadbeef): This isn't working right now, because we're not returning
1650 // *any* stats for the inactive stream. Uncomment when the bug is completely
1651 // fixed.
1652 // auto inbound_stream_stats =
1653 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1654 // ASSERT_EQ(2U, inbound_stream_stats.size());
1655}
1656
deadbeef1dcb1642017-03-29 21:08:16 -07001657// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001658TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001659 PeerConnectionFactory::Options dtls_10_options;
1660 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1661 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1662 dtls_10_options));
1663 ConnectFakeSignaling();
1664 // Do normal offer/answer and wait for some frames to be received in each
1665 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001666 caller()->AddAudioVideoTracks();
1667 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001668 caller()->CreateAndSetAndSignalOffer();
1669 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001670 MediaExpectations media_expectations;
1671 media_expectations.ExpectBidirectionalAudioAndVideo();
1672 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001673}
1674
1675// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001676TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001677 PeerConnectionFactory::Options dtls_10_options;
1678 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1679 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1680 dtls_10_options));
1681 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001682 caller()->AddAudioVideoTracks();
1683 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001684 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001685 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001686 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001687 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001688 kDefaultTimeout);
1689 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001690 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001691 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001692 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1693 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1694 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001695}
1696
1697// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001698TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001699 PeerConnectionFactory::Options dtls_12_options;
1700 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1701 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
1702 dtls_12_options));
1703 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001704 caller()->AddAudioVideoTracks();
1705 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001706 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001707 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001708 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001709 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001710 kDefaultTimeout);
1711 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001712 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001713 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001714 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1715 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1716 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001717}
1718
1719// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
1720// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001721TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001722 PeerConnectionFactory::Options caller_options;
1723 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1724 PeerConnectionFactory::Options callee_options;
1725 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1726 ASSERT_TRUE(
1727 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1728 ConnectFakeSignaling();
1729 // Do normal offer/answer and wait for some frames to be received in each
1730 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001731 caller()->AddAudioVideoTracks();
1732 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001733 caller()->CreateAndSetAndSignalOffer();
1734 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001735 MediaExpectations media_expectations;
1736 media_expectations.ExpectBidirectionalAudioAndVideo();
1737 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001738}
1739
1740// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
1741// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001742TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07001743 PeerConnectionFactory::Options caller_options;
1744 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1745 PeerConnectionFactory::Options callee_options;
1746 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1747 ASSERT_TRUE(
1748 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1749 ConnectFakeSignaling();
1750 // Do normal offer/answer and wait for some frames to be received in each
1751 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001752 caller()->AddAudioVideoTracks();
1753 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001754 caller()->CreateAndSetAndSignalOffer();
1755 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001756 MediaExpectations media_expectations;
1757 media_expectations.ExpectBidirectionalAudioAndVideo();
1758 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001759}
1760
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001761// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
1762// works as expected; the cipher should only be used if enabled by both sides.
1763TEST_P(PeerConnectionIntegrationTest,
1764 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
1765 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001766 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001767 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001768 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1769 false;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001770 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001771 TestNegotiatedCipherSuite(caller_options, callee_options,
1772 expected_cipher_suite);
1773}
1774
1775TEST_P(PeerConnectionIntegrationTest,
1776 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
1777 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001778 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1779 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001780 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001781 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001782 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001783 TestNegotiatedCipherSuite(caller_options, callee_options,
1784 expected_cipher_suite);
1785}
1786
1787TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
1788 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001789 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001790 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001791 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001792 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_32;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001793 TestNegotiatedCipherSuite(caller_options, callee_options,
1794 expected_cipher_suite);
1795}
1796
deadbeef1dcb1642017-03-29 21:08:16 -07001797// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001798TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001799 bool local_gcm_enabled = false;
1800 bool remote_gcm_enabled = false;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001801 bool aes_ctr_enabled = true;
deadbeef1dcb1642017-03-29 21:08:16 -07001802 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
1803 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001804 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001805}
1806
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001807// Test that a GCM cipher is used if both ends support it and non-GCM is
1808// disabled.
1809TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001810 bool local_gcm_enabled = true;
1811 bool remote_gcm_enabled = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001812 bool aes_ctr_enabled = false;
deadbeef1dcb1642017-03-29 21:08:16 -07001813 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
1814 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001815 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001816}
1817
deadbeef7914b8c2017-04-21 03:23:33 -07001818// Verify that media can be transmitted end-to-end when GCM crypto suites are
1819// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
1820// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
1821// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001822TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07001823 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001824 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001825 gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false;
deadbeef7914b8c2017-04-21 03:23:33 -07001826 ASSERT_TRUE(
1827 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
1828 ConnectFakeSignaling();
1829 // Do normal offer/answer and wait for some frames to be received in each
1830 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001831 caller()->AddAudioVideoTracks();
1832 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07001833 caller()->CreateAndSetAndSignalOffer();
1834 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001835 MediaExpectations media_expectations;
1836 media_expectations.ExpectBidirectionalAudioAndVideo();
1837 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07001838}
1839
deadbeef1dcb1642017-03-29 21:08:16 -07001840// Test that the ICE connection and gathering states eventually reach
1841// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08001842TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07001843 ASSERT_TRUE(CreatePeerConnectionWrappers());
1844 ConnectFakeSignaling();
1845 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001846 caller()->AddAudioVideoTracks();
1847 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001848 caller()->CreateAndSetAndSignalOffer();
1849 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1850 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1851 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
1852 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1853 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
1854 // After the best candidate pair is selected and all candidates are signaled,
1855 // the ICE connection state should reach "complete".
1856 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
1857 // answerer/"callee" by default) only reaches "connected". When this is
1858 // fixed, this test should be updated.
1859 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1860 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00001861 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1862 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001863}
1864
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001865#if !defined(THREAD_SANITIZER)
1866// This test provokes TSAN errors. See bugs.webrtc.org/3608
1867
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001868constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
1869 cricket::PORTALLOCATOR_DISABLE_RELAY |
1870 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001871
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001872// Use a mock resolver to resolve the hostname back to the original IP on both
1873// sides and check that the ICE connection connects.
Markus Handell56910532021-04-10 11:23:14 +00001874// TODO(bugs.webrtc.org/12590): Flaky on Windows and on Linux MSAN.
1875#if defined(WEBRTC_WIN) || defined(WEBRTC_LINUX)
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001876#define MAYBE_IceStatesReachCompletionWithRemoteHostname \
1877 DISABLED_IceStatesReachCompletionWithRemoteHostname
1878#else
1879#define MAYBE_IceStatesReachCompletionWithRemoteHostname \
1880 IceStatesReachCompletionWithRemoteHostname
1881#endif
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001882TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001883 MAYBE_IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001884 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001885 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001886 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001887 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001888 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
1889 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001890
1891 // This also verifies that the injected AsyncResolverFactory is used by
1892 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001893 EXPECT_CALL(*caller_resolver_factory, Create())
1894 .WillOnce(Return(&caller_async_resolver));
1895 webrtc::PeerConnectionDependencies caller_deps(nullptr);
1896 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
1897
1898 EXPECT_CALL(*callee_resolver_factory, Create())
1899 .WillOnce(Return(&callee_async_resolver));
1900 webrtc::PeerConnectionDependencies callee_deps(nullptr);
1901 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
1902
1903 PeerConnectionInterface::RTCConfiguration config;
1904 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
1905 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
1906
1907 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
1908 config, std::move(caller_deps), config, std::move(callee_deps)));
1909
1910 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
1911 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
1912
1913 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07001914 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001915 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07001916 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001917 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001918
1919 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001920
1921 ConnectFakeSignaling();
1922 caller()->AddAudioVideoTracks();
1923 callee()->AddAudioVideoTracks();
1924 caller()->CreateAndSetAndSignalOffer();
1925 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1926 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1927 caller()->ice_connection_state(), kDefaultTimeout);
1928 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1929 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08001930
Ying Wangef3998f2019-12-09 13:06:53 +01001931 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1932 "WebRTC.PeerConnection.CandidatePairType_UDP",
1933 webrtc::kIceCandidatePairHostNameHostName));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001934}
1935
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001936#endif // !defined(THREAD_SANITIZER)
1937
Steve Antonede9ca52017-10-16 13:04:27 -07001938// Test that firewalling the ICE connection causes the clients to identify the
1939// disconnected state and then removing the firewall causes them to reconnect.
1940class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08001941 : public PeerConnectionIntegrationBaseTest,
1942 public ::testing::WithParamInterface<
1943 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07001944 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001945 PeerConnectionIntegrationIceStatesTest()
1946 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
1947 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07001948 }
1949
1950 void StartStunServer(const SocketAddress& server_address) {
1951 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01001952 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07001953 }
1954
1955 bool TestIPv6() {
1956 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
1957 }
1958
1959 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001960 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
1961 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07001962 }
1963
1964 std::vector<SocketAddress> CallerAddresses() {
1965 std::vector<SocketAddress> addresses;
1966 addresses.push_back(SocketAddress("1.1.1.1", 0));
1967 if (TestIPv6()) {
1968 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
1969 }
1970 return addresses;
1971 }
1972
1973 std::vector<SocketAddress> CalleeAddresses() {
1974 std::vector<SocketAddress> addresses;
1975 addresses.push_back(SocketAddress("2.2.2.2", 0));
1976 if (TestIPv6()) {
1977 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
1978 }
1979 return addresses;
1980 }
1981
1982 void SetUpNetworkInterfaces() {
1983 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07001984 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
1985 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07001986
1987 // Add network addresses for test.
1988 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001989 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001990 }
1991 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001992 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001993 }
1994 }
1995
1996 private:
1997 uint32_t port_allocator_flags_;
1998 std::unique_ptr<cricket::TestStunServer> stun_server_;
1999};
2000
Yves Gerey100fe632020-01-17 19:15:53 +01002001// Ensure FakeClockForTest is constructed first (see class for rationale).
2002class PeerConnectionIntegrationIceStatesTestWithFakeClock
2003 : public FakeClockForTest,
2004 public PeerConnectionIntegrationIceStatesTest {};
2005
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002006#if !defined(THREAD_SANITIZER)
2007// This test provokes TSAN errors. bugs.webrtc.org/11282
2008
Steve Antonede9ca52017-10-16 13:04:27 -07002009// Tests that the PeerConnection goes through all the ICE gathering/connection
2010// states over the duration of the call. This includes Disconnected and Failed
2011// states, induced by putting a firewall between the peers and waiting for them
2012// to time out.
Yves Gerey100fe632020-01-17 19:15:53 +01002013TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock, VerifyIceStates) {
Steve Antonede9ca52017-10-16 13:04:27 -07002014 const SocketAddress kStunServerAddress =
2015 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
2016 StartStunServer(kStunServerAddress);
2017
2018 PeerConnectionInterface::RTCConfiguration config;
2019 PeerConnectionInterface::IceServer ice_stun_server;
2020 ice_stun_server.urls.push_back(
2021 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
2022 kStunServerAddress.PortAsString());
2023 config.servers.push_back(ice_stun_server);
2024
2025 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2026 ConnectFakeSignaling();
2027 SetPortAllocatorFlags();
2028 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08002029 caller()->AddAudioVideoTracks();
2030 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002031
2032 // Initial state before anything happens.
2033 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
2034 caller()->ice_gathering_state());
2035 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
2036 caller()->ice_connection_state());
Jonas Olsson7a6739e2019-01-15 16:31:55 +01002037 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
2038 caller()->standardized_ice_connection_state());
Steve Antonede9ca52017-10-16 13:04:27 -07002039
2040 // Start the call by creating the offer, setting it as the local description,
2041 // then sending it to the peer who will respond with an answer. This happens
2042 // asynchronously so that we can watch the states as it runs in the
2043 // background.
2044 caller()->CreateAndSetAndSignalOffer();
2045
Steve Antona9b67ce2020-01-16 14:00:44 -08002046 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2047 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002048 FakeClock());
Steve Antona9b67ce2020-01-16 14:00:44 -08002049 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2050 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002051 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002052
2053 // Verify that the observer was notified of the intermediate transitions.
2054 EXPECT_THAT(caller()->ice_connection_state_history(),
2055 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
2056 PeerConnectionInterface::kIceConnectionConnected,
2057 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olssonacd8ae72019-02-25 15:26:24 +01002058 EXPECT_THAT(caller()->standardized_ice_connection_state_history(),
2059 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
2060 PeerConnectionInterface::kIceConnectionConnected,
2061 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olsson635474e2018-10-18 15:58:17 +02002062 EXPECT_THAT(
2063 caller()->peer_connection_state_history(),
2064 ElementsAre(PeerConnectionInterface::PeerConnectionState::kConnecting,
Jonas Olsson635474e2018-10-18 15:58:17 +02002065 PeerConnectionInterface::PeerConnectionState::kConnected));
Steve Antonede9ca52017-10-16 13:04:27 -07002066 EXPECT_THAT(caller()->ice_gathering_state_history(),
2067 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
2068 PeerConnectionInterface::kIceGatheringComplete));
2069
2070 // Block connections to/from the caller and wait for ICE to become
2071 // disconnected.
2072 for (const auto& caller_address : CallerAddresses()) {
2073 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
2074 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01002075 RTC_LOG(LS_INFO) << "Firewall rules applied";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002076 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
2077 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002078 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002079 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
2080 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002081 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002082
2083 // Let ICE re-establish by removing the firewall rules.
2084 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01002085 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002086 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2087 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002088 FakeClock());
Jonas Olssonacd8ae72019-02-25 15:26:24 +01002089 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002090 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002091 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002092
2093 // According to RFC7675, if there is no response within 30 seconds then the
2094 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08002095 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07002096 constexpr int kConsentTimeout = 30000;
2097 for (const auto& caller_address : CallerAddresses()) {
2098 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
2099 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01002100 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002101 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
2102 caller()->ice_connection_state(), kConsentTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002103 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002104 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
2105 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002106 kConsentTimeout, FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002107}
2108
2109// Tests that if the connection doesn't get set up properly we eventually reach
2110// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01002111TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
2112 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002113 // Block connections to/from the caller and wait for ICE to become
2114 // disconnected.
2115 for (const auto& caller_address : CallerAddresses()) {
2116 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
2117 }
2118
2119 ASSERT_TRUE(CreatePeerConnectionWrappers());
2120 ConnectFakeSignaling();
2121 SetPortAllocatorFlags();
2122 SetUpNetworkInterfaces();
2123 caller()->AddAudioVideoTracks();
2124 caller()->CreateAndSetAndSignalOffer();
2125
2126 // According to RFC7675, if there is no response within 30 seconds then the
2127 // peer should consider the other side to have rejected the connection. This
2128 // is signaled by the state transitioning to "failed".
2129 constexpr int kConsentTimeout = 30000;
2130 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
2131 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002132 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002133}
2134
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002135#endif // !defined(THREAD_SANITIZER)
2136
Steve Antonede9ca52017-10-16 13:04:27 -07002137// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
2138// and that the statistics in the metric observers are updated correctly.
Rasmus Brandt32af25b2021-03-17 13:40:21 +01002139// TODO(bugs.webrtc.org/12591): Flaky on Windows.
2140#if defined(WEBRTC_WIN)
2141#define MAYBE_VerifyBestConnection DISABLED_VerifyBestConnection
2142#else
2143#define MAYBE_VerifyBestConnection VerifyBestConnection
2144#endif
2145TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
Steve Antonede9ca52017-10-16 13:04:27 -07002146 ASSERT_TRUE(CreatePeerConnectionWrappers());
2147 ConnectFakeSignaling();
2148 SetPortAllocatorFlags();
2149 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08002150 caller()->AddAudioVideoTracks();
2151 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002152 caller()->CreateAndSetAndSignalOffer();
2153
2154 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08002155 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2156 caller()->ice_connection_state(), kDefaultTimeout);
2157 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2158 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07002159
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002160 // TODO(bugs.webrtc.org/9456): Fix it.
2161 const int num_best_ipv4 = webrtc::metrics::NumEvents(
2162 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
2163 const int num_best_ipv6 = webrtc::metrics::NumEvents(
2164 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07002165 if (TestIPv6()) {
2166 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
2167 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01002168 EXPECT_METRIC_EQ(0, num_best_ipv4);
2169 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07002170 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01002171 EXPECT_METRIC_EQ(1, num_best_ipv4);
2172 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07002173 }
2174
Ying Wangef3998f2019-12-09 13:06:53 +01002175 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
2176 "WebRTC.PeerConnection.CandidatePairType_UDP",
2177 webrtc::kIceCandidatePairHostHost));
2178 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
2179 "WebRTC.PeerConnection.CandidatePairType_UDP",
2180 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07002181}
2182
2183constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
2184 cricket::PORTALLOCATOR_DISABLE_STUN |
2185 cricket::PORTALLOCATOR_DISABLE_RELAY;
2186constexpr uint32_t kFlagsIPv6NoStun =
2187 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
2188 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
2189constexpr uint32_t kFlagsIPv4Stun =
2190 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
2191
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002192INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002193 PeerConnectionIntegrationTest,
2194 PeerConnectionIntegrationIceStatesTest,
2195 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
2196 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2197 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2198 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07002199
Yves Gerey100fe632020-01-17 19:15:53 +01002200INSTANTIATE_TEST_SUITE_P(
2201 PeerConnectionIntegrationTest,
2202 PeerConnectionIntegrationIceStatesTestWithFakeClock,
2203 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
2204 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2205 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2206 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
2207
deadbeef1dcb1642017-03-29 21:08:16 -07002208// This test sets up a call between two parties with audio and video.
2209// During the call, the caller restarts ICE and the test verifies that
2210// new ICE candidates are generated and audio and video still can flow, and the
2211// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002212TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07002213 ASSERT_TRUE(CreatePeerConnectionWrappers());
2214 ConnectFakeSignaling();
2215 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08002216 caller()->AddAudioVideoTracks();
2217 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002218 caller()->CreateAndSetAndSignalOffer();
2219 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2220 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2221 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002222 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2223 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07002224
2225 // To verify that the ICE restart actually occurs, get
2226 // ufrag/password/candidates before and after restart.
2227 // Create an SDP string of the first audio candidate for both clients.
2228 const webrtc::IceCandidateCollection* audio_candidates_caller =
2229 caller()->pc()->local_description()->candidates(0);
2230 const webrtc::IceCandidateCollection* audio_candidates_callee =
2231 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_pre_restart;
2235 ASSERT_TRUE(
2236 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
2237 std::string callee_candidate_pre_restart;
2238 ASSERT_TRUE(
2239 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
2240 const cricket::SessionDescription* desc =
2241 caller()->pc()->local_description()->description();
2242 std::string caller_ufrag_pre_restart =
2243 desc->transport_infos()[0].description.ice_ufrag;
2244 desc = callee()->pc()->local_description()->description();
2245 std::string callee_ufrag_pre_restart =
2246 desc->transport_infos()[0].description.ice_ufrag;
2247
Alex Drake00c7ecf2019-08-06 10:54:47 -07002248 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002249 // Have the caller initiate an ICE restart.
2250 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2251 caller()->CreateAndSetAndSignalOffer();
2252 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2253 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2254 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002255 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07002256 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2257
2258 // Grab the ufrags/candidates again.
2259 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
2260 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
2261 ASSERT_GT(audio_candidates_caller->count(), 0u);
2262 ASSERT_GT(audio_candidates_callee->count(), 0u);
2263 std::string caller_candidate_post_restart;
2264 ASSERT_TRUE(
2265 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
2266 std::string callee_candidate_post_restart;
2267 ASSERT_TRUE(
2268 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
2269 desc = caller()->pc()->local_description()->description();
2270 std::string caller_ufrag_post_restart =
2271 desc->transport_infos()[0].description.ice_ufrag;
2272 desc = callee()->pc()->local_description()->description();
2273 std::string callee_ufrag_post_restart =
2274 desc->transport_infos()[0].description.ice_ufrag;
2275 // Sanity check that an ICE restart was actually negotiated in SDP.
2276 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
2277 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
2278 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
2279 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07002280 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002281
2282 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002283 MediaExpectations media_expectations;
2284 media_expectations.ExpectBidirectionalAudioAndVideo();
2285 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002286}
2287
2288// Verify that audio/video can be received end-to-end when ICE renomination is
2289// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002290TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07002291 PeerConnectionInterface::RTCConfiguration config;
2292 config.enable_ice_renomination = true;
2293 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2294 ConnectFakeSignaling();
2295 // Do normal offer/answer and wait for some frames to be received in each
2296 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002297 caller()->AddAudioVideoTracks();
2298 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002299 caller()->CreateAndSetAndSignalOffer();
2300 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2301 // Sanity check that ICE renomination was actually negotiated.
2302 const cricket::SessionDescription* desc =
2303 caller()->pc()->local_description()->description();
2304 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002305 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002306 }
2307 desc = callee()->pc()->local_description()->description();
2308 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002309 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002310 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08002311 MediaExpectations media_expectations;
2312 media_expectations.ExpectBidirectionalAudioAndVideo();
2313 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002314}
2315
Steve Anton6f25b092017-10-23 09:39:20 -07002316// With a max bundle policy and RTCP muxing, adding a new media description to
2317// the connection should not affect ICE at all because the new media will use
2318// the existing connection.
Rasmus Brandt685be142021-03-15 14:03:38 +01002319// TODO(bugs.webrtc.org/12538): Fails on tsan.
2320#if defined(THREAD_SANITIZER)
2321#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2322 DISABLED_AddMediaToConnectedBundleDoesNotRestartIce
2323#else
2324#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2325 AddMediaToConnectedBundleDoesNotRestartIce
2326#endif
Seth Hampson2f0d7022018-02-20 11:54:42 -08002327TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt685be142021-03-15 14:03:38 +01002328 MAYBE_AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07002329 PeerConnectionInterface::RTCConfiguration config;
2330 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
2331 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
2332 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
2333 config, PeerConnectionInterface::RTCConfiguration()));
2334 ConnectFakeSignaling();
2335
Steve Anton15324772018-01-16 10:26:49 -08002336 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002337 caller()->CreateAndSetAndSignalOffer();
2338 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07002339 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2340 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07002341
2342 caller()->clear_ice_connection_state_history();
2343
Steve Anton15324772018-01-16 10:26:49 -08002344 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002345 caller()->CreateAndSetAndSignalOffer();
2346 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2347
2348 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
2349}
2350
deadbeef1dcb1642017-03-29 21:08:16 -07002351// This test sets up a call between two parties with audio and video. It then
2352// renegotiates setting the video m-line to "port 0", then later renegotiates
2353// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002354TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002355 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
2356 ASSERT_TRUE(CreatePeerConnectionWrappers());
2357 ConnectFakeSignaling();
2358
2359 // Do initial negotiation, only sending media from the caller. Will result in
2360 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08002361 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002362 caller()->CreateAndSetAndSignalOffer();
2363 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2364
2365 // Negotiate again, disabling the video "m=" section (the callee will set the
2366 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002367 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2368 PeerConnectionInterface::RTCOfferAnswerOptions options;
2369 options.offer_to_receive_video = 0;
2370 callee()->SetOfferAnswerOptions(options);
2371 } else {
2372 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002373 callee()
2374 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2375 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002376 });
2377 }
deadbeef1dcb1642017-03-29 21:08:16 -07002378 caller()->CreateAndSetAndSignalOffer();
2379 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2380 // Sanity check that video "m=" section was actually rejected.
2381 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
2382 callee()->pc()->local_description()->description());
2383 ASSERT_NE(nullptr, answer_video_content);
2384 ASSERT_TRUE(answer_video_content->rejected);
2385
2386 // Enable video and do negotiation again, making sure video is received
2387 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002388 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2389 PeerConnectionInterface::RTCOfferAnswerOptions options;
2390 options.offer_to_receive_video = 1;
2391 callee()->SetOfferAnswerOptions(options);
2392 } else {
2393 // The caller's transceiver is stopped, so we need to add another track.
2394 auto caller_transceiver =
2395 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002396 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002397 caller()->AddVideoTrack();
2398 }
2399 callee()->AddVideoTrack();
2400 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07002401 caller()->CreateAndSetAndSignalOffer();
2402 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002403
deadbeef1dcb1642017-03-29 21:08:16 -07002404 // Verify the caller receives frames from the newly added stream, and the
2405 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002406 MediaExpectations media_expectations;
2407 media_expectations.CalleeExpectsSomeAudio();
2408 media_expectations.ExpectBidirectionalVideo();
2409 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002410}
2411
deadbeef1dcb1642017-03-29 21:08:16 -07002412// This tests that if we negotiate after calling CreateSender but before we
2413// have a track, then set a track later, frames from the newly-set track are
2414// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002415TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07002416 MediaFlowsAfterEarlyWarmupWithCreateSender) {
2417 ASSERT_TRUE(CreatePeerConnectionWrappers());
2418 ConnectFakeSignaling();
2419 auto caller_audio_sender =
2420 caller()->pc()->CreateSender("audio", "caller_stream");
2421 auto caller_video_sender =
2422 caller()->pc()->CreateSender("video", "caller_stream");
2423 auto callee_audio_sender =
2424 callee()->pc()->CreateSender("audio", "callee_stream");
2425 auto callee_video_sender =
2426 callee()->pc()->CreateSender("video", "callee_stream");
2427 caller()->CreateAndSetAndSignalOffer();
2428 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2429 // Wait for ICE to complete, without any tracks being set.
2430 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2431 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2432 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2433 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2434 // Now set the tracks, and expect frames to immediately start flowing.
2435 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
2436 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
2437 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
2438 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002439 MediaExpectations media_expectations;
2440 media_expectations.ExpectBidirectionalAudioAndVideo();
2441 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2442}
2443
2444// This tests that if we negotiate after calling AddTransceiver but before we
2445// have a track, then set a track later, frames from the newly-set tracks are
2446// received end-to-end.
2447TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2448 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
2449 ASSERT_TRUE(CreatePeerConnectionWrappers());
2450 ConnectFakeSignaling();
2451 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
2452 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
2453 auto caller_audio_sender = audio_result.MoveValue()->sender();
2454 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
2455 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
2456 auto caller_video_sender = video_result.MoveValue()->sender();
2457 callee()->SetRemoteOfferHandler([this] {
2458 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02002459 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002460 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002461 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002462 RtpTransceiverDirection::kSendRecv);
2463 });
2464 caller()->CreateAndSetAndSignalOffer();
2465 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2466 // Wait for ICE to complete, without any tracks being set.
2467 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2468 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2469 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2470 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2471 // Now set the tracks, and expect frames to immediately start flowing.
2472 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
2473 auto callee_video_sender = callee()->pc()->GetSenders()[1];
2474 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
2475 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
2476 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
2477 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
2478 MediaExpectations media_expectations;
2479 media_expectations.ExpectBidirectionalAudioAndVideo();
2480 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002481}
2482
2483// This test verifies that a remote video track can be added via AddStream,
2484// and sent end-to-end. For this particular test, it's simply echoed back
2485// from the caller to the callee, rather than being forwarded to a third
2486// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002487TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07002488 ASSERT_TRUE(CreatePeerConnectionWrappers());
2489 ConnectFakeSignaling();
2490 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08002491 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002492 caller()->CreateAndSetAndSignalOffer();
2493 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002494 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07002495
2496 // Echo the stream back, and do a new offer/anwer (initiated by callee this
2497 // time).
2498 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
2499 callee()->CreateAndSetAndSignalOffer();
2500 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2501
Seth Hampson2f0d7022018-02-20 11:54:42 -08002502 MediaExpectations media_expectations;
2503 media_expectations.ExpectBidirectionalVideo();
2504 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002505}
2506
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002507#if !defined(THREAD_SANITIZER)
2508// This test provokes TSAN errors. bugs.webrtc.org/11282
2509
deadbeef1dcb1642017-03-29 21:08:16 -07002510// Test that we achieve the expected end-to-end connection time, using a
2511// fake clock and simulated latency on the media and signaling paths.
2512// We use a TURN<->TURN connection because this is usually the quickest to
2513// set up initially, especially when we're confident the connection will work
2514// and can start sending media before we get a STUN response.
2515//
2516// With various optimizations enabled, here are the network delays we expect to
2517// be on the critical path:
2518// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
2519// signaling answer (with DTLS fingerprint).
2520// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
2521// using TURN<->TURN pair, and DTLS exchange is 4 packets,
2522// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01002523TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2524 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07002525 static constexpr int media_hop_delay_ms = 50;
2526 static constexpr int signaling_trip_delay_ms = 500;
2527 // For explanation of these values, see comment above.
2528 static constexpr int required_media_hops = 9;
2529 static constexpr int required_signaling_trips = 2;
2530 // For internal delays (such as posting an event asychronously).
2531 static constexpr int allowed_internal_delay_ms = 20;
2532 static constexpr int total_connection_time_ms =
2533 media_hop_delay_ms * required_media_hops +
2534 signaling_trip_delay_ms * required_signaling_trips +
2535 allowed_internal_delay_ms;
2536
2537 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2538 3478};
2539 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2540 0};
2541 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2542 3478};
2543 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2544 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002545 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
2546 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002547
Seth Hampsonaed71642018-06-11 07:41:32 -07002548 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
2549 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07002550 // Bypass permission check on received packets so media can be sent before
2551 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07002552 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
2553 turn_server_1->set_enable_permission_checks(false);
2554 });
2555 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
2556 turn_server_2->set_enable_permission_checks(false);
2557 });
deadbeef1dcb1642017-03-29 21:08:16 -07002558
2559 PeerConnectionInterface::RTCConfiguration client_1_config;
2560 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2561 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2562 ice_server_1.username = "test";
2563 ice_server_1.password = "test";
2564 client_1_config.servers.push_back(ice_server_1);
2565 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2566 client_1_config.presume_writable_when_fully_relayed = true;
2567
2568 PeerConnectionInterface::RTCConfiguration client_2_config;
2569 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2570 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2571 ice_server_2.username = "test";
2572 ice_server_2.password = "test";
2573 client_2_config.servers.push_back(ice_server_2);
2574 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2575 client_2_config.presume_writable_when_fully_relayed = true;
2576
2577 ASSERT_TRUE(
2578 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2579 // Set up the simulated delays.
2580 SetSignalingDelayMs(signaling_trip_delay_ms);
2581 ConnectFakeSignaling();
2582 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
2583 virtual_socket_server()->UpdateDelayDistribution();
2584
2585 // Set "offer to receive audio/video" without adding any tracks, so we just
2586 // set up ICE/DTLS with no media.
2587 PeerConnectionInterface::RTCOfferAnswerOptions options;
2588 options.offer_to_receive_audio = 1;
2589 options.offer_to_receive_video = 1;
2590 caller()->SetOfferAnswerOptions(options);
2591 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07002592 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01002593 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07002594 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
2595 // If this is not done a DCHECK can be hit in ports.cc, because a large
2596 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07002597 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07002598}
2599
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002600#endif // !defined(THREAD_SANITIZER)
2601
Jonas Orelandbdcee282017-10-10 14:01:40 +02002602// Verify that a TurnCustomizer passed in through RTCConfiguration
2603// is actually used by the underlying TURN candidate pair.
2604// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002605TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02002606 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2607 3478};
2608 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2609 0};
2610 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2611 3478};
2612 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2613 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002614 CreateTurnServer(turn_server_1_internal_address,
2615 turn_server_1_external_address);
2616 CreateTurnServer(turn_server_2_internal_address,
2617 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002618
2619 PeerConnectionInterface::RTCConfiguration client_1_config;
2620 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2621 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2622 ice_server_1.username = "test";
2623 ice_server_1.password = "test";
2624 client_1_config.servers.push_back(ice_server_1);
2625 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002626 auto* customizer1 = CreateTurnCustomizer();
2627 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002628
2629 PeerConnectionInterface::RTCConfiguration client_2_config;
2630 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2631 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2632 ice_server_2.username = "test";
2633 ice_server_2.password = "test";
2634 client_2_config.servers.push_back(ice_server_2);
2635 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002636 auto* customizer2 = CreateTurnCustomizer();
2637 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002638
2639 ASSERT_TRUE(
2640 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2641 ConnectFakeSignaling();
2642
2643 // Set "offer to receive audio/video" without adding any tracks, so we just
2644 // set up ICE/DTLS with no media.
2645 PeerConnectionInterface::RTCOfferAnswerOptions options;
2646 options.offer_to_receive_audio = 1;
2647 options.offer_to_receive_video = 1;
2648 caller()->SetOfferAnswerOptions(options);
2649 caller()->CreateAndSetAndSignalOffer();
2650 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2651
Seth Hampsonaed71642018-06-11 07:41:32 -07002652 ExpectTurnCustomizerCountersIncremented(customizer1);
2653 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002654}
2655
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002656// Verifies that you can use TCP instead of UDP to connect to a TURN server and
2657// send media between the caller and the callee.
2658TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
2659 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2660 3478};
2661 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2662
2663 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07002664 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2665 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002666
2667 webrtc::PeerConnectionInterface::IceServer ice_server;
2668 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
2669 ice_server.username = "test";
2670 ice_server.password = "test";
2671
2672 PeerConnectionInterface::RTCConfiguration client_1_config;
2673 client_1_config.servers.push_back(ice_server);
2674 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2675
2676 PeerConnectionInterface::RTCConfiguration client_2_config;
2677 client_2_config.servers.push_back(ice_server);
2678 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2679
2680 ASSERT_TRUE(
2681 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2682
2683 // Do normal offer/answer and wait for ICE to complete.
2684 ConnectFakeSignaling();
2685 caller()->AddAudioVideoTracks();
2686 callee()->AddAudioVideoTracks();
2687 caller()->CreateAndSetAndSignalOffer();
2688 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2689 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2690 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2691
2692 MediaExpectations media_expectations;
2693 media_expectations.ExpectBidirectionalAudioAndVideo();
2694 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2695}
2696
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002697// Verify that a SSLCertificateVerifier passed in through
2698// PeerConnectionDependencies is actually used by the underlying SSL
2699// implementation to determine whether a certificate presented by the TURN
2700// server is accepted by the client. Note that openssladapter_unittest.cc
2701// contains more detailed, lower-level tests.
2702TEST_P(PeerConnectionIntegrationTest,
2703 SSLCertificateVerifierUsedForTurnConnections) {
2704 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2705 3478};
2706 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2707
2708 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2709 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002710 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2711 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002712
2713 webrtc::PeerConnectionInterface::IceServer ice_server;
2714 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2715 ice_server.username = "test";
2716 ice_server.password = "test";
2717
2718 PeerConnectionInterface::RTCConfiguration client_1_config;
2719 client_1_config.servers.push_back(ice_server);
2720 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2721
2722 PeerConnectionInterface::RTCConfiguration client_2_config;
2723 client_2_config.servers.push_back(ice_server);
2724 // Setting the type to kRelay forces the connection to go through a TURN
2725 // server.
2726 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2727
2728 // Get a copy to the pointer so we can verify calls later.
2729 rtc::TestCertificateVerifier* client_1_cert_verifier =
2730 new rtc::TestCertificateVerifier();
2731 client_1_cert_verifier->verify_certificate_ = true;
2732 rtc::TestCertificateVerifier* client_2_cert_verifier =
2733 new rtc::TestCertificateVerifier();
2734 client_2_cert_verifier->verify_certificate_ = true;
2735
2736 // Create the dependencies with the test certificate verifier.
2737 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2738 client_1_deps.tls_cert_verifier =
2739 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2740 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2741 client_2_deps.tls_cert_verifier =
2742 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2743
2744 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2745 client_1_config, std::move(client_1_deps), client_2_config,
2746 std::move(client_2_deps)));
2747 ConnectFakeSignaling();
2748
2749 // Set "offer to receive audio/video" without adding any tracks, so we just
2750 // set up ICE/DTLS with no media.
2751 PeerConnectionInterface::RTCOfferAnswerOptions options;
2752 options.offer_to_receive_audio = 1;
2753 options.offer_to_receive_video = 1;
2754 caller()->SetOfferAnswerOptions(options);
2755 caller()->CreateAndSetAndSignalOffer();
2756 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2757
2758 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2759 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002760}
2761
2762TEST_P(PeerConnectionIntegrationTest,
2763 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
2764 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2765 3478};
2766 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2767
2768 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2769 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002770 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2771 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002772
2773 webrtc::PeerConnectionInterface::IceServer ice_server;
2774 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2775 ice_server.username = "test";
2776 ice_server.password = "test";
2777
2778 PeerConnectionInterface::RTCConfiguration client_1_config;
2779 client_1_config.servers.push_back(ice_server);
2780 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2781
2782 PeerConnectionInterface::RTCConfiguration client_2_config;
2783 client_2_config.servers.push_back(ice_server);
2784 // Setting the type to kRelay forces the connection to go through a TURN
2785 // server.
2786 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2787
2788 // Get a copy to the pointer so we can verify calls later.
2789 rtc::TestCertificateVerifier* client_1_cert_verifier =
2790 new rtc::TestCertificateVerifier();
2791 client_1_cert_verifier->verify_certificate_ = false;
2792 rtc::TestCertificateVerifier* client_2_cert_verifier =
2793 new rtc::TestCertificateVerifier();
2794 client_2_cert_verifier->verify_certificate_ = false;
2795
2796 // Create the dependencies with the test certificate verifier.
2797 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2798 client_1_deps.tls_cert_verifier =
2799 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2800 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2801 client_2_deps.tls_cert_verifier =
2802 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2803
2804 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2805 client_1_config, std::move(client_1_deps), client_2_config,
2806 std::move(client_2_deps)));
2807 ConnectFakeSignaling();
2808
2809 // Set "offer to receive audio/video" without adding any tracks, so we just
2810 // set up ICE/DTLS with no media.
2811 PeerConnectionInterface::RTCOfferAnswerOptions options;
2812 options.offer_to_receive_audio = 1;
2813 options.offer_to_receive_video = 1;
2814 caller()->SetOfferAnswerOptions(options);
2815 caller()->CreateAndSetAndSignalOffer();
2816 bool wait_res = true;
2817 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
2818 // properly, should be able to just wait for a state of "failed" instead of
2819 // waiting a fixed 10 seconds.
2820 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
2821 ASSERT_FALSE(wait_res);
2822
2823 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2824 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002825}
2826
Qingsi Wang25ec8882019-11-15 12:33:05 -08002827// Test that the injected ICE transport factory is used to create ICE transports
2828// for WebRTC connections.
2829TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
2830 PeerConnectionInterface::RTCConfiguration default_config;
2831 PeerConnectionDependencies dependencies(nullptr);
2832 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
2833 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
2834 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02002835 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
2836 std::move(dependencies), nullptr,
2837 /*reset_encoder_factory=*/false,
2838 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08002839 ASSERT_TRUE(wrapper);
2840 wrapper->CreateDataChannel();
Tommi87f70902021-04-27 14:43:08 +02002841 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Qingsi Wang25ec8882019-11-15 12:33:05 -08002842 wrapper->pc()->SetLocalDescription(observer,
2843 wrapper->CreateOfferAndWait().release());
2844}
2845
deadbeefc964d0b2017-04-03 10:03:35 -07002846// Test that audio and video flow end-to-end when codec names don't use the
2847// expected casing, given that they're supposed to be case insensitive. To test
2848// this, all but one codec is removed from each media description, and its
2849// casing is changed.
2850//
2851// In the past, this has regressed and caused crashes/black video, due to the
2852// fact that code at some layers was doing case-insensitive comparisons and
2853// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002854TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07002855 ASSERT_TRUE(CreatePeerConnectionWrappers());
2856 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002857 caller()->AddAudioVideoTracks();
2858 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07002859
2860 // Remove all but one audio/video codec (opus and VP8), and change the
2861 // casing of the caller's generated offer.
2862 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
2863 cricket::AudioContentDescription* audio =
2864 GetFirstAudioContentDescription(description);
2865 ASSERT_NE(nullptr, audio);
2866 auto audio_codecs = audio->codecs();
2867 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
2868 [](const cricket::AudioCodec& codec) {
2869 return codec.name != "opus";
2870 }),
2871 audio_codecs.end());
2872 ASSERT_EQ(1u, audio_codecs.size());
2873 audio_codecs[0].name = "OpUs";
2874 audio->set_codecs(audio_codecs);
2875
2876 cricket::VideoContentDescription* video =
2877 GetFirstVideoContentDescription(description);
2878 ASSERT_NE(nullptr, video);
2879 auto video_codecs = video->codecs();
2880 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
2881 [](const cricket::VideoCodec& codec) {
2882 return codec.name != "VP8";
2883 }),
2884 video_codecs.end());
2885 ASSERT_EQ(1u, video_codecs.size());
2886 video_codecs[0].name = "vP8";
2887 video->set_codecs(video_codecs);
2888 });
2889
2890 caller()->CreateAndSetAndSignalOffer();
2891 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2892
2893 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002894 MediaExpectations media_expectations;
2895 media_expectations.ExpectBidirectionalAudioAndVideo();
2896 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07002897}
2898
Jonas Oreland49ac5952018-09-26 16:04:32 +02002899TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07002900 ASSERT_TRUE(CreatePeerConnectionWrappers());
2901 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002902 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07002903 caller()->CreateAndSetAndSignalOffer();
2904 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07002905 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002906 MediaExpectations media_expectations;
2907 media_expectations.CalleeExpectsSomeAudio(1);
2908 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02002909 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07002910 auto receiver = callee()->pc()->GetReceivers()[0];
2911 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002912 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07002913 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
2914 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02002915 sources[0].source_id());
2916 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
2917}
2918
2919TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
2920 ASSERT_TRUE(CreatePeerConnectionWrappers());
2921 ConnectFakeSignaling();
2922 caller()->AddVideoTrack();
2923 caller()->CreateAndSetAndSignalOffer();
2924 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2925 // Wait for one video frame to be received by the callee.
2926 MediaExpectations media_expectations;
2927 media_expectations.CalleeExpectsSomeVideo(1);
2928 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2929 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2930 auto receiver = callee()->pc()->GetReceivers()[0];
2931 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
2932 auto sources = receiver->GetSources();
2933 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02002934 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002935 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
2936 sources[0].source_id());
2937 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07002938}
2939
deadbeef2f425aa2017-04-14 10:41:32 -07002940// Test that if a track is removed and added again with a different stream ID,
2941// the new stream ID is successfully communicated in SDP and media continues to
2942// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002943// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
2944// it will not reuse a transceiver that has already been sending. After creating
2945// a new transceiver it tries to create an offer with two senders of the same
2946// track ids and it fails.
2947TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07002948 ASSERT_TRUE(CreatePeerConnectionWrappers());
2949 ConnectFakeSignaling();
2950
deadbeef2f425aa2017-04-14 10:41:32 -07002951 // Add track using stream 1, do offer/answer.
2952 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2953 caller()->CreateLocalAudioTrack();
2954 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07002955 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07002956 caller()->CreateAndSetAndSignalOffer();
2957 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002958 {
2959 MediaExpectations media_expectations;
2960 media_expectations.CalleeExpectsSomeAudio(1);
2961 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2962 }
deadbeef2f425aa2017-04-14 10:41:32 -07002963 // Remove the sender, and create a new one with the new stream.
Harald Alvestrand93dd7632022-01-19 12:28:45 +00002964 caller()->pc()->RemoveTrackOrError(sender);
Steve Antond78323f2018-07-11 11:13:44 -07002965 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07002966 caller()->CreateAndSetAndSignalOffer();
2967 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2968 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002969 {
2970 MediaExpectations media_expectations;
2971 media_expectations.CalleeExpectsSomeAudio();
2972 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2973 }
deadbeef2f425aa2017-04-14 10:41:32 -07002974}
2975
Seth Hampson2f0d7022018-02-20 11:54:42 -08002976TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02002977 ASSERT_TRUE(CreatePeerConnectionWrappers());
2978 ConnectFakeSignaling();
2979
Mirko Bonadei317a1f02019-09-17 17:06:18 +02002980 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002981 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
2982 ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true));
Elad Alon99c3fe52017-10-13 16:29:40 +02002983 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01002984 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
2985 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02002986
Steve Anton15324772018-01-16 10:26:49 -08002987 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02002988 caller()->CreateAndSetAndSignalOffer();
2989 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2990}
2991
Steve Antonede9ca52017-10-16 13:04:27 -07002992// Test that if candidates are only signaled by applying full session
2993// descriptions (instead of using AddIceCandidate), the peers can connect to
2994// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002995TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07002996 ASSERT_TRUE(CreatePeerConnectionWrappers());
2997 // Each side will signal the session descriptions but not candidates.
2998 ConnectFakeSignalingForSdpOnly();
2999
3000 // Add audio video track and exchange the initial offer/answer with media
3001 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08003002 caller()->AddAudioVideoTracks();
3003 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003004 caller()->CreateAndSetAndSignalOffer();
3005
3006 // Wait for all candidates to be gathered on both the caller and callee.
3007 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
3008 caller()->ice_gathering_state(), kDefaultTimeout);
3009 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
3010 callee()->ice_gathering_state(), kDefaultTimeout);
3011
3012 // The candidates will now be included in the session description, so
3013 // signaling them will start the ICE connection.
3014 caller()->CreateAndSetAndSignalOffer();
3015 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3016
3017 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003018 MediaExpectations media_expectations;
3019 media_expectations.ExpectBidirectionalAudioAndVideo();
3020 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07003021}
3022
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00003023#if !defined(THREAD_SANITIZER)
3024// These tests provokes TSAN errors. See bugs.webrtc.org/11305.
3025
henrika5f6bf242017-11-01 11:06:56 +01003026// Test that SetAudioPlayout can be used to disable audio playout from the
3027// start, then later enable it. This may be useful, for example, if the caller
3028// needs to play a local ringtone until some event occurs, after which it
3029// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003030TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01003031 ASSERT_TRUE(CreatePeerConnectionWrappers());
3032 ConnectFakeSignaling();
3033
3034 // Set up audio-only call where audio playout is disabled on caller's side.
3035 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08003036 caller()->AddAudioTrack();
3037 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01003038 caller()->CreateAndSetAndSignalOffer();
3039 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3040
3041 // Pump messages for a second.
3042 WAIT(false, 1000);
3043 // Since audio playout is disabled, the caller shouldn't have received
3044 // anything (at the playout level, at least).
3045 EXPECT_EQ(0, caller()->audio_frames_received());
3046 // As a sanity check, make sure the callee (for which playout isn't disabled)
3047 // did still see frames on its audio level.
3048 ASSERT_GT(callee()->audio_frames_received(), 0);
3049
3050 // Enable playout again, and ensure audio starts flowing.
3051 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003052 MediaExpectations media_expectations;
3053 media_expectations.ExpectBidirectionalAudio();
3054 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01003055}
3056
Harald Alvestrand39993842021-02-17 09:05:31 +00003057double GetAudioEnergyStat(PeerConnectionIntegrationWrapper* pc) {
henrika5f6bf242017-11-01 11:06:56 +01003058 auto report = pc->NewGetStats();
3059 auto track_stats_list =
3060 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3061 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
3062 for (const auto* track_stats : track_stats_list) {
3063 if (track_stats->remote_source.is_defined() &&
3064 *track_stats->remote_source) {
3065 remote_track_stats = track_stats;
3066 break;
3067 }
3068 }
3069
3070 if (!remote_track_stats->total_audio_energy.is_defined()) {
3071 return 0.0;
3072 }
3073 return *remote_track_stats->total_audio_energy;
3074}
3075
3076// Test that if audio playout is disabled via the SetAudioPlayout() method, then
3077// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003078TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01003079 DisableAudioPlayoutStillGeneratesAudioStats) {
3080 ASSERT_TRUE(CreatePeerConnectionWrappers());
3081 ConnectFakeSignaling();
3082
3083 // Set up audio-only call where playout is disabled but audio-processing is
3084 // still active.
Steve Anton15324772018-01-16 10:26:49 -08003085 caller()->AddAudioTrack();
3086 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01003087 caller()->pc()->SetAudioPlayout(false);
3088
3089 caller()->CreateAndSetAndSignalOffer();
3090 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3091
3092 // Wait for the callee to receive audio stats.
3093 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
3094}
3095
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00003096#endif // !defined(THREAD_SANITIZER)
3097
henrika4f167df2017-11-01 14:45:55 +01003098// Test that SetAudioRecording can be used to disable audio recording from the
3099// start, then later enable it. This may be useful, for example, if the caller
3100// wants to ensure that no audio resources are active before a certain state
3101// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003102TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01003103 ASSERT_TRUE(CreatePeerConnectionWrappers());
3104 ConnectFakeSignaling();
3105
3106 // Set up audio-only call where audio recording is disabled on caller's side.
3107 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08003108 caller()->AddAudioTrack();
3109 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01003110 caller()->CreateAndSetAndSignalOffer();
3111 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3112
3113 // Pump messages for a second.
3114 WAIT(false, 1000);
3115 // Since caller has disabled audio recording, the callee shouldn't have
3116 // received anything.
3117 EXPECT_EQ(0, callee()->audio_frames_received());
3118 // As a sanity check, make sure the caller did still see frames on its
3119 // audio level since audio recording is enabled on the calle side.
3120 ASSERT_GT(caller()->audio_frames_received(), 0);
3121
3122 // Enable audio recording again, and ensure audio starts flowing.
3123 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003124 MediaExpectations media_expectations;
3125 media_expectations.ExpectBidirectionalAudio();
3126 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01003127}
3128
Qingsi Wang7685e862018-06-11 20:15:46 -07003129TEST_P(PeerConnectionIntegrationTest,
3130 IceEventsGeneratedAndLoggedInRtcEventLog) {
3131 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
3132 ConnectFakeSignaling();
3133 PeerConnectionInterface::RTCOfferAnswerOptions options;
3134 options.offer_to_receive_audio = 1;
3135 caller()->SetOfferAnswerOptions(options);
3136 caller()->CreateAndSetAndSignalOffer();
3137 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3138 ASSERT_NE(nullptr, caller()->event_log_factory());
3139 ASSERT_NE(nullptr, callee()->event_log_factory());
3140 webrtc::FakeRtcEventLog* caller_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01003141 caller()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07003142 webrtc::FakeRtcEventLog* callee_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01003143 callee()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07003144 ASSERT_NE(nullptr, caller_event_log);
3145 ASSERT_NE(nullptr, callee_event_log);
3146 int caller_ice_config_count = caller_event_log->GetEventCount(
3147 webrtc::RtcEvent::Type::IceCandidatePairConfig);
3148 int caller_ice_event_count = caller_event_log->GetEventCount(
3149 webrtc::RtcEvent::Type::IceCandidatePairEvent);
3150 int callee_ice_config_count = callee_event_log->GetEventCount(
3151 webrtc::RtcEvent::Type::IceCandidatePairConfig);
3152 int callee_ice_event_count = callee_event_log->GetEventCount(
3153 webrtc::RtcEvent::Type::IceCandidatePairEvent);
3154 EXPECT_LT(0, caller_ice_config_count);
3155 EXPECT_LT(0, caller_ice_event_count);
3156 EXPECT_LT(0, callee_ice_config_count);
3157 EXPECT_LT(0, callee_ice_event_count);
3158}
3159
Qingsi Wangc129c352019-04-18 10:41:58 -07003160TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07003161 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3162 3478};
3163 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3164
3165 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3166
3167 webrtc::PeerConnectionInterface::IceServer ice_server;
3168 ice_server.urls.push_back("turn:88.88.88.0:3478");
3169 ice_server.username = "test";
3170 ice_server.password = "test";
3171
3172 PeerConnectionInterface::RTCConfiguration caller_config;
3173 caller_config.servers.push_back(ice_server);
3174 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3175 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07003176 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07003177
3178 PeerConnectionInterface::RTCConfiguration callee_config;
3179 callee_config.servers.push_back(ice_server);
3180 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3181 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07003182 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07003183
3184 ASSERT_TRUE(
3185 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3186
3187 // Do normal offer/answer and wait for ICE to complete.
3188 ConnectFakeSignaling();
3189 caller()->AddAudioVideoTracks();
3190 callee()->AddAudioVideoTracks();
3191 caller()->CreateAndSetAndSignalOffer();
3192 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3193 // Since we are doing continual gathering, the ICE transport does not reach
3194 // kIceGatheringComplete (see
3195 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
3196 // kIceConnectionComplete.
3197 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3198 caller()->ice_connection_state(), kDefaultTimeout);
3199 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3200 callee()->ice_connection_state(), kDefaultTimeout);
3201 // Note that we cannot use the metric
Artem Titovcfea2182021-08-10 01:22:31 +02003202 // `WebRTC.PeerConnection.CandidatePairType_UDP` in this test since this
Qingsi Wangc129c352019-04-18 10:41:58 -07003203 // metric is only populated when we reach kIceConnectionComplete in the
3204 // current implementation.
3205 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3206 caller()->last_candidate_gathered().type());
3207 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3208 callee()->last_candidate_gathered().type());
3209
3210 // Loosen the caller's candidate filter.
3211 caller_config = caller()->pc()->GetConfiguration();
3212 caller_config.type = webrtc::PeerConnectionInterface::kAll;
3213 caller()->pc()->SetConfiguration(caller_config);
3214 // We should have gathered a new host candidate.
3215 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3216 caller()->last_candidate_gathered().type(), kDefaultTimeout);
3217
3218 // Loosen the callee's candidate filter.
3219 callee_config = callee()->pc()->GetConfiguration();
3220 callee_config.type = webrtc::PeerConnectionInterface::kAll;
3221 callee()->pc()->SetConfiguration(callee_config);
3222 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3223 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02003224
3225 // Create an offer and verify that it does not contain an ICE restart (i.e new
3226 // ice credentials).
3227 std::string caller_ufrag_pre_offer = caller()
3228 ->pc()
3229 ->local_description()
3230 ->description()
3231 ->transport_infos()[0]
3232 .description.ice_ufrag;
3233 caller()->CreateAndSetAndSignalOffer();
3234 std::string caller_ufrag_post_offer = caller()
3235 ->pc()
3236 ->local_description()
3237 ->description()
3238 ->transport_infos()[0]
3239 .description.ice_ufrag;
3240 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07003241}
3242
Eldar Relloda13ea22019-06-01 12:23:43 +03003243TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03003244 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3245 3478};
3246 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3247
3248 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3249
3250 webrtc::PeerConnectionInterface::IceServer ice_server;
3251 ice_server.urls.push_back("turn:88.88.88.0:3478");
3252 ice_server.username = "test";
3253 ice_server.password = "123";
3254
3255 PeerConnectionInterface::RTCConfiguration caller_config;
3256 caller_config.servers.push_back(ice_server);
3257 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3258 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3259
3260 PeerConnectionInterface::RTCConfiguration callee_config;
3261 callee_config.servers.push_back(ice_server);
3262 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3263 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3264
3265 ASSERT_TRUE(
3266 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3267
3268 // Do normal offer/answer and wait for ICE to complete.
3269 ConnectFakeSignaling();
3270 caller()->AddAudioVideoTracks();
3271 callee()->AddAudioVideoTracks();
3272 caller()->CreateAndSetAndSignalOffer();
3273 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3274 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
3275 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
3276 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02003277 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03003278}
3279
Eldar Rellofa8019c2020-05-14 11:59:33 +03003280TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
3281 webrtc::PeerConnectionInterface::IceServer ice_server;
3282 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
3283 ice_server.username = "test";
3284 ice_server.password = "test";
3285
3286 PeerConnectionInterface::RTCConfiguration caller_config;
3287 caller_config.servers.push_back(ice_server);
3288 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3289 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3290
3291 PeerConnectionInterface::RTCConfiguration callee_config;
3292 callee_config.servers.push_back(ice_server);
3293 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3294 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3295
3296 ASSERT_TRUE(
3297 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3298
3299 // Do normal offer/answer and wait for ICE to complete.
3300 ConnectFakeSignaling();
3301 caller()->AddAudioVideoTracks();
3302 callee()->AddAudioVideoTracks();
3303 caller()->CreateAndSetAndSignalOffer();
3304 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3305 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
3306 EXPECT_EQ(caller()->error_event().address, "");
3307}
3308
Eldar Rello5ab79e62019-10-09 18:29:44 +03003309TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3310 AudioKeepsFlowingAfterImplicitRollback) {
3311 PeerConnectionInterface::RTCConfiguration config;
3312 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3313 config.enable_implicit_rollback = true;
3314 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3315 ConnectFakeSignaling();
3316 caller()->AddAudioTrack();
3317 callee()->AddAudioTrack();
3318 caller()->CreateAndSetAndSignalOffer();
3319 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3320 MediaExpectations media_expectations;
3321 media_expectations.ExpectBidirectionalAudio();
3322 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3323 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
3324 caller()->AddVideoTrack();
3325 callee()->AddVideoTrack();
Tommi87f70902021-04-27 14:43:08 +02003326 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003327 callee()->pc()->SetLocalDescription(observer,
3328 callee()->CreateOfferAndWait().release());
3329 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3330 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
3331 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3332 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3333}
3334
3335TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3336 ImplicitRollbackVisitsStableState) {
3337 RTCConfiguration config;
3338 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3339 config.enable_implicit_rollback = true;
3340
3341 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3342
Tommi87f70902021-04-27 14:43:08 +02003343 auto sld_observer =
3344 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003345 callee()->pc()->SetLocalDescription(sld_observer,
3346 callee()->CreateOfferAndWait().release());
3347 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
3348 EXPECT_EQ(sld_observer->error(), "");
3349
Tommi87f70902021-04-27 14:43:08 +02003350 auto srd_observer =
3351 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003352 callee()->pc()->SetRemoteDescription(
3353 srd_observer, caller()->CreateOfferAndWait().release());
3354 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
3355 EXPECT_EQ(srd_observer->error(), "");
3356
3357 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
3358 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
3359 PeerConnectionInterface::kStable,
3360 PeerConnectionInterface::kHaveRemoteOffer));
3361}
3362
Eldar Rellobd9c33a2020-10-01 17:52:45 +03003363TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3364 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
3365 ASSERT_TRUE(CreatePeerConnectionWrappers());
3366 ConnectFakeSignaling();
3367 caller()->AddVideoTrack();
3368 callee()->AddVideoTrack();
3369 auto munger = [](cricket::SessionDescription* desc) {
3370 cricket::VideoContentDescription* video =
3371 GetFirstVideoContentDescription(desc);
3372 auto codecs = video->codecs();
3373 for (auto&& codec : codecs) {
3374 if (codec.name == "H264") {
3375 std::string value;
3376 // The parameter is not supposed to be present in SDP by default.
3377 EXPECT_FALSE(
3378 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3379 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
3380 std::string(""));
3381 }
3382 }
3383 video->set_codecs(codecs);
3384 };
3385 // Munge local offer for SLD.
3386 caller()->SetGeneratedSdpMunger(munger);
3387 // Munge remote answer for SRD.
3388 caller()->SetReceivedSdpMunger(munger);
3389 caller()->CreateAndSetAndSignalOffer();
3390 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3391 // Observe that after munging the parameter is present in generated SDP.
3392 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
3393 cricket::VideoContentDescription* video =
3394 GetFirstVideoContentDescription(desc);
3395 for (auto&& codec : video->codecs()) {
3396 if (codec.name == "H264") {
3397 std::string value;
3398 EXPECT_TRUE(
3399 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3400 }
3401 }
3402 });
3403 caller()->CreateOfferAndWait();
3404}
3405
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003406TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00003407 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003408 PeerConnectionInterface::RTCConfiguration config;
3409 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3410 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3411 ConnectFakeSignaling();
3412 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3413
3414 caller()->CreateAndSetAndSignalOffer();
3415 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3416 int current_size = caller()->pc()->GetTransceivers().size();
3417 // Add more tracks until we get close to having issues.
3418 // Issues have been seen at:
3419 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003420 // - 16 tracks on android_arm_dbg (flaky)
3421 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003422 // Double the number of tracks
3423 for (int i = 0; i < current_size; i++) {
3424 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3425 }
3426 current_size = caller()->pc()->GetTransceivers().size();
3427 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3428 auto start_time_ms = rtc::TimeMillis();
3429 caller()->CreateAndSetAndSignalOffer();
3430 // We want to stop when the time exceeds one second.
3431 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3432 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3433 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3434 ASSERT_GT(1000, elapsed_time_ms)
3435 << "Audio transceivers: Negotiation took too long after "
3436 << current_size << " tracks added";
3437 }
3438}
3439
3440TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3441 RenegotiateManyVideoTransceivers) {
3442 PeerConnectionInterface::RTCConfiguration config;
3443 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3444 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3445 ConnectFakeSignaling();
3446 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3447
3448 caller()->CreateAndSetAndSignalOffer();
3449 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3450 int current_size = caller()->pc()->GetTransceivers().size();
3451 // Add more tracks until we get close to having issues.
3452 // Issues have been seen at:
3453 // - 96 on a Linux workstation
3454 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
3455 // - 32 on android_arm64_rel and linux_dbg bots
Harald Alvestrand785e23b2021-03-15 21:26:27 +00003456 // - 16 on Android 64 (Nexus 5x)
3457 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003458 // Double the number of tracks
3459 for (int i = 0; i < current_size; i++) {
3460 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3461 }
3462 current_size = caller()->pc()->GetTransceivers().size();
3463 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3464 auto start_time_ms = rtc::TimeMillis();
3465 caller()->CreateAndSetAndSignalOffer();
3466 // We want to stop when the time exceeds one second.
3467 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3468 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3469 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3470 ASSERT_GT(1000, elapsed_time_ms)
3471 << "Video transceivers: Negotiation took too long after "
3472 << current_size << " tracks added";
3473 }
3474}
3475
Harald Alvestrand94324f22021-01-13 12:31:53 +00003476TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3477 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
3478 PeerConnectionInterface::RTCConfiguration config;
3479 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3480 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3481 ConnectFakeSignaling();
3482 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003483 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003484 caller()->CreateAndSetAndSignalOffer();
3485 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3486 // Wait until we can see the audio flowing.
3487 MediaExpectations media_expectations;
3488 media_expectations.CalleeExpectsSomeAudio();
3489 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3490
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003491 // Get the baseline numbers for audio_packets and audio_delay
3492 // in both directions.
3493 caller()->StartWatchingDelayStats();
3494 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003495
3496 int current_size = caller()->pc()->GetTransceivers().size();
3497 // Add more tracks until we get close to having issues.
3498 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003499 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00003500 // Double the number of tracks
3501 for (int i = 0; i < current_size; i++) {
3502 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3503 }
3504 current_size = caller()->pc()->GetTransceivers().size();
3505 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3506 auto start_time_ms = rtc::TimeMillis();
3507 caller()->CreateAndSetAndSignalOffer();
3508 // We want to stop when the time exceeds one second.
3509 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3510 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3511 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3512 // This is a guard against the test using excessive amounts of time.
3513 ASSERT_GT(5000, elapsed_time_ms)
3514 << "Video transceivers: Negotiation took too long after "
3515 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003516 caller()->UpdateDelayStats("caller reception", current_size);
3517 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00003518 }
3519}
3520
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003521INSTANTIATE_TEST_SUITE_P(
3522 PeerConnectionIntegrationTest,
3523 PeerConnectionIntegrationTest,
3524 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3525 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3526 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3527 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Steve Antond3679212018-01-17 17:41:02 -08003528
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003529INSTANTIATE_TEST_SUITE_P(
3530 PeerConnectionIntegrationTest,
3531 PeerConnectionIntegrationTestWithFakeClock,
3532 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3533 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3534 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3535 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Yves Gerey100fe632020-01-17 19:15:53 +01003536
Steve Anton74255ff2018-01-24 18:32:57 -08003537// Tests that verify interoperability between Plan B and Unified Plan
3538// PeerConnections.
3539class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003540 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08003541 public ::testing::WithParamInterface<
3542 std::tuple<SdpSemantics, SdpSemantics>> {
3543 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003544 // Setting the SdpSemantics for the base test to kDefault does not matter
3545 // because we specify not to use the test semantics when creating
Harald Alvestrand39993842021-02-17 09:05:31 +00003546 // PeerConnectionIntegrationWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08003547 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07003548 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08003549 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08003550 callee_semantics_(std::get<1>(GetParam())) {}
3551
3552 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07003553 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
3554 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08003555 }
3556
3557 const SdpSemantics caller_semantics_;
3558 const SdpSemantics callee_semantics_;
3559};
3560
3561TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
3562 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3563 ConnectFakeSignaling();
3564
3565 caller()->CreateAndSetAndSignalOffer();
3566 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3567}
3568
3569TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
3570 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3571 ConnectFakeSignaling();
3572 auto audio_sender = caller()->AddAudioTrack();
3573
3574 caller()->CreateAndSetAndSignalOffer();
3575 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3576
3577 // Verify that one audio receiver has been created on the remote and that it
3578 // has the same track ID as the sending track.
3579 auto receivers = callee()->pc()->GetReceivers();
3580 ASSERT_EQ(1u, receivers.size());
3581 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
3582 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
3583
Seth Hampson2f0d7022018-02-20 11:54:42 -08003584 MediaExpectations media_expectations;
3585 media_expectations.CalleeExpectsSomeAudio();
3586 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003587}
3588
3589TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
3590 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3591 ConnectFakeSignaling();
3592 auto video_sender = caller()->AddVideoTrack();
3593 auto audio_sender = caller()->AddAudioTrack();
3594
3595 caller()->CreateAndSetAndSignalOffer();
3596 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3597
3598 // Verify that one audio and one video receiver have been created on the
3599 // remote and that they have the same track IDs as the sending tracks.
3600 auto audio_receivers =
3601 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
3602 ASSERT_EQ(1u, audio_receivers.size());
3603 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
3604 auto video_receivers =
3605 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
3606 ASSERT_EQ(1u, video_receivers.size());
3607 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
3608
Seth Hampson2f0d7022018-02-20 11:54:42 -08003609 MediaExpectations media_expectations;
3610 media_expectations.CalleeExpectsSomeAudioAndVideo();
3611 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003612}
3613
3614TEST_P(PeerConnectionIntegrationInteropTest,
3615 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
3616 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3617 ConnectFakeSignaling();
3618 caller()->AddAudioVideoTracks();
3619 callee()->AddAudioVideoTracks();
3620
3621 caller()->CreateAndSetAndSignalOffer();
3622 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3623
Seth Hampson2f0d7022018-02-20 11:54:42 -08003624 MediaExpectations media_expectations;
3625 media_expectations.ExpectBidirectionalAudioAndVideo();
3626 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003627}
3628
3629TEST_P(PeerConnectionIntegrationInteropTest,
3630 ReverseRolesOneAudioLocalToOneVideoRemote) {
3631 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3632 ConnectFakeSignaling();
3633 caller()->AddAudioTrack();
3634 callee()->AddVideoTrack();
3635
3636 caller()->CreateAndSetAndSignalOffer();
3637 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3638
3639 // Verify that only the audio track has been negotiated.
3640 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
3641 // Might also check that the callee's NegotiationNeeded flag is set.
3642
3643 // Reverse roles.
3644 callee()->CreateAndSetAndSignalOffer();
3645 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3646
Seth Hampson2f0d7022018-02-20 11:54:42 -08003647 MediaExpectations media_expectations;
3648 media_expectations.CallerExpectsSomeVideo();
3649 media_expectations.CalleeExpectsSomeAudio();
3650 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003651}
3652
Taylor Brandstetter1c7ecef2021-08-11 12:38:35 -07003653TEST_P(PeerConnectionIntegrationTest, NewTracksDoNotCauseNewCandidates) {
3654 ASSERT_TRUE(CreatePeerConnectionWrappers());
3655 ConnectFakeSignaling();
3656 caller()->AddAudioVideoTracks();
3657 caller()->CreateAndSetAndSignalOffer();
3658 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3659 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3660 caller()->ExpectCandidates(0);
3661 callee()->ExpectCandidates(0);
3662 caller()->AddAudioTrack();
3663 caller()->CreateAndSetAndSignalOffer();
3664 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3665}
3666
Mirko Bonadeic84f6612019-01-31 12:20:57 +01003667INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07003668 PeerConnectionIntegrationTest,
3669 PeerConnectionIntegrationInteropTest,
3670 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3671 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
3672
3673// Test that if the Unified Plan side offers two video tracks then the Plan B
3674// side will only see the first one and ignore the second.
3675TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07003676 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
3677 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08003678 ConnectFakeSignaling();
3679 auto first_sender = caller()->AddVideoTrack();
3680 caller()->AddVideoTrack();
3681
3682 caller()->CreateAndSetAndSignalOffer();
3683 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3684
3685 // Verify that there is only one receiver and it corresponds to the first
3686 // added track.
3687 auto receivers = callee()->pc()->GetReceivers();
3688 ASSERT_EQ(1u, receivers.size());
3689 EXPECT_TRUE(receivers[0]->track()->enabled());
3690 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
3691
Seth Hampson2f0d7022018-02-20 11:54:42 -08003692 MediaExpectations media_expectations;
3693 media_expectations.CalleeExpectsSomeVideo();
3694 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003695}
3696
Steve Anton2bed3972019-01-04 17:04:30 -08003697// Test that if the initial offer tagged BUNDLE section is rejected due to its
3698// associated RtpTransceiver being stopped and another transceiver is added,
3699// then renegotiation causes the callee to receive the new video track without
3700// error.
3701// This is a regression test for bugs.webrtc.org/9954
3702TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3703 ReOfferWithStoppedBundleTaggedTransceiver) {
3704 RTCConfiguration config;
3705 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3706 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3707 ConnectFakeSignaling();
3708 auto audio_transceiver_or_error =
3709 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3710 ASSERT_TRUE(audio_transceiver_or_error.ok());
3711 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3712
3713 caller()->CreateAndSetAndSignalOffer();
3714 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3715 {
3716 MediaExpectations media_expectations;
3717 media_expectations.CalleeExpectsSomeAudio();
3718 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3719 }
3720
Harald Alvestrand6060df52020-08-11 09:54:02 +02003721 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08003722 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3723
3724 caller()->CreateAndSetAndSignalOffer();
3725 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3726 {
3727 MediaExpectations media_expectations;
3728 media_expectations.CalleeExpectsSomeVideo();
3729 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3730 }
3731}
3732
Harald Alvestrandbedb6052020-08-20 14:50:10 +02003733TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3734 StopTransceiverRemovesDtlsTransports) {
3735 RTCConfiguration config;
3736 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3737 ConnectFakeSignaling();
3738 auto audio_transceiver_or_error =
3739 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3740 ASSERT_TRUE(audio_transceiver_or_error.ok());
3741 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3742
3743 caller()->CreateAndSetAndSignalOffer();
3744 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3745
3746 audio_transceiver->StopStandard();
3747 caller()->CreateAndSetAndSignalOffer();
3748 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3749 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
3750 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
3751 caller()->pc()->ice_gathering_state());
3752 EXPECT_THAT(caller()->ice_gathering_state_history(),
3753 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3754 PeerConnectionInterface::kIceGatheringComplete,
3755 PeerConnectionInterface::kIceGatheringNew));
3756}
3757
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003758TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00003759 StopTransceiverStopsAndRemovesTransceivers) {
3760 RTCConfiguration config;
3761 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3762 ConnectFakeSignaling();
3763 auto audio_transceiver_or_error =
3764 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3765 ASSERT_TRUE(audio_transceiver_or_error.ok());
3766 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
3767
3768 caller()->CreateAndSetAndSignalOffer();
3769 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3770 caller_transceiver->StopStandard();
3771
3772 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
3773 caller()->CreateAndSetAndSignalOffer();
3774 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3775 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
3776 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
3777 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
3778 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
3779 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
3780 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
3781 EXPECT_TRUE(caller_transceiver->stopped());
3782 EXPECT_TRUE(callee_transceiver->stopped());
3783}
3784
3785TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003786 StopTransceiverEndsIncomingAudioTrack) {
3787 RTCConfiguration config;
3788 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3789 ConnectFakeSignaling();
3790 auto audio_transceiver_or_error =
3791 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3792 ASSERT_TRUE(audio_transceiver_or_error.ok());
3793 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3794
3795 caller()->CreateAndSetAndSignalOffer();
3796 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3797 auto caller_track = audio_transceiver->receiver()->track();
3798 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3799 audio_transceiver->StopStandard();
3800 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3801 caller_track->state());
3802 caller()->CreateAndSetAndSignalOffer();
3803 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3804 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3805 callee_track->state());
3806}
3807
3808TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3809 StopTransceiverEndsIncomingVideoTrack) {
3810 RTCConfiguration config;
3811 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3812 ConnectFakeSignaling();
3813 auto audio_transceiver_or_error =
3814 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3815 ASSERT_TRUE(audio_transceiver_or_error.ok());
3816 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3817
3818 caller()->CreateAndSetAndSignalOffer();
3819 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3820 auto caller_track = audio_transceiver->receiver()->track();
3821 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3822 audio_transceiver->StopStandard();
3823 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3824 caller_track->state());
3825 caller()->CreateAndSetAndSignalOffer();
3826 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3827 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3828 callee_track->state());
3829}
3830
Harald Alvestrand89c40e22021-02-17 08:58:35 +00003831} // namespace
Harald Alvestrand39993842021-02-17 09:05:31 +00003832
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01003833} // namespace webrtc