Extend testing of prAnswer
- Modify munger to take (mutable)
std::unique_ptr<SessionDescriptionInterface> rather than
cricket::SessionDescription (that latter is embedded in the former)
- For all pranswer test cases, do a final SetRemoteDescription(kAnswer) and
check that signaling_state == stable
Add new test cases:
1) A test case that only applies it as prAnswer on caller (callee is stable)
2) A test case that "scramble" sdb between prAnswer and Anser.
Bug: None
Change-Id: Ifedd92ade01ae781a2e59d0569133c486c7093fe
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/360781
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Jonas Oreland <jonaso@webrtc.org>
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42891}
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index 429c4de..fd94772 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -2440,6 +2440,7 @@
"../rtc_base:network",
"../rtc_base:network_constants",
"../rtc_base:null_socket_server",
+ "../rtc_base:random",
"../rtc_base:refcount",
"../rtc_base:rtc_base_tests_utils",
"../rtc_base:rtc_certificate_generator",
diff --git a/pc/data_channel_integrationtest.cc b/pc/data_channel_integrationtest.cc
index 4489618..1a23a17 100644
--- a/pc/data_channel_integrationtest.cc
+++ b/pc/data_channel_integrationtest.cc
@@ -111,8 +111,8 @@
: PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
};
-void MakeActiveSctpOffer(cricket::SessionDescription* desc) {
- auto& transport_infos = desc->transport_infos();
+void MakeActiveSctpOffer(std::unique_ptr<SessionDescriptionInterface>& desc) {
+ auto& transport_infos = desc->description()->transport_infos();
for (auto& transport_info : transport_infos) {
transport_info.description.connection_role = cricket::CONNECTIONROLE_ACTIVE;
}
@@ -770,9 +770,10 @@
ASSERT_TRUE(ExpectNewFrames(media_expectations));
}
-static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
+static void MakeSpecCompliantSctpOffer(
+ std::unique_ptr<SessionDescriptionInterface>& desc) {
cricket::SctpDataContentDescription* dcd_offer =
- GetFirstSctpDataContentDescription(desc);
+ GetFirstSctpDataContentDescription(desc->description());
// See https://crbug.com/webrtc/11211 - this function is a no-op
ASSERT_TRUE(dcd_offer);
dcd_offer->set_use_sctpmap(false);
@@ -913,10 +914,11 @@
ConnectFakeSignaling();
caller()->CreateDataChannel();
- callee()->SetReceivedSdpMunger([this](cricket::SessionDescription* desc) {
- MakeActiveSctpOffer(desc);
- callee()->CreateDataChannel();
- });
+ callee()->SetReceivedSdpMunger(
+ [this](std::unique_ptr<SessionDescriptionInterface>& desc) {
+ MakeActiveSctpOffer(desc);
+ callee()->CreateDataChannel();
+ });
caller()->CreateAndSetAndSignalOffer();
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc
index 8362c8b..7bf6b6d 100644
--- a/pc/peer_connection_integrationtest.cc
+++ b/pc/peer_connection_integrationtest.cc
@@ -84,6 +84,7 @@
#include "rtc_base/firewall_socket_server.h"
#include "rtc_base/gunit.h"
#include "rtc_base/logging.h"
+#include "rtc_base/random.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/ssl_fingerprint.h"
@@ -605,9 +606,10 @@
caller()->AddAudioVideoTracks();
callee()->AddAudioVideoTracks();
// Remove the bundle group from the SDP received by the callee.
- callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
- desc->RemoveGroupByName("BUNDLE");
- });
+ callee()->SetReceivedSdpMunger(
+ [](std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ sdp->description()->RemoveGroupByName("BUNDLE");
+ });
caller()->CreateAndSetAndSignalOffer();
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
{
@@ -673,11 +675,12 @@
callee()->CreateLocalVideoTrackWithRotation(kVideoRotation_270));
// Remove the CVO extension from the offered SDP.
- callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
- cricket::VideoContentDescription* video =
- GetFirstVideoContentDescription(desc);
- video->ClearRtpHeaderExtensions();
- });
+ callee()->SetReceivedSdpMunger(
+ [](std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ cricket::VideoContentDescription* video =
+ GetFirstVideoContentDescription(sdp->description());
+ video->ClearRtpHeaderExtensions();
+ });
// Wait for video frames to be received by both sides.
caller()->CreateAndSetAndSignalOffer();
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
@@ -845,8 +848,8 @@
// Renegotiate, rejecting the video m= section.
if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
caller()->SetGeneratedSdpMunger(
- [](cricket::SessionDescription* description) {
- for (cricket::ContentInfo& content : description->contents()) {
+ [](std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ for (cricket::ContentInfo& content : sdp->description()->contents()) {
if (cricket::IsVideoContent(&content)) {
content.rejected = true;
}
@@ -1010,10 +1013,11 @@
}
// Used for the test below.
-void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
- RemoveSsrcsAndKeepMsids(desc);
- desc->RemoveGroupByName("BUNDLE");
- for (ContentInfo& content : desc->contents()) {
+void RemoveBundleGroupSsrcsAndMidExtension(
+ std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ RemoveSsrcsAndKeepMsids(sdp);
+ sdp->description()->RemoveGroupByName("BUNDLE");
+ for (ContentInfo& content : sdp->description()->contents()) {
cricket::MediaContentDescription* media = content.media_description();
cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
@@ -1058,9 +1062,9 @@
// Used for the test below.
void ModifyPayloadTypesAndRemoveMidExtension(
- cricket::SessionDescription* desc) {
+ std::unique_ptr<SessionDescriptionInterface>& sdp) {
int pt = 96;
- for (ContentInfo& content : desc->contents()) {
+ for (ContentInfo& content : sdp->description()->contents()) {
cricket::MediaContentDescription* media = content.media_description();
cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
@@ -1154,9 +1158,10 @@
ASSERT_TRUE(ExpectNewFrames(media_expectations));
}
-static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
+static void MakeSpecCompliantMaxBundleOffer(
+ std::unique_ptr<SessionDescriptionInterface>& sdp) {
bool first = true;
- for (cricket::ContentInfo& content : desc->contents()) {
+ for (cricket::ContentInfo& content : sdp->description()->contents()) {
if (first) {
first = false;
continue;
@@ -1164,7 +1169,8 @@
content.bundle_only = true;
}
first = true;
- for (cricket::TransportInfo& transport : desc->transport_infos()) {
+ for (cricket::TransportInfo& transport :
+ sdp->description()->transport_infos()) {
if (first) {
first = false;
continue;
@@ -2567,9 +2573,10 @@
// Remove all but one audio/video codec (opus and VP8), and change the
// casing of the caller's generated offer.
- caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
+ caller()->SetGeneratedSdpMunger([](std::unique_ptr<
+ SessionDescriptionInterface>& sdp) {
cricket::AudioContentDescription* audio =
- GetFirstAudioContentDescription(description);
+ GetFirstAudioContentDescription(sdp->description());
ASSERT_NE(nullptr, audio);
auto audio_codecs = audio->codecs();
audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
@@ -2582,7 +2589,7 @@
audio->set_codecs(audio_codecs);
cricket::VideoContentDescription* video =
- GetFirstVideoContentDescription(description);
+ GetFirstVideoContentDescription(sdp->description());
ASSERT_NE(nullptr, video);
auto video_codecs = video->codecs();
video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
@@ -3231,9 +3238,9 @@
ConnectFakeSignaling();
caller()->AddVideoTrack();
callee()->AddVideoTrack();
- auto munger = [](cricket::SessionDescription* desc) {
+ auto munger = [](std::unique_ptr<SessionDescriptionInterface>& sdp) {
cricket::VideoContentDescription* video =
- GetFirstVideoContentDescription(desc);
+ GetFirstVideoContentDescription(sdp->description());
auto codecs = video->codecs();
for (auto&& codec : codecs) {
if (codec.name == "H264") {
@@ -3254,17 +3261,18 @@
caller()->CreateAndSetAndSignalOffer();
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
// Observe that after munging the parameter is present in generated SDP.
- caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
- cricket::VideoContentDescription* video =
- GetFirstVideoContentDescription(desc);
- for (auto&& codec : video->codecs()) {
- if (codec.name == "H264") {
- std::string value;
- EXPECT_TRUE(
- codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
- }
- }
- });
+ caller()->SetGeneratedSdpMunger(
+ [](std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ cricket::VideoContentDescription* video =
+ GetFirstVideoContentDescription(sdp->description());
+ for (auto&& codec : video->codecs()) {
+ if (codec.name == "H264") {
+ std::string value;
+ EXPECT_TRUE(
+ codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
+ }
+ }
+ });
caller()->CreateOfferAndWait();
}
@@ -3785,24 +3793,25 @@
auto send_transceiver = audio_transceiver_or_error.MoveValue();
// Munge the SDP to include NACK and RRTR on Opus, and remove all other
// codecs.
- caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
- for (ContentInfo& content : desc->contents()) {
- cricket::MediaContentDescription* media = content.media_description();
- std::vector<cricket::Codec> codecs = media->codecs();
- std::vector<cricket::Codec> codecs_out;
- for (cricket::Codec codec : codecs) {
- if (codec.name == "opus") {
- codec.AddFeedbackParam(cricket::FeedbackParam(
- cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
- codec.AddFeedbackParam(cricket::FeedbackParam(
- cricket::kRtcpFbParamRrtr, cricket::kParamValueEmpty));
- codecs_out.push_back(codec);
+ caller()->SetGeneratedSdpMunger(
+ [](std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ for (ContentInfo& content : sdp->description()->contents()) {
+ cricket::MediaContentDescription* media = content.media_description();
+ std::vector<cricket::Codec> codecs = media->codecs();
+ std::vector<cricket::Codec> codecs_out;
+ for (cricket::Codec codec : codecs) {
+ if (codec.name == "opus") {
+ codec.AddFeedbackParam(cricket::FeedbackParam(
+ cricket::kRtcpFbParamNack, cricket::kParamValueEmpty));
+ codec.AddFeedbackParam(cricket::FeedbackParam(
+ cricket::kRtcpFbParamRrtr, cricket::kParamValueEmpty));
+ codecs_out.push_back(codec);
+ }
+ }
+ EXPECT_FALSE(codecs_out.empty());
+ media->set_codecs(codecs_out);
}
- }
- EXPECT_FALSE(codecs_out.empty());
- media->set_codecs(codecs_out);
- }
- });
+ });
caller()->CreateAndSetAndSignalOffer();
// Check for failure in helpers
@@ -3835,22 +3844,23 @@
auto send_transceiver = video_transceiver_or_error.MoveValue();
// Munge the SDP to include NACK and RRTR on VP8, and remove all other
// codecs.
- caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
- for (ContentInfo& content : desc->contents()) {
- cricket::MediaContentDescription* media = content.media_description();
- std::vector<cricket::Codec> codecs = media->codecs();
- std::vector<cricket::Codec> codecs_out;
- for (cricket::Codec codec : codecs) {
- if (codec.name == "VP8") {
- ASSERT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
- cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
- codecs_out.push_back(codec);
+ caller()->SetGeneratedSdpMunger(
+ [](std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ for (ContentInfo& content : sdp->description()->contents()) {
+ cricket::MediaContentDescription* media = content.media_description();
+ std::vector<cricket::Codec> codecs = media->codecs();
+ std::vector<cricket::Codec> codecs_out;
+ for (cricket::Codec codec : codecs) {
+ if (codec.name == "VP8") {
+ ASSERT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
+ cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
+ codecs_out.push_back(codec);
+ }
+ }
+ EXPECT_FALSE(codecs_out.empty());
+ media->set_codecs(codecs_out);
}
- }
- EXPECT_FALSE(codecs_out.empty());
- media->set_codecs(codecs_out);
- }
- });
+ });
caller()->CreateAndSetAndSignalOffer();
// Check for failure in helpers
@@ -3877,14 +3887,181 @@
ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
ConnectFakeSignaling();
caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
- callee()->SetAnswerWithPrAnswer(true);
+ caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
+
+ callee()->SetGeneratedSdpMunger(
+ [](std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ SetSdpType(sdp, SdpType::kPrAnswer);
+ });
+ std::unique_ptr<SessionDescriptionInterface> answer;
+ caller()->SetReceivedSdpMunger(
+ [&](std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ answer = sdp->Clone();
+ });
caller()->CreateAndSetAndSignalOffer();
ASSERT_FALSE(HasFailure());
EXPECT_EQ(caller()->pc()->signaling_state(),
PeerConnectionInterface::kHaveRemotePrAnswer);
EXPECT_EQ(callee()->pc()->signaling_state(),
PeerConnectionInterface::kHaveLocalPrAnswer);
- // Note: there should be code here for applying the permanent answer.
+
+ // // Apply the pranswer as a definitive one.
+ SetSdpType(answer, SdpType::kAnswer);
+ EXPECT_TRUE(caller()->SetRemoteDescription(std::move(answer)));
+ EXPECT_EQ(caller()->pc()->signaling_state(),
+ PeerConnectionInterface::kStable);
+}
+
+// Let caller get a prAnswer followed by answer.
+TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
+ PrAnswerStateTransitionsAsymmetric) {
+ RTCConfiguration config;
+ ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
+ ConnectFakeSignaling();
+ caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
+ caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
+
+ std::unique_ptr<SessionDescriptionInterface> answer;
+ caller()->SetReceivedSdpMunger(
+ [&](std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ answer = sdp->Clone();
+ SetSdpType(sdp, SdpType::kPrAnswer);
+ });
+ caller()->CreateAndSetAndSignalOffer();
+ ASSERT_FALSE(HasFailure());
+ EXPECT_EQ(caller()->pc()->signaling_state(),
+ PeerConnectionInterface::kHaveRemotePrAnswer);
+ EXPECT_EQ(callee()->pc()->signaling_state(),
+ PeerConnectionInterface::kStable);
+
+ // // Apply the pranswer as a definitive one.
+ EXPECT_TRUE(caller()->SetRemoteDescription(std::move(answer)));
+ EXPECT_EQ(caller()->pc()->signaling_state(),
+ PeerConnectionInterface::kStable);
+}
+
+int ReassignPayloadIds(std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ int swaps = 0;
+ for (ContentInfo& content : sdp->description()->contents()) {
+ if (!content.media_description()) {
+ continue;
+ }
+ std::vector<cricket::Codec> codecs = content.media_description()->codecs();
+ int left = 0;
+ int right = codecs.size() - 1;
+ while (left < right) {
+ if (!codecs[left].IsMediaCodec()) {
+ left++;
+ continue;
+ }
+ if (!codecs[right].IsMediaCodec()) {
+ right--;
+ continue;
+ }
+ auto tmp = codecs[left].id;
+ codecs[left].id = codecs[right].id;
+ codecs[right].id = tmp;
+ left++;
+ right--;
+ swaps++;
+ }
+ content.media_description()->set_codecs(codecs);
+ }
+ return swaps;
+}
+
+int SetNewSsrcs(std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ int assignments = 0;
+ std::unordered_set<uint32_t> already_used_ssrcs;
+ for (ContentInfo& content : sdp->description()->contents()) {
+ if (!content.media_description()) {
+ continue;
+ }
+ for (const auto& stream : content.media_description()->streams()) {
+ for (const auto& ssrc : stream.ssrcs) {
+ already_used_ssrcs.insert(ssrc);
+ }
+ }
+ }
+
+ Random random(/* random_seed= */ 77);
+ auto ssrc_generator = [&]() -> uint32_t {
+ do {
+ auto ssrc = random.Rand(1u, 0xFFFFFFF0u);
+ if (already_used_ssrcs.find(ssrc) == already_used_ssrcs.end()) {
+ already_used_ssrcs.insert(ssrc);
+ return ssrc;
+ }
+ } while (true);
+ };
+
+ for (ContentInfo& content : sdp->description()->contents()) {
+ if (!content.media_description()) {
+ continue;
+ }
+ for (auto& stream : content.media_description()->mutable_streams()) {
+ // Only reassign primary ssrc for now...
+ // but we should maybe also reassign ssrcs for ssrc groups?.
+ if (stream.ssrcs.size() == 1) {
+ assignments++;
+ stream.ssrcs[0] = ssrc_generator();
+ }
+ }
+ }
+ return assignments;
+}
+
+void SetNewFingerprint(std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ auto identity = rtc::SSLIdentity::Create("NewIdentity", rtc::KT_DEFAULT);
+ auto new_fingerprint =
+ rtc::SSLFingerprint::CreateUnique("sha-256", *identity.get());
+ for (auto& transport_info : sdp->description()->transport_infos()) {
+ transport_info.description.identity_fingerprint =
+ absl::WrapUnique(new rtc::SSLFingerprint(*new_fingerprint.get()));
+ }
+}
+
+TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
+ PrAnswerStateTransitionsAsymmetricScrambled) {
+ RTCConfiguration config;
+ ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
+ ConnectFakeSignaling();
+ webrtc::RtpEncodingParameters init_send_encodings;
+ init_send_encodings.active = false;
+ caller()->pc()->AddTrack(caller()->CreateLocalAudioTrack(), {"name"},
+ {init_send_encodings});
+ caller()->pc()->AddTrack(caller()->CreateLocalVideoTrack(), {"name"},
+ {init_send_encodings});
+ callee()->pc()->AddTrack(callee()->CreateLocalAudioTrack(), {"name"},
+ {init_send_encodings});
+ callee()->pc()->AddTrack(callee()->CreateLocalVideoTrack(), {"name"},
+ {init_send_encodings});
+
+ std::unique_ptr<SessionDescriptionInterface> answer;
+ caller()->SetReceivedSdpMunger(
+ [&](std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ answer = sdp->Clone();
+ SetSdpType(sdp, SdpType::kPrAnswer);
+ });
+ caller()->CreateAndSetAndSignalOffer();
+
+ ASSERT_FALSE(HasFailure());
+ ASSERT_EQ(caller()->pc()->signaling_state(),
+ PeerConnectionInterface::kHaveRemotePrAnswer);
+ ASSERT_EQ(callee()->pc()->signaling_state(),
+ PeerConnectionInterface::kStable);
+
+ // Now scramble the answer sdp so that it (really!) different from the first
+ // prAnswer.
+ // Note: this is maybe {possibly...probably?} a spec violation.
+ ASSERT_GT(SetNewSsrcs(answer), 0);
+ ASSERT_GT(ReassignPayloadIds(answer), 0);
+ SetNewFingerprint(answer);
+
+ // Apply the modified answer as a definitive one.
+ EXPECT_TRUE(caller()->SetRemoteDescription(std::move(answer)));
+ EXPECT_EQ(caller()->pc()->signaling_state(),
+ PeerConnectionInterface::kStable);
}
} // namespace
diff --git a/pc/test/integration_test_helpers.cc b/pc/test/integration_test_helpers.cc
index 7ffe4db..9a439f4 100644
--- a/pc/test/integration_test_helpers.cc
+++ b/pc/test/integration_test_helpers.cc
@@ -18,15 +18,16 @@
return options;
}
-void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) {
- for (ContentInfo& content : desc->contents()) {
+void RemoveSsrcsAndMsids(std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ for (ContentInfo& content : sdp->description()->contents()) {
content.media_description()->mutable_streams().clear();
}
- desc->set_msid_signaling(0);
+ sdp->description()->set_msid_signaling(0);
}
-void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) {
- for (ContentInfo& content : desc->contents()) {
+void RemoveSsrcsAndKeepMsids(
+ std::unique_ptr<SessionDescriptionInterface>& sdp) {
+ for (ContentInfo& content : sdp->description()->contents()) {
std::string track_id;
std::vector<std::string> stream_ids;
if (!content.media_description()->streams().empty()) {
@@ -43,6 +44,13 @@
}
}
+void SetSdpType(std::unique_ptr<SessionDescriptionInterface>& sdp,
+ SdpType sdpType) {
+ std::string str;
+ sdp->ToString(&str);
+ sdp = CreateSessionDescription(sdpType, str);
+}
+
int FindFirstMediaStatsIndexByKind(
const std::string& kind,
const std::vector<const RTCInboundRtpStreamStats*>& inbound_rtps) {
diff --git a/pc/test/integration_test_helpers.h b/pc/test/integration_test_helpers.h
index 458aa3a..5b9d632 100644
--- a/pc/test/integration_test_helpers.h
+++ b/pc/test/integration_test_helpers.h
@@ -165,11 +165,16 @@
// Remove all stream information (SSRCs, track IDs, etc.) and "msid-semantic"
// attribute from received SDP, simulating a legacy endpoint.
-void RemoveSsrcsAndMsids(cricket::SessionDescription* desc);
+void RemoveSsrcsAndMsids(std::unique_ptr<SessionDescriptionInterface>& desc);
// Removes all stream information besides the stream ids, simulating an
// endpoint that only signals a=msid lines to convey stream_ids.
-void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc);
+void RemoveSsrcsAndKeepMsids(
+ std::unique_ptr<SessionDescriptionInterface>& desc);
+
+// Set SdpType.
+void SetSdpType(std::unique_ptr<SessionDescriptionInterface>& sdp,
+ SdpType sdpType);
// Replaces the stream's primary SSRC and updates the first SSRC of all
// ssrc-groups.
@@ -265,14 +270,16 @@
// used to test SDP being applied that a PeerConnection would normally not
// generate, but a non-JSEP endpoint might.
void SetReceivedSdpMunger(
- std::function<void(cricket::SessionDescription*)> munger) {
+ std::function<void(std::unique_ptr<SessionDescriptionInterface>&)>
+ munger) {
received_sdp_munger_ = std::move(munger);
}
// Similar to the above, but this is run on SDP immediately after it's
// generated.
void SetGeneratedSdpMunger(
- std::function<void(cricket::SessionDescription*)> munger) {
+ std::function<void(std::unique_ptr<SessionDescriptionInterface>&)>
+ munger) {
generated_sdp_munger_ = std::move(munger);
}
@@ -658,9 +665,21 @@
candidates_expected_ = candidate_count;
}
- // For testing PR-Answer functionality
- // If true, an offer will get a pr-answer back.
- void SetAnswerWithPrAnswer(bool value) { answer_with_pr_answer_ = value; }
+ bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
+ auto observer = rtc::make_ref_counted<FakeSetRemoteDescriptionObserver>();
+ std::string str;
+ desc->ToString(&str);
+ RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription SDP:\n" << str;
+ pc()->SetRemoteDescription(std::move(desc), observer); // desc.release());
+ RemoveUnusedVideoRenderers();
+ EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
+ auto err = observer->error();
+ if (!err.ok()) {
+ RTC_LOG(LS_WARNING) << debug_name_
+ << ": SetRemoteDescription error: " << err.message();
+ }
+ return observer->error().ok();
+ }
private:
// Constructor used by friend class PeerConnectionIntegrationBaseTest.
@@ -736,7 +755,7 @@
std::unique_ptr<SessionDescriptionInterface> desc =
CreateSessionDescription(SdpType::kOffer, msg);
if (received_sdp_munger_) {
- received_sdp_munger_(desc->description());
+ received_sdp_munger_(desc);
}
EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
@@ -748,11 +767,6 @@
}
auto answer = CreateAnswer();
ASSERT_NE(nullptr, answer);
- if (answer_with_pr_answer_) {
- std::string answer_string;
- answer->ToString(&answer_string);
- answer = CreateSessionDescription(SdpType::kPrAnswer, answer_string);
- }
EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
}
@@ -762,7 +776,7 @@
std::unique_ptr<SessionDescriptionInterface> desc =
CreateSessionDescription(type, msg);
if (received_sdp_munger_) {
- received_sdp_munger_(desc->description());
+ received_sdp_munger_(desc);
}
EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
@@ -786,7 +800,7 @@
}
auto description = observer->MoveDescription();
if (generated_sdp_munger_) {
- generated_sdp_munger_(description->description());
+ generated_sdp_munger_(description);
}
return description;
}
@@ -813,15 +827,6 @@
return true;
}
- bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
- auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
- RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription";
- pc()->SetRemoteDescription(observer.get(), desc.release());
- RemoveUnusedVideoRenderers();
- EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
- return observer->result();
- }
-
// This is a work around to remove unused fake_video_renderers from
// transceivers that have either stopped or are no longer receiving.
void RemoveUnusedVideoRenderers() {
@@ -1059,8 +1064,10 @@
SdpSemantics sdp_semantics_;
PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_;
- std::function<void(cricket::SessionDescription*)> received_sdp_munger_;
- std::function<void(cricket::SessionDescription*)> generated_sdp_munger_;
+ std::function<void(std::unique_ptr<SessionDescriptionInterface>&)>
+ received_sdp_munger_;
+ std::function<void(std::unique_ptr<SessionDescriptionInterface>&)>
+ generated_sdp_munger_;
std::function<void()> remote_offer_handler_;
MockAsyncDnsResolver* remote_async_dns_resolver_ = nullptr;
// Result variables for the mock DNS resolver
@@ -1097,8 +1104,6 @@
uint64_t audio_concealed_stat_ = 0;
std::string rtp_stats_id_;
- bool answer_with_pr_answer_ = false;
-
ScopedTaskSafety task_safety_;
friend class PeerConnectionIntegrationBaseTest;