Index: webrtc/libjingle/session/session_unittest.cc |
diff --git a/webrtc/libjingle/session/session_unittest.cc b/webrtc/libjingle/session/session_unittest.cc |
deleted file mode 100644 |
index e1168db26edb4ae18f1bec127a7fe62d82a961b8..0000000000000000000000000000000000000000 |
--- a/webrtc/libjingle/session/session_unittest.cc |
+++ /dev/null |
@@ -1,2430 +0,0 @@ |
-/* |
- * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
- * |
- * Use of this source code is governed by a BSD-style license |
- * that can be found in the LICENSE file in the root of the source |
- * tree. An additional intellectual property rights grant can be found |
- * in the file PATENTS. All contributing project authors may |
- * be found in the AUTHORS file in the root of the source tree. |
- */ |
- |
-#include <string.h> |
- |
-#include <deque> |
-#include <map> |
-#include <sstream> |
- |
-#include "webrtc/base/base64.h" |
-#include "webrtc/base/common.h" |
-#include "webrtc/base/gunit.h" |
-#include "webrtc/base/helpers.h" |
-#include "webrtc/base/logging.h" |
-#include "webrtc/base/natserver.h" |
-#include "webrtc/base/natsocketfactory.h" |
-#include "webrtc/base/stringencode.h" |
-#include "webrtc/libjingle/session/parsing.h" |
-#include "webrtc/libjingle/session/sessionclient.h" |
-#include "webrtc/libjingle/session/sessionmanager.h" |
-#include "webrtc/libjingle/xmpp/constants.h" |
-#include "webrtc/p2p/base/basicpacketsocketfactory.h" |
-#include "webrtc/p2p/base/constants.h" |
-#include "webrtc/p2p/base/p2ptransport.h" |
-#include "webrtc/p2p/base/portallocator.h" |
-#include "webrtc/p2p/base/relayport.h" |
-#include "webrtc/p2p/base/relayserver.h" |
-#include "webrtc/p2p/base/stunport.h" |
-#include "webrtc/p2p/base/stunserver.h" |
-#include "webrtc/p2p/base/transportchannel.h" |
-#include "webrtc/p2p/base/transportchannelproxy.h" |
-#include "webrtc/p2p/base/udpport.h" |
- |
-using cricket::SignalingProtocol; |
-using cricket::PROTOCOL_HYBRID; |
-using cricket::PROTOCOL_JINGLE; |
-using cricket::PROTOCOL_GINGLE; |
- |
-static const std::string kInitiator = "init@init.com"; |
-static const std::string kResponder = "resp@resp.com"; |
-// Expected from test random number generator. |
-static const std::string kSessionId = "9254631414740579489"; |
-// TODO: When we need to test more than one transport type, |
-// allow this to be injected like the content types are. |
-static const std::string kTransportType = "http://www.google.com/transport/p2p"; |
- |
-// Controls how long we wait for a session to send messages that we |
-// expect, in milliseconds. We put it high to avoid flaky tests. |
-static const int kEventTimeout = 5000; |
- |
-static const int kNumPorts = 2; |
-static const int kPort0 = 28653; |
-static const int kPortStep = 5; |
- |
-int GetPort(int port_index) { |
- return kPort0 + (port_index * kPortStep); |
-} |
- |
-std::string GetPortString(int port_index) { |
- return rtc::ToString(GetPort(port_index)); |
-} |
- |
-// Only works for port_index < 10, which is fine for our purposes. |
-std::string GetUsername(int port_index) { |
- return "username" + std::string(8, rtc::ToString(port_index)[0]); |
-} |
- |
-// Only works for port_index < 10, which is fine for our purposes. |
-std::string GetPassword(int port_index) { |
- return "password" + std::string(8, rtc::ToString(port_index)[0]); |
-} |
- |
-std::string IqAck(const std::string& id, |
- const std::string& from, |
- const std::string& to) { |
- return "<cli:iq" |
- " to=\"" + to + "\"" |
- " id=\"" + id + "\"" |
- " type=\"result\"" |
- " from=\"" + from + "\"" |
- " xmlns:cli=\"jabber:client\"" |
- "/>"; |
-} |
- |
-std::string IqSet(const std::string& id, |
- const std::string& from, |
- const std::string& to, |
- const std::string& content) { |
- return "<cli:iq" |
- " to=\"" + to + "\"" |
- " type=\"set\"" |
- " from=\"" + from + "\"" |
- " id=\"" + id + "\"" |
- " xmlns:cli=\"jabber:client\"" |
- ">" |
- + content + |
- "</cli:iq>"; |
-} |
- |
-std::string IqError(const std::string& id, |
- const std::string& from, |
- const std::string& to, |
- const std::string& content) { |
- return "<cli:error" |
- " to=\"" + to + "\"" |
- " type=\"error\"" |
- " from=\"" + from + "\"" |
- " id=\"" + id + "\"" |
- " xmlns:cli=\"jabber:client\"" |
- ">" |
- + content + |
- "</cli:error>"; |
-} |
- |
-std::string GingleSessionXml(const std::string& type, |
- const std::string& content) { |
- return "<session" |
- " xmlns=\"http://www.google.com/session\"" |
- " type=\"" + type + "\"" |
- " id=\"" + kSessionId + "\"" |
- " initiator=\"" + kInitiator + "\"" |
- ">" |
- + content + |
- "</session>"; |
-} |
- |
-std::string GingleDescriptionXml(const std::string& content_type) { |
- return "<description" |
- " xmlns=\"" + content_type + "\"" |
- "/>"; |
-} |
- |
-std::string P2pCandidateXml(const std::string& name, int port_index) { |
- // Port will update the rtcp username by +1 on the last character. So we need |
- // to compensate here. See Port::username_fragment() for detail. |
- std::string username = GetUsername(port_index); |
- // TODO: Use the component id instead of the channel name to |
- // determinte if we need to covert the username here. |
- if (name == "rtcp" || name == "video_rtcp" || name == "chanb") { |
- char next_ch = username[username.size() - 1]; |
- ASSERT(username.size() > 0); |
- rtc::Base64::GetNextBase64Char(next_ch, &next_ch); |
- username[username.size() - 1] = next_ch; |
- } |
- return "<candidate" |
- " name=\"" + name + "\"" |
- " address=\"127.0.0.1\"" |
- " port=\"" + GetPortString(port_index) + "\"" |
- " preference=\"0.99\"" |
- " username=\"" + username + "\"" |
- " protocol=\"udp\"" |
- " generation=\"0\"" |
- " password=\"" + GetPassword(port_index) + "\"" |
- " type=\"local\"" |
- " network=\"network\"" |
- "/>"; |
-} |
- |
-std::string JingleActionXml(const std::string& action, |
- const std::string& content) { |
- return "<jingle" |
- " xmlns=\"urn:xmpp:jingle:1\"" |
- " action=\"" + action + "\"" |
- " sid=\"" + kSessionId + "\"" |
- ">" |
- + content + |
- "</jingle>"; |
-} |
- |
-std::string JingleInitiateActionXml(const std::string& content) { |
- return "<jingle" |
- " xmlns=\"urn:xmpp:jingle:1\"" |
- " action=\"session-initiate\"" |
- " sid=\"" + kSessionId + "\"" |
- " initiator=\"" + kInitiator + "\"" |
- ">" |
- + content + |
- "</jingle>"; |
-} |
- |
-std::string JingleGroupInfoXml(const std::string& content_name_a, |
- const std::string& content_name_b) { |
- std::string group_info = "<jin:group" |
- " type=\"BUNDLE\"" |
- " xmlns:jin=\"google:jingle\"" |
- ">"; |
- if (!content_name_a.empty()) |
- group_info += "<content name=\"" + content_name_a + "\"" |
- "/>"; |
- if (!content_name_b.empty()) |
- group_info += "<content name=\"" + content_name_b + "\"" |
- "/>"; |
- group_info += "</jin:group>"; |
- return group_info; |
-} |
- |
- |
-std::string JingleEmptyContentXml(const std::string& content_name, |
- const std::string& content_type, |
- const std::string& transport_type) { |
- return "<content" |
- " name=\"" + content_name + "\"" |
- " creator=\"initiator\"" |
- ">" |
- "<description" |
- " xmlns=\"" + content_type + "\"" |
- "/>" |
- "<transport" |
- " xmlns=\"" + transport_type + "\"" |
- "/>" |
- "</content>"; |
-} |
- |
-std::string JingleContentXml(const std::string& content_name, |
- const std::string& content_type, |
- const std::string& transport_type, |
- const std::string& transport_main) { |
- std::string transport = transport_type.empty() ? "" : |
- "<transport" |
- " xmlns=\"" + transport_type + "\"" |
- ">" |
- + transport_main + |
- "</transport>"; |
- |
- return"<content" |
- " name=\"" + content_name + "\"" |
- " creator=\"initiator\"" |
- ">" |
- "<description" |
- " xmlns=\"" + content_type + "\"" |
- "/>" |
- + transport + |
- "</content>"; |
-} |
- |
-std::string JingleTransportContentXml(const std::string& content_name, |
- const std::string& transport_type, |
- const std::string& content) { |
- return "<content" |
- " name=\"" + content_name + "\"" |
- " creator=\"initiator\"" |
- ">" |
- "<transport" |
- " xmlns=\"" + transport_type + "\"" |
- ">" |
- + content + |
- "</transport>" |
- "</content>"; |
-} |
- |
-std::string GingleInitiateXml(const std::string& content_type) { |
- return GingleSessionXml( |
- "initiate", |
- GingleDescriptionXml(content_type)); |
-} |
- |
-std::string JingleInitiateXml(const std::string& content_name_a, |
- const std::string& content_type_a, |
- const std::string& content_name_b, |
- const std::string& content_type_b, |
- bool bundle = false) { |
- std::string content_xml; |
- if (content_name_b.empty()) { |
- content_xml = JingleEmptyContentXml( |
- content_name_a, content_type_a, kTransportType); |
- } else { |
- content_xml = JingleEmptyContentXml( |
- content_name_a, content_type_a, kTransportType) + |
- JingleEmptyContentXml( |
- content_name_b, content_type_b, kTransportType); |
- if (bundle) { |
- content_xml += JingleGroupInfoXml(content_name_a, content_name_b); |
- } |
- } |
- return JingleInitiateActionXml(content_xml); |
-} |
- |
-std::string GingleAcceptXml(const std::string& content_type) { |
- return GingleSessionXml( |
- "accept", |
- GingleDescriptionXml(content_type)); |
-} |
- |
-std::string JingleAcceptXml(const std::string& content_name_a, |
- const std::string& content_type_a, |
- const std::string& content_name_b, |
- const std::string& content_type_b, |
- bool bundle = false) { |
- std::string content_xml; |
- if (content_name_b.empty()) { |
- content_xml = JingleEmptyContentXml( |
- content_name_a, content_type_a, kTransportType); |
- } else { |
- content_xml = JingleEmptyContentXml( |
- content_name_a, content_type_a, kTransportType) + |
- JingleEmptyContentXml( |
- content_name_b, content_type_b, kTransportType); |
- } |
- if (bundle) { |
- content_xml += JingleGroupInfoXml(content_name_a, content_name_b); |
- } |
- |
- return JingleActionXml("session-accept", content_xml); |
-} |
- |
-std::string Gingle2CandidatesXml(const std::string& channel_name, |
- int port_index0, |
- int port_index1) { |
- return GingleSessionXml( |
- "candidates", |
- P2pCandidateXml(channel_name, port_index0) + |
- P2pCandidateXml(channel_name, port_index1)); |
-} |
- |
-std::string Gingle4CandidatesXml(const std::string& channel_name_a, |
- int port_index0, |
- int port_index1, |
- const std::string& channel_name_b, |
- int port_index2, |
- int port_index3) { |
- return GingleSessionXml( |
- "candidates", |
- P2pCandidateXml(channel_name_a, port_index0) + |
- P2pCandidateXml(channel_name_a, port_index1) + |
- P2pCandidateXml(channel_name_b, port_index2) + |
- P2pCandidateXml(channel_name_b, port_index3)); |
-} |
- |
-std::string Jingle2TransportInfoXml(const std::string& content_name, |
- const std::string& channel_name, |
- int port_index0, |
- int port_index1) { |
- return JingleActionXml( |
- "transport-info", |
- JingleTransportContentXml( |
- content_name, kTransportType, |
- P2pCandidateXml(channel_name, port_index0) + |
- P2pCandidateXml(channel_name, port_index1))); |
-} |
- |
-std::string Jingle4TransportInfoXml(const std::string& content_name, |
- const std::string& channel_name_a, |
- int port_index0, |
- int port_index1, |
- const std::string& channel_name_b, |
- int port_index2, |
- int port_index3) { |
- return JingleActionXml( |
- "transport-info", |
- JingleTransportContentXml( |
- content_name, kTransportType, |
- P2pCandidateXml(channel_name_a, port_index0) + |
- P2pCandidateXml(channel_name_a, port_index1) + |
- P2pCandidateXml(channel_name_b, port_index2) + |
- P2pCandidateXml(channel_name_b, port_index3))); |
-} |
- |
-std::string JingleDescriptionInfoXml(const std::string& content_name, |
- const std::string& content_type) { |
- return JingleActionXml( |
- "description-info", |
- JingleContentXml(content_name, content_type, "", "")); |
-} |
- |
-std::string GingleRejectXml(const std::string& reason) { |
- return GingleSessionXml( |
- "reject", |
- "<" + reason + "/>"); |
-} |
- |
-std::string JingleTerminateXml(const std::string& reason) { |
- return JingleActionXml( |
- "session-terminate", |
- "<reason><" + reason + "/></reason>"); |
-} |
- |
-std::string GingleTerminateXml(const std::string& reason) { |
- return GingleSessionXml( |
- "terminate", |
- "<" + reason + "/>"); |
-} |
- |
-std::string GingleRedirectXml(const std::string& intitiate, |
- const std::string& target) { |
- return intitiate + |
- "<error code=\"302\" type=\"modify\">" |
- "<redirect xmlns=\"http://www.google.com/session\">" |
- "xmpp:" + target + |
- "</redirect>" |
- "</error>"; |
-} |
- |
-std::string JingleRedirectXml(const std::string& intitiate, |
- const std::string& target) { |
- return intitiate + |
- "<error code=\"302\" type=\"modify\">" |
- "<redirect xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\">" |
- "xmpp:" + target + |
- "</redirect>" |
- "</error>"; |
-} |
- |
-std::string InitiateXml(SignalingProtocol protocol, |
- const std::string& gingle_content_type, |
- const std::string& content_name_a, |
- const std::string& content_type_a, |
- const std::string& content_name_b, |
- const std::string& content_type_b, |
- bool bundle = false) { |
- switch (protocol) { |
- case PROTOCOL_JINGLE: |
- return JingleInitiateXml(content_name_a, content_type_a, |
- content_name_b, content_type_b, |
- bundle); |
- case PROTOCOL_GINGLE: |
- return GingleInitiateXml(gingle_content_type); |
- case PROTOCOL_HYBRID: |
- return JingleInitiateXml(content_name_a, content_type_a, |
- content_name_b, content_type_b) + |
- GingleInitiateXml(gingle_content_type); |
- } |
- return ""; |
-} |
- |
-std::string InitiateXml(SignalingProtocol protocol, |
- const std::string& content_name, |
- const std::string& content_type) { |
- return InitiateXml(protocol, |
- content_type, |
- content_name, content_type, |
- "", ""); |
-} |
- |
-std::string AcceptXml(SignalingProtocol protocol, |
- const std::string& gingle_content_type, |
- const std::string& content_name_a, |
- const std::string& content_type_a, |
- const std::string& content_name_b, |
- const std::string& content_type_b, |
- bool bundle = false) { |
- switch (protocol) { |
- case PROTOCOL_JINGLE: |
- return JingleAcceptXml(content_name_a, content_type_a, |
- content_name_b, content_type_b, bundle); |
- case PROTOCOL_GINGLE: |
- return GingleAcceptXml(gingle_content_type); |
- case PROTOCOL_HYBRID: |
- return |
- JingleAcceptXml(content_name_a, content_type_a, |
- content_name_b, content_type_b) + |
- GingleAcceptXml(gingle_content_type); |
- } |
- return ""; |
-} |
- |
- |
-std::string AcceptXml(SignalingProtocol protocol, |
- const std::string& content_name, |
- const std::string& content_type, |
- bool bundle = false) { |
- return AcceptXml(protocol, |
- content_type, |
- content_name, content_type, |
- "", ""); |
-} |
- |
-std::string TransportInfo2Xml(SignalingProtocol protocol, |
- const std::string& content_name, |
- const std::string& channel_name, |
- int port_index0, |
- int port_index1) { |
- switch (protocol) { |
- case PROTOCOL_JINGLE: |
- return Jingle2TransportInfoXml( |
- content_name, |
- channel_name, port_index0, port_index1); |
- case PROTOCOL_GINGLE: |
- return Gingle2CandidatesXml( |
- channel_name, port_index0, port_index1); |
- case PROTOCOL_HYBRID: |
- return |
- Jingle2TransportInfoXml( |
- content_name, |
- channel_name, port_index0, port_index1) + |
- Gingle2CandidatesXml( |
- channel_name, port_index0, port_index1); |
- } |
- return ""; |
-} |
- |
-std::string TransportInfo4Xml(SignalingProtocol protocol, |
- const std::string& content_name, |
- const std::string& channel_name_a, |
- int port_index0, |
- int port_index1, |
- const std::string& channel_name_b, |
- int port_index2, |
- int port_index3) { |
- switch (protocol) { |
- case PROTOCOL_JINGLE: |
- return Jingle4TransportInfoXml( |
- content_name, |
- channel_name_a, port_index0, port_index1, |
- channel_name_b, port_index2, port_index3); |
- case PROTOCOL_GINGLE: |
- return Gingle4CandidatesXml( |
- channel_name_a, port_index0, port_index1, |
- channel_name_b, port_index2, port_index3); |
- case PROTOCOL_HYBRID: |
- return |
- Jingle4TransportInfoXml( |
- content_name, |
- channel_name_a, port_index0, port_index1, |
- channel_name_b, port_index2, port_index3) + |
- Gingle4CandidatesXml( |
- channel_name_a, port_index0, port_index1, |
- channel_name_b, port_index2, port_index3); |
- } |
- return ""; |
-} |
- |
-std::string RejectXml(SignalingProtocol protocol, |
- const std::string& reason) { |
- switch (protocol) { |
- case PROTOCOL_JINGLE: |
- return JingleTerminateXml(reason); |
- case PROTOCOL_GINGLE: |
- return GingleRejectXml(reason); |
- case PROTOCOL_HYBRID: |
- return JingleTerminateXml(reason) + |
- GingleRejectXml(reason); |
- } |
- return ""; |
-} |
- |
-std::string TerminateXml(SignalingProtocol protocol, |
- const std::string& reason) { |
- switch (protocol) { |
- case PROTOCOL_JINGLE: |
- return JingleTerminateXml(reason); |
- case PROTOCOL_GINGLE: |
- return GingleTerminateXml(reason); |
- case PROTOCOL_HYBRID: |
- return JingleTerminateXml(reason) + |
- GingleTerminateXml(reason); |
- } |
- return ""; |
-} |
- |
-std::string RedirectXml(SignalingProtocol protocol, |
- const std::string& initiate, |
- const std::string& target) { |
- switch (protocol) { |
- case PROTOCOL_JINGLE: |
- return JingleRedirectXml(initiate, target); |
- case PROTOCOL_GINGLE: |
- return GingleRedirectXml(initiate, target); |
- default: |
- break; |
- } |
- return ""; |
-} |
- |
-// TODO: Break out and join with fakeportallocator.h |
-class TestPortAllocatorSession : public cricket::PortAllocatorSession { |
- public: |
- TestPortAllocatorSession(const std::string& content_name, |
- int component, |
- const std::string& ice_ufrag, |
- const std::string& ice_pwd, |
- const int port_offset) |
- : PortAllocatorSession(content_name, component, ice_ufrag, ice_pwd, 0), |
- port_offset_(port_offset), |
- ports_(kNumPorts), |
- address_("127.0.0.1", 0), |
- network_("network", "unittest", |
- rtc::IPAddress(INADDR_LOOPBACK), 8), |
- socket_factory_(rtc::Thread::Current()), |
- running_(false) { |
- network_.AddIP(address_.ipaddr()); |
- } |
- |
- ~TestPortAllocatorSession() { |
- for (size_t i = 0; i < ports_.size(); i++) |
- delete ports_[i]; |
- } |
- |
- virtual void StartGettingPorts() { |
- for (int i = 0; i < kNumPorts; i++) { |
- int index = port_offset_ + i; |
- ports_[i] = cricket::UDPPort::Create( |
- rtc::Thread::Current(), &socket_factory_, |
- &network_, address_.ipaddr(), GetPort(index), GetPort(index), |
- GetUsername(index), GetPassword(index), |
- std::string()); |
- AddPort(ports_[i]); |
- } |
- running_ = true; |
- } |
- |
- virtual void StopGettingPorts() { running_ = false; } |
- virtual bool IsGettingPorts() { return running_; } |
- |
- void AddPort(cricket::Port* port) { |
- port->set_component(component_); |
- port->set_generation(0); |
- port->SignalDestroyed.connect( |
- this, &TestPortAllocatorSession::OnPortDestroyed); |
- port->SignalPortComplete.connect( |
- this, &TestPortAllocatorSession::OnPortComplete); |
- port->PrepareAddress(); |
- SignalPortReady(this, port); |
- } |
- |
- void OnPortDestroyed(cricket::PortInterface* port) { |
- for (size_t i = 0; i < ports_.size(); i++) { |
- if (ports_[i] == port) |
- ports_[i] = NULL; |
- } |
- } |
- |
- void OnPortComplete(cricket::Port* port) { |
- SignalCandidatesReady(this, port->Candidates()); |
- } |
- |
- private: |
- int port_offset_; |
- std::vector<cricket::Port*> ports_; |
- rtc::SocketAddress address_; |
- rtc::Network network_; |
- rtc::BasicPacketSocketFactory socket_factory_; |
- bool running_; |
-}; |
- |
-class TestPortAllocator : public cricket::PortAllocator { |
- public: |
- TestPortAllocator() : port_offset_(0) {} |
- |
- virtual cricket::PortAllocatorSession* |
- CreateSessionInternal( |
- const std::string& content_name, |
- int component, |
- const std::string& ice_ufrag, |
- const std::string& ice_pwd) { |
- port_offset_ += 2; |
- return new TestPortAllocatorSession(content_name, component, |
- ice_ufrag, ice_pwd, port_offset_ - 2); |
- } |
- |
- int port_offset_; |
-}; |
- |
-class TestContentDescription : public cricket::ContentDescription { |
- public: |
- explicit TestContentDescription(const std::string& gingle_content_type, |
- const std::string& content_type) |
- : gingle_content_type(gingle_content_type), |
- content_type(content_type) { |
- } |
- virtual ContentDescription* Copy() const { |
- return new TestContentDescription(*this); |
- } |
- |
- std::string gingle_content_type; |
- std::string content_type; |
-}; |
- |
-cricket::SessionDescription* NewTestSessionDescription( |
- const std::string gingle_content_type, |
- const std::string& content_name_a, const std::string& content_type_a, |
- const std::string& content_name_b, const std::string& content_type_b) { |
- |
- cricket::SessionDescription* offer = new cricket::SessionDescription(); |
- offer->AddContent(content_name_a, content_type_a, |
- new TestContentDescription(gingle_content_type, |
- content_type_a)); |
- cricket::TransportDescription desc(cricket::NS_GINGLE_P2P, |
- std::string(), std::string()); |
- offer->AddTransportInfo(cricket::TransportInfo(content_name_a, desc)); |
- |
- if (content_name_a != content_name_b) { |
- offer->AddContent(content_name_b, content_type_b, |
- new TestContentDescription(gingle_content_type, |
- content_type_b)); |
- offer->AddTransportInfo(cricket::TransportInfo(content_name_b, desc)); |
- } |
- return offer; |
-} |
- |
-cricket::SessionDescription* NewTestSessionDescription( |
- const std::string& content_name, const std::string& content_type) { |
- |
- cricket::SessionDescription* offer = new cricket::SessionDescription(); |
- offer->AddContent(content_name, content_type, |
- new TestContentDescription(content_type, |
- content_type)); |
- offer->AddTransportInfo(cricket::TransportInfo |
- (content_name, cricket::TransportDescription( |
- cricket::NS_GINGLE_P2P, |
- std::string(), std::string()))); |
- return offer; |
-} |
- |
-struct TestSessionClient: public cricket::SessionClient, |
- public sigslot::has_slots<> { |
- public: |
- TestSessionClient() { |
- } |
- |
- ~TestSessionClient() { |
- } |
- |
- virtual bool ParseContent(SignalingProtocol protocol, |
- const buzz::XmlElement* elem, |
- cricket::ContentDescription** content, |
- cricket::ParseError* error) { |
- std::string content_type; |
- std::string gingle_content_type; |
- if (protocol == PROTOCOL_GINGLE) { |
- gingle_content_type = elem->Name().Namespace(); |
- } else { |
- content_type = elem->Name().Namespace(); |
- } |
- |
- *content = new TestContentDescription(gingle_content_type, content_type); |
- return true; |
- } |
- |
- virtual bool WriteContent(SignalingProtocol protocol, |
- const cricket::ContentDescription* untyped_content, |
- buzz::XmlElement** elem, |
- cricket::WriteError* error) { |
- const TestContentDescription* content = |
- static_cast<const TestContentDescription*>(untyped_content); |
- std::string content_type = (protocol == PROTOCOL_GINGLE ? |
- content->gingle_content_type : |
- content->content_type); |
- *elem = new buzz::XmlElement( |
- buzz::QName(content_type, "description"), true); |
- return true; |
- } |
- |
- void OnSessionCreate(cricket::Session* session, bool initiate) { |
- } |
- |
- void OnSessionDestroy(cricket::Session* session) { |
- } |
-}; |
- |
-struct ChannelHandler : sigslot::has_slots<> { |
- explicit ChannelHandler(cricket::TransportChannel* p, const std::string& name) |
- : channel(p), last_readable(false), last_writable(false), data_count(0), |
- last_size(0), name(name) { |
- p->SignalReadableState.connect(this, &ChannelHandler::OnReadableState); |
- p->SignalWritableState.connect(this, &ChannelHandler::OnWritableState); |
- p->SignalReadPacket.connect(this, &ChannelHandler::OnReadPacket); |
- } |
- |
- bool writable() const { |
- return last_writable && channel->writable(); |
- } |
- |
- bool readable() const { |
- return last_readable && channel->readable(); |
- } |
- |
- void OnReadableState(cricket::TransportChannel* p) { |
- EXPECT_EQ(channel, p); |
- last_readable = channel->readable(); |
- } |
- |
- void OnWritableState(cricket::TransportChannel* p) { |
- EXPECT_EQ(channel, p); |
- last_writable = channel->writable(); |
- } |
- |
- void OnReadPacket(cricket::TransportChannel* p, const char* buf, |
- size_t size, const rtc::PacketTime& time, int flags) { |
- if (memcmp(buf, name.c_str(), name.size()) != 0) |
- return; // drop packet if packet doesn't belong to this channel. This |
- // can happen when transport channels are muxed together. |
- buf += name.size(); // Remove channel name from the message. |
- size -= name.size(); // Decrement size by channel name string size. |
- EXPECT_EQ(channel, p); |
- EXPECT_LE(size, sizeof(last_data)); |
- data_count += 1; |
- last_size = size; |
- memcpy(last_data, buf, size); |
- } |
- |
- void Send(const char* data, size_t size) { |
- rtc::PacketOptions options; |
- std::string data_with_id(name); |
- data_with_id += data; |
- int result = channel->SendPacket(data_with_id.c_str(), data_with_id.size(), |
- options, 0); |
- EXPECT_EQ(static_cast<int>(data_with_id.size()), result); |
- } |
- |
- cricket::TransportChannel* channel; |
- bool last_readable, last_writable; |
- int data_count; |
- char last_data[4096]; |
- size_t last_size; |
- std::string name; |
-}; |
- |
-void PrintStanza(const std::string& message, |
- const buzz::XmlElement* stanza) { |
- printf("%s: %s\n", message.c_str(), stanza->Str().c_str()); |
-} |
- |
-class TestClient : public sigslot::has_slots<> { |
- public: |
- // TODO: Add channel_component_a/b as inputs to the ctor. |
- TestClient(cricket::PortAllocator* port_allocator, |
- int* next_message_id, |
- const std::string& local_name, |
- SignalingProtocol start_protocol, |
- const std::string& content_type, |
- const std::string& content_name_a, |
- const std::string& channel_name_a, |
- const std::string& content_name_b, |
- const std::string& channel_name_b) { |
- Construct(port_allocator, next_message_id, local_name, start_protocol, |
- content_type, content_name_a, channel_name_a, |
- content_name_b, channel_name_b); |
- } |
- |
- ~TestClient() { |
- if (session) { |
- session_manager->DestroySession(session); |
- EXPECT_EQ(1U, session_destroyed_count); |
- } |
- delete session_manager; |
- delete client; |
- for (std::deque<buzz::XmlElement*>::iterator it = sent_stanzas.begin(); |
- it != sent_stanzas.end(); ++it) { |
- delete *it; |
- } |
- } |
- |
- void Construct(cricket::PortAllocator* pa, |
- int* message_id, |
- const std::string& lname, |
- SignalingProtocol protocol, |
- const std::string& cont_type, |
- const std::string& cont_name_a, |
- const std::string& chan_name_a, |
- const std::string& cont_name_b, |
- const std::string& chan_name_b) { |
- port_allocator_ = pa; |
- next_message_id = message_id; |
- local_name = lname; |
- start_protocol = protocol; |
- content_type = cont_type; |
- content_name_a = cont_name_a; |
- channel_name_a = chan_name_a; |
- content_name_b = cont_name_b; |
- channel_name_b = chan_name_b; |
- session_created_count = 0; |
- session_destroyed_count = 0; |
- session_remote_description_update_count = 0; |
- new_local_description = false; |
- new_remote_description = false; |
- last_content_action = cricket::CA_OFFER; |
- last_content_source = cricket::CS_LOCAL; |
- session = NULL; |
- last_session_state = cricket::BaseSession::STATE_INIT; |
- blow_up_on_error = true; |
- error_count = 0; |
- |
- session_manager = new cricket::SessionManager(port_allocator_); |
- session_manager->SignalSessionCreate.connect( |
- this, &TestClient::OnSessionCreate); |
- session_manager->SignalSessionDestroy.connect( |
- this, &TestClient::OnSessionDestroy); |
- session_manager->SignalOutgoingMessage.connect( |
- this, &TestClient::OnOutgoingMessage); |
- |
- client = new TestSessionClient(); |
- session_manager->AddClient(content_type, client); |
- EXPECT_EQ(client, session_manager->GetClient(content_type)); |
- } |
- |
- uint32 sent_stanza_count() const { |
- return static_cast<uint32>(sent_stanzas.size()); |
- } |
- |
- const buzz::XmlElement* stanza() const { |
- return last_expected_sent_stanza.get(); |
- } |
- |
- cricket::BaseSession::State session_state() const { |
- EXPECT_EQ(last_session_state, session->state()); |
- return session->state(); |
- } |
- |
- void SetSessionState(cricket::BaseSession::State state) { |
- session->SetState(state); |
- EXPECT_EQ_WAIT(last_session_state, session->state(), kEventTimeout); |
- } |
- |
- void CreateSession() { |
- session_manager->CreateSession(local_name, content_type); |
- } |
- |
- void DeliverStanza(const buzz::XmlElement* stanza) { |
- session_manager->OnIncomingMessage(stanza); |
- } |
- |
- void DeliverStanza(const std::string& str) { |
- buzz::XmlElement* stanza = buzz::XmlElement::ForStr(str); |
- session_manager->OnIncomingMessage(stanza); |
- delete stanza; |
- } |
- |
- void DeliverAckToLastStanza() { |
- const buzz::XmlElement* orig_stanza = stanza(); |
- const buzz::XmlElement* response_stanza = |
- buzz::XmlElement::ForStr(IqAck(orig_stanza->Attr(buzz::QN_IQ), "", "")); |
- session_manager->OnIncomingResponse(orig_stanza, response_stanza); |
- delete response_stanza; |
- } |
- |
- void ExpectSentStanza(const std::string& expected) { |
- EXPECT_TRUE(!sent_stanzas.empty()) << |
- "Found no stanza when expected " << expected; |
- |
- last_expected_sent_stanza.reset(sent_stanzas.front()); |
- sent_stanzas.pop_front(); |
- |
- std::string actual = last_expected_sent_stanza->Str(); |
- EXPECT_EQ(expected, actual); |
- } |
- |
- void SkipUnsentStanza() { |
- GetNextOutgoingMessageID(); |
- } |
- |
- bool HasTransport(const std::string& content_name) const { |
- ASSERT(session != NULL); |
- const cricket::Transport* transport = session->GetTransport(content_name); |
- return transport != NULL && (kTransportType == transport->type()); |
- } |
- |
- bool HasChannel(const std::string& content_name, |
- int component) const { |
- ASSERT(session != NULL); |
- const cricket::TransportChannel* channel = |
- session->GetChannel(content_name, component); |
- return channel != NULL && (component == channel->component()); |
- } |
- |
- cricket::TransportChannel* GetChannel(const std::string& content_name, |
- int component) const { |
- ASSERT(session != NULL); |
- return session->GetChannel(content_name, component); |
- } |
- |
- void OnSessionCreate(cricket::Session* created_session, bool initiate) { |
- session_created_count += 1; |
- |
- session = created_session; |
- session->set_current_protocol(start_protocol); |
- session->SignalState.connect(this, &TestClient::OnSessionState); |
- session->SignalError.connect(this, &TestClient::OnSessionError); |
- session->SignalRemoteDescriptionUpdate.connect( |
- this, &TestClient::OnSessionRemoteDescriptionUpdate); |
- session->SignalNewLocalDescription.connect( |
- this, &TestClient::OnNewLocalDescription); |
- session->SignalNewRemoteDescription.connect( |
- this, &TestClient::OnNewRemoteDescription); |
- |
- CreateChannels(); |
- } |
- |
- void OnSessionDestroy(cricket::Session *session) { |
- session_destroyed_count += 1; |
- } |
- |
- void OnSessionState(cricket::BaseSession* session, |
- cricket::BaseSession::State state) { |
- // EXPECT_EQ does not allow use of this, hence the tmp variable. |
- cricket::BaseSession* tmp = this->session; |
- EXPECT_EQ(tmp, session); |
- last_session_state = state; |
- } |
- |
- void OnSessionError(cricket::BaseSession* session, |
- cricket::BaseSession::Error error) { |
- // EXPECT_EQ does not allow use of this, hence the tmp variable. |
- cricket::BaseSession* tmp = this->session; |
- EXPECT_EQ(tmp, session); |
- if (blow_up_on_error) { |
- EXPECT_TRUE(false); |
- } else { |
- error_count++; |
- } |
- } |
- |
- void OnSessionRemoteDescriptionUpdate(cricket::BaseSession* session, |
- const cricket::ContentInfos& contents) { |
- session_remote_description_update_count++; |
- } |
- |
- void OnNewLocalDescription(cricket::BaseSession* session, |
- cricket::ContentAction action) { |
- new_local_description = true; |
- last_content_action = action; |
- last_content_source = cricket::CS_LOCAL; |
- } |
- |
- void OnNewRemoteDescription(cricket::BaseSession* session, |
- cricket::ContentAction action) { |
- new_remote_description = true; |
- last_content_action = action; |
- last_content_source = cricket::CS_REMOTE; |
- } |
- |
- void PrepareCandidates() { |
- session_manager->OnSignalingReady(); |
- } |
- |
- void OnOutgoingMessage(cricket::SessionManager* manager, |
- const buzz::XmlElement* stanza) { |
- buzz::XmlElement* elem = new buzz::XmlElement(*stanza); |
- EXPECT_TRUE(elem->Name() == buzz::QN_IQ); |
- EXPECT_TRUE(elem->HasAttr(buzz::QN_TO)); |
- EXPECT_FALSE(elem->HasAttr(buzz::QN_FROM)); |
- EXPECT_TRUE(elem->HasAttr(buzz::QN_TYPE)); |
- EXPECT_TRUE((elem->Attr(buzz::QN_TYPE) == "set") || |
- (elem->Attr(buzz::QN_TYPE) == "result") || |
- (elem->Attr(buzz::QN_TYPE) == "error")); |
- |
- elem->SetAttr(buzz::QN_FROM, local_name); |
- if (elem->Attr(buzz::QN_TYPE) == "set") { |
- EXPECT_FALSE(elem->HasAttr(buzz::QN_ID)); |
- elem->SetAttr(buzz::QN_ID, GetNextOutgoingMessageID()); |
- } |
- |
- // Uncommenting this is useful for debugging. |
- // PrintStanza("OutgoingMessage", elem); |
- sent_stanzas.push_back(elem); |
- } |
- |
- std::string GetNextOutgoingMessageID() { |
- int message_id = (*next_message_id)++; |
- std::ostringstream ost; |
- ost << message_id; |
- return ost.str(); |
- } |
- |
- void CreateChannels() { |
- ASSERT(session != NULL); |
- // We either have a single content with multiple components (RTP/RTCP), or |
- // multiple contents with single components, but not both. |
- int component_a = 1; |
- int component_b = (content_name_a == content_name_b) ? 2 : 1; |
- chan_a.reset(new ChannelHandler( |
- session->CreateChannel(content_name_a, channel_name_a, component_a), |
- channel_name_a)); |
- chan_b.reset(new ChannelHandler( |
- session->CreateChannel(content_name_b, channel_name_b, component_b), |
- channel_name_b)); |
- } |
- |
- int* next_message_id; |
- std::string local_name; |
- SignalingProtocol start_protocol; |
- std::string content_type; |
- std::string content_name_a; |
- std::string channel_name_a; |
- std::string content_name_b; |
- std::string channel_name_b; |
- |
- uint32 session_created_count; |
- uint32 session_destroyed_count; |
- uint32 session_remote_description_update_count; |
- bool new_local_description; |
- bool new_remote_description; |
- cricket::ContentAction last_content_action; |
- cricket::ContentSource last_content_source; |
- std::deque<buzz::XmlElement*> sent_stanzas; |
- rtc::scoped_ptr<buzz::XmlElement> last_expected_sent_stanza; |
- |
- cricket::SessionManager* session_manager; |
- TestSessionClient* client; |
- cricket::PortAllocator* port_allocator_; |
- cricket::Session* session; |
- cricket::BaseSession::State last_session_state; |
- rtc::scoped_ptr<ChannelHandler> chan_a; |
- rtc::scoped_ptr<ChannelHandler> chan_b; |
- bool blow_up_on_error; |
- int error_count; |
-}; |
- |
-class SessionTest : public testing::Test { |
- protected: |
- virtual void SetUp() { |
- // Seed needed for each test to satisfy expectations. |
- rtc::SetRandomTestMode(true); |
- } |
- |
- virtual void TearDown() { |
- rtc::SetRandomTestMode(false); |
- } |
- |
- // Tests sending data between two clients, over two channels. |
- void TestSendRecv(ChannelHandler* chan1a, |
- ChannelHandler* chan1b, |
- ChannelHandler* chan2a, |
- ChannelHandler* chan2b) { |
- const char* dat1a = "spamspamspamspamspamspamspambakedbeansspam"; |
- const char* dat2a = "mapssnaebdekabmapsmapsmapsmapsmapsmapsmaps"; |
- const char* dat1b = "Lobster Thermidor a Crevette with a mornay sauce..."; |
- const char* dat2b = "...ecuas yanrom a htiw etteverC a rodimrehT retsboL"; |
- |
- for (int i = 0; i < 20; i++) { |
- chan1a->Send(dat1a, strlen(dat1a)); |
- chan1b->Send(dat1b, strlen(dat1b)); |
- chan2a->Send(dat2a, strlen(dat2a)); |
- chan2b->Send(dat2b, strlen(dat2b)); |
- |
- EXPECT_EQ_WAIT(i + 1, chan1a->data_count, kEventTimeout); |
- EXPECT_EQ_WAIT(i + 1, chan1b->data_count, kEventTimeout); |
- EXPECT_EQ_WAIT(i + 1, chan2a->data_count, kEventTimeout); |
- EXPECT_EQ_WAIT(i + 1, chan2b->data_count, kEventTimeout); |
- |
- EXPECT_EQ(strlen(dat2a), chan1a->last_size); |
- EXPECT_EQ(strlen(dat2b), chan1b->last_size); |
- EXPECT_EQ(strlen(dat1a), chan2a->last_size); |
- EXPECT_EQ(strlen(dat1b), chan2b->last_size); |
- |
- EXPECT_EQ(0, memcmp(chan1a->last_data, dat2a, strlen(dat2a))); |
- EXPECT_EQ(0, memcmp(chan1b->last_data, dat2b, strlen(dat2b))); |
- EXPECT_EQ(0, memcmp(chan2a->last_data, dat1a, strlen(dat1a))); |
- EXPECT_EQ(0, memcmp(chan2b->last_data, dat1b, strlen(dat1b))); |
- } |
- } |
- |
- // Test an initiate from one client to another, each with |
- // independent initial protocols. Checks for the correct initiates, |
- // candidates, and accept messages, and tests that working network |
- // channels are established. |
- void TestSession(SignalingProtocol initiator_protocol, |
- SignalingProtocol responder_protocol, |
- SignalingProtocol resulting_protocol, |
- const std::string& gingle_content_type, |
- const std::string& content_type, |
- const std::string& content_name_a, |
- const std::string& channel_name_a, |
- const std::string& content_name_b, |
- const std::string& channel_name_b, |
- const std::string& initiate_xml, |
- const std::string& transport_info_a_xml, |
- const std::string& transport_info_b_xml, |
- const std::string& transport_info_reply_a_xml, |
- const std::string& transport_info_reply_b_xml, |
- const std::string& accept_xml, |
- bool bundle = false) { |
- rtc::scoped_ptr<cricket::PortAllocator> allocator( |
- new TestPortAllocator()); |
- int next_message_id = 0; |
- |
- rtc::scoped_ptr<TestClient> initiator( |
- new TestClient(allocator.get(), &next_message_id, |
- kInitiator, initiator_protocol, |
- content_type, |
- content_name_a, channel_name_a, |
- content_name_b, channel_name_b)); |
- rtc::scoped_ptr<TestClient> responder( |
- new TestClient(allocator.get(), &next_message_id, |
- kResponder, responder_protocol, |
- content_type, |
- content_name_a, channel_name_a, |
- content_name_b, channel_name_b)); |
- |
- // Create Session and check channels and state. |
- initiator->CreateSession(); |
- EXPECT_EQ(1U, initiator->session_created_count); |
- EXPECT_EQ(kSessionId, initiator->session->id()); |
- EXPECT_EQ(initiator->session->local_name(), kInitiator); |
- EXPECT_EQ(cricket::BaseSession::STATE_INIT, |
- initiator->session_state()); |
- |
- // See comment in CreateChannels about how we choose component IDs. |
- int component_a = 1; |
- int component_b = (content_name_a == content_name_b) ? 2 : 1; |
- EXPECT_TRUE(initiator->HasTransport(content_name_a)); |
- EXPECT_TRUE(initiator->HasChannel(content_name_a, component_a)); |
- EXPECT_TRUE(initiator->HasTransport(content_name_b)); |
- EXPECT_TRUE(initiator->HasChannel(content_name_b, component_b)); |
- |
- // Initiate and expect initiate message sent. |
- cricket::SessionDescription* offer = NewTestSessionDescription( |
- gingle_content_type, |
- content_name_a, content_type, |
- content_name_b, content_type); |
- if (bundle) { |
- cricket::ContentGroup group(cricket::GROUP_TYPE_BUNDLE); |
- group.AddContentName(content_name_a); |
- group.AddContentName(content_name_b); |
- EXPECT_TRUE(group.HasContentName(content_name_a)); |
- EXPECT_TRUE(group.HasContentName(content_name_b)); |
- offer->AddGroup(group); |
- } |
- EXPECT_TRUE(initiator->session->Initiate(kResponder, offer)); |
- EXPECT_EQ(initiator->session->remote_name(), kResponder); |
- EXPECT_EQ(initiator->session->local_description(), offer); |
- |
- EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout); |
- EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE, |
- initiator->session_state()); |
- |
- initiator->ExpectSentStanza( |
- IqSet("0", kInitiator, kResponder, initiate_xml)); |
- |
- // Deliver the initiate. Expect ack and session created with |
- // transports. |
- responder->DeliverStanza(initiator->stanza()); |
- responder->ExpectSentStanza( |
- IqAck("0", kResponder, kInitiator)); |
- EXPECT_EQ(0U, responder->sent_stanza_count()); |
- |
- EXPECT_EQ(1U, responder->session_created_count); |
- EXPECT_EQ(kSessionId, responder->session->id()); |
- EXPECT_EQ(responder->session->local_name(), kResponder); |
- EXPECT_EQ(responder->session->remote_name(), kInitiator); |
- EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE, |
- responder->session_state()); |
- |
- EXPECT_TRUE(responder->HasTransport(content_name_a)); |
- EXPECT_TRUE(responder->HasChannel(content_name_a, component_a)); |
- EXPECT_TRUE(responder->HasTransport(content_name_b)); |
- EXPECT_TRUE(responder->HasChannel(content_name_b, component_b)); |
- |
- // Expect transport-info message from initiator. |
- // But don't send candidates until initiate ack is received. |
- initiator->PrepareCandidates(); |
- WAIT(initiator->sent_stanza_count() > 0, 100); |
- EXPECT_EQ(0U, initiator->sent_stanza_count()); |
- initiator->DeliverAckToLastStanza(); |
- EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout); |
- initiator->ExpectSentStanza( |
- IqSet("1", kInitiator, kResponder, transport_info_a_xml)); |
- |
- // Deliver transport-info and expect ack. |
- responder->DeliverStanza(initiator->stanza()); |
- responder->ExpectSentStanza( |
- IqAck("1", kResponder, kInitiator)); |
- |
- if (!transport_info_b_xml.empty()) { |
- // Expect second transport-info message from initiator. |
- EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout); |
- initiator->ExpectSentStanza( |
- IqSet("2", kInitiator, kResponder, transport_info_b_xml)); |
- EXPECT_EQ(0U, initiator->sent_stanza_count()); |
- |
- // Deliver second transport-info message and expect ack. |
- responder->DeliverStanza(initiator->stanza()); |
- responder->ExpectSentStanza( |
- IqAck("2", kResponder, kInitiator)); |
- } else { |
- EXPECT_EQ(0U, initiator->sent_stanza_count()); |
- EXPECT_EQ(0U, responder->sent_stanza_count()); |
- initiator->SkipUnsentStanza(); |
- } |
- |
- // Expect reply transport-info message from responder. |
- responder->PrepareCandidates(); |
- EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout); |
- responder->ExpectSentStanza( |
- IqSet("3", kResponder, kInitiator, transport_info_reply_a_xml)); |
- |
- // Deliver reply transport-info and expect ack. |
- initiator->DeliverStanza(responder->stanza()); |
- initiator->ExpectSentStanza( |
- IqAck("3", kInitiator, kResponder)); |
- |
- if (!transport_info_reply_b_xml.empty()) { |
- // Expect second reply transport-info message from responder. |
- EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout); |
- responder->ExpectSentStanza( |
- IqSet("4", kResponder, kInitiator, transport_info_reply_b_xml)); |
- EXPECT_EQ(0U, responder->sent_stanza_count()); |
- |
- // Deliver second reply transport-info message and expect ack. |
- initiator->DeliverStanza(responder->stanza()); |
- initiator->ExpectSentStanza( |
- IqAck("4", kInitiator, kResponder)); |
- EXPECT_EQ(0U, initiator->sent_stanza_count()); |
- } else { |
- EXPECT_EQ(0U, initiator->sent_stanza_count()); |
- EXPECT_EQ(0U, responder->sent_stanza_count()); |
- responder->SkipUnsentStanza(); |
- } |
- |
- // The channels should be able to become writable at this point. This |
- // requires pinging, so it may take a little while. |
- EXPECT_TRUE_WAIT(initiator->chan_a->writable() && |
- initiator->chan_a->readable(), kEventTimeout); |
- EXPECT_TRUE_WAIT(initiator->chan_b->writable() && |
- initiator->chan_b->readable(), kEventTimeout); |
- EXPECT_TRUE_WAIT(responder->chan_a->writable() && |
- responder->chan_a->readable(), kEventTimeout); |
- EXPECT_TRUE_WAIT(responder->chan_b->writable() && |
- responder->chan_b->readable(), kEventTimeout); |
- |
- // Accept the session and expect accept stanza. |
- cricket::SessionDescription* answer = NewTestSessionDescription( |
- gingle_content_type, |
- content_name_a, content_type, |
- content_name_b, content_type); |
- if (bundle) { |
- cricket::ContentGroup group(cricket::GROUP_TYPE_BUNDLE); |
- group.AddContentName(content_name_a); |
- group.AddContentName(content_name_b); |
- EXPECT_TRUE(group.HasContentName(content_name_a)); |
- EXPECT_TRUE(group.HasContentName(content_name_b)); |
- answer->AddGroup(group); |
- } |
- EXPECT_TRUE(responder->session->Accept(answer)); |
- EXPECT_EQ(responder->session->local_description(), answer); |
- |
- responder->ExpectSentStanza( |
- IqSet("5", kResponder, kInitiator, accept_xml)); |
- |
- EXPECT_EQ(0U, responder->sent_stanza_count()); |
- |
- // Deliver the accept message and expect an ack. |
- initiator->DeliverStanza(responder->stanza()); |
- EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout); |
- initiator->ExpectSentStanza( |
- IqAck("5", kInitiator, kResponder)); |
- EXPECT_EQ(0U, initiator->sent_stanza_count()); |
- |
- // Both sessions should be in progress and have functioning |
- // channels. |
- EXPECT_EQ(resulting_protocol, initiator->session->current_protocol()); |
- EXPECT_EQ(resulting_protocol, responder->session->current_protocol()); |
- EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS, |
- initiator->session_state(), kEventTimeout); |
- EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS, |
- responder->session_state(), kEventTimeout); |
- if (bundle) { |
- cricket::TransportChannel* initiator_chan_a = initiator->chan_a->channel; |
- cricket::TransportChannel* initiator_chan_b = initiator->chan_b->channel; |
- |
- // Since we know these are TransportChannelProxy, type cast it. |
- cricket::TransportChannelProxy* initiator_proxy_chan_a = |
- static_cast<cricket::TransportChannelProxy*>(initiator_chan_a); |
- cricket::TransportChannelProxy* initiator_proxy_chan_b = |
- static_cast<cricket::TransportChannelProxy*>(initiator_chan_b); |
- EXPECT_TRUE(initiator_proxy_chan_a->impl() != NULL); |
- EXPECT_TRUE(initiator_proxy_chan_b->impl() != NULL); |
- EXPECT_EQ(initiator_proxy_chan_a->impl(), initiator_proxy_chan_b->impl()); |
- |
- cricket::TransportChannel* responder_chan_a = responder->chan_a->channel; |
- cricket::TransportChannel* responder_chan_b = responder->chan_b->channel; |
- |
- // Since we know these are TransportChannelProxy, type cast it. |
- cricket::TransportChannelProxy* responder_proxy_chan_a = |
- static_cast<cricket::TransportChannelProxy*>(responder_chan_a); |
- cricket::TransportChannelProxy* responder_proxy_chan_b = |
- static_cast<cricket::TransportChannelProxy*>(responder_chan_b); |
- EXPECT_TRUE(responder_proxy_chan_a->impl() != NULL); |
- EXPECT_TRUE(responder_proxy_chan_b->impl() != NULL); |
- EXPECT_EQ(responder_proxy_chan_a->impl(), responder_proxy_chan_b->impl()); |
- } |
- TestSendRecv(initiator->chan_a.get(), initiator->chan_b.get(), |
- responder->chan_a.get(), responder->chan_b.get()); |
- |
- if (resulting_protocol == PROTOCOL_JINGLE) { |
- // Deliver a description-info message to the initiator and check if the |
- // content description changes. |
- EXPECT_EQ(0U, initiator->session_remote_description_update_count); |
- |
- const cricket::SessionDescription* old_session_desc = |
- initiator->session->remote_description(); |
- const cricket::ContentInfo* old_content_a = |
- old_session_desc->GetContentByName(content_name_a); |
- const cricket::ContentDescription* old_content_desc_a = |
- old_content_a->description; |
- const cricket::ContentInfo* old_content_b = |
- old_session_desc->GetContentByName(content_name_b); |
- const cricket::ContentDescription* old_content_desc_b = |
- old_content_b->description; |
- EXPECT_TRUE(old_content_desc_a != NULL); |
- EXPECT_TRUE(old_content_desc_b != NULL); |
- |
- LOG(LS_INFO) << "A " << old_content_a->name; |
- LOG(LS_INFO) << "B " << old_content_b->name; |
- |
- std::string description_info_xml = |
- JingleDescriptionInfoXml(content_name_a, content_type); |
- initiator->DeliverStanza( |
- IqSet("6", kResponder, kInitiator, description_info_xml)); |
- responder->SkipUnsentStanza(); |
- EXPECT_EQ(1U, initiator->session_remote_description_update_count); |
- |
- const cricket::SessionDescription* new_session_desc = |
- initiator->session->remote_description(); |
- const cricket::ContentInfo* new_content_a = |
- new_session_desc->GetContentByName(content_name_a); |
- const cricket::ContentDescription* new_content_desc_a = |
- new_content_a->description; |
- const cricket::ContentInfo* new_content_b = |
- new_session_desc->GetContentByName(content_name_b); |
- const cricket::ContentDescription* new_content_desc_b = |
- new_content_b->description; |
- EXPECT_TRUE(new_content_desc_a != NULL); |
- EXPECT_TRUE(new_content_desc_b != NULL); |
- |
- // TODO: We used to replace contents from an update, but |
- // that no longer works with partial updates. We need to figure out |
- // a way to merge patial updates into contents. For now, users of |
- // Session should listen to SignalRemoteDescriptionUpdate and handle |
- // updates. They should not expect remote_description to be the |
- // latest value. |
- // See session.cc OnDescriptionInfoMessage. |
- |
- // EXPECT_NE(old_content_desc_a, new_content_desc_a); |
- |
- // if (content_name_a != content_name_b) { |
- // // If content_name_a != content_name_b, then b's content description |
- // // should not have changed since the description-info message only |
- // // contained an update for content_name_a. |
- // EXPECT_EQ(old_content_desc_b, new_content_desc_b); |
- // } |
- |
- EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout); |
- initiator->ExpectSentStanza( |
- IqAck("6", kInitiator, kResponder)); |
- EXPECT_EQ(0U, initiator->sent_stanza_count()); |
- } else { |
- responder->SkipUnsentStanza(); |
- } |
- |
- initiator->session->Terminate(); |
- initiator->ExpectSentStanza( |
- IqSet("7", kInitiator, kResponder, |
- TerminateXml(resulting_protocol, |
- cricket::STR_TERMINATE_SUCCESS))); |
- |
- responder->DeliverStanza(initiator->stanza()); |
- responder->ExpectSentStanza( |
- IqAck("7", kResponder, kInitiator)); |
- EXPECT_EQ(cricket::BaseSession::STATE_SENTTERMINATE, |
- initiator->session_state()); |
- EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDTERMINATE, |
- responder->session_state()); |
- } |
- |
- // Test an initiate with other content, called "main". |
- void TestOtherContent(SignalingProtocol initiator_protocol, |
- SignalingProtocol responder_protocol, |
- SignalingProtocol resulting_protocol) { |
- std::string content_name = "main"; |
- std::string content_type = "http://oink.splat/session"; |
- std::string content_name_a = content_name; |
- std::string channel_name_a = "rtp"; |
- std::string content_name_b = content_name; |
- std::string channel_name_b = "rtcp"; |
- std::string initiate_xml = InitiateXml( |
- initiator_protocol, |
- content_name_a, content_type); |
- std::string transport_info_a_xml = TransportInfo4Xml( |
- initiator_protocol, content_name, |
- channel_name_a, 0, 1, |
- channel_name_b, 2, 3); |
- std::string transport_info_b_xml = ""; |
- std::string transport_info_reply_a_xml = TransportInfo4Xml( |
- resulting_protocol, content_name, |
- channel_name_a, 4, 5, |
- channel_name_b, 6, 7); |
- std::string transport_info_reply_b_xml = ""; |
- std::string accept_xml = AcceptXml( |
- resulting_protocol, |
- content_name_a, content_type); |
- |
- |
- TestSession(initiator_protocol, responder_protocol, resulting_protocol, |
- content_type, |
- content_type, |
- content_name_a, channel_name_a, |
- content_name_b, channel_name_b, |
- initiate_xml, |
- transport_info_a_xml, transport_info_b_xml, |
- transport_info_reply_a_xml, transport_info_reply_b_xml, |
- accept_xml); |
- } |
- |
- // Test an initiate with audio content. |
- void TestAudioContent(SignalingProtocol initiator_protocol, |
- SignalingProtocol responder_protocol, |
- SignalingProtocol resulting_protocol) { |
- std::string gingle_content_type = cricket::NS_GINGLE_AUDIO; |
- std::string content_name = cricket::CN_AUDIO; |
- std::string content_type = cricket::NS_JINGLE_RTP; |
- std::string channel_name_a = "rtp"; |
- std::string channel_name_b = "rtcp"; |
- std::string initiate_xml = InitiateXml( |
- initiator_protocol, |
- gingle_content_type, |
- content_name, content_type, |
- "", ""); |
- std::string transport_info_a_xml = TransportInfo4Xml( |
- initiator_protocol, content_name, |
- channel_name_a, 0, 1, |
- channel_name_b, 2, 3); |
- std::string transport_info_b_xml = ""; |
- std::string transport_info_reply_a_xml = TransportInfo4Xml( |
- resulting_protocol, content_name, |
- channel_name_a, 4, 5, |
- channel_name_b, 6, 7); |
- std::string transport_info_reply_b_xml = ""; |
- std::string accept_xml = AcceptXml( |
- resulting_protocol, |
- gingle_content_type, |
- content_name, content_type, |
- "", ""); |
- |
- |
- TestSession(initiator_protocol, responder_protocol, resulting_protocol, |
- gingle_content_type, |
- content_type, |
- content_name, channel_name_a, |
- content_name, channel_name_b, |
- initiate_xml, |
- transport_info_a_xml, transport_info_b_xml, |
- transport_info_reply_a_xml, transport_info_reply_b_xml, |
- accept_xml); |
- } |
- |
- // Since media content is "split" into two contents (audio and |
- // video), we need to treat it special. |
- void TestVideoContents(SignalingProtocol initiator_protocol, |
- SignalingProtocol responder_protocol, |
- SignalingProtocol resulting_protocol) { |
- std::string content_type = cricket::NS_JINGLE_RTP; |
- std::string gingle_content_type = cricket::NS_GINGLE_VIDEO; |
- std::string content_name_a = cricket::CN_AUDIO; |
- std::string channel_name_a = "rtp"; |
- std::string content_name_b = cricket::CN_VIDEO; |
- std::string channel_name_b = "video_rtp"; |
- |
- std::string initiate_xml = InitiateXml( |
- initiator_protocol, |
- gingle_content_type, |
- content_name_a, content_type, |
- content_name_b, content_type); |
- std::string transport_info_a_xml = TransportInfo2Xml( |
- initiator_protocol, content_name_a, |
- channel_name_a, 0, 1); |
- std::string transport_info_b_xml = TransportInfo2Xml( |
- initiator_protocol, content_name_b, |
- channel_name_b, 2, 3); |
- std::string transport_info_reply_a_xml = TransportInfo2Xml( |
- resulting_protocol, content_name_a, |
- channel_name_a, 4, 5); |
- std::string transport_info_reply_b_xml = TransportInfo2Xml( |
- resulting_protocol, content_name_b, |
- channel_name_b, 6, 7); |
- std::string accept_xml = AcceptXml( |
- resulting_protocol, |
- gingle_content_type, |
- content_name_a, content_type, |
- content_name_b, content_type); |
- |
- TestSession(initiator_protocol, responder_protocol, resulting_protocol, |
- gingle_content_type, |
- content_type, |
- content_name_a, channel_name_a, |
- content_name_b, channel_name_b, |
- initiate_xml, |
- transport_info_a_xml, transport_info_b_xml, |
- transport_info_reply_a_xml, transport_info_reply_b_xml, |
- accept_xml); |
- } |
- |
- void TestBadRedirect(SignalingProtocol protocol) { |
- std::string content_name = "main"; |
- std::string content_type = "http://oink.splat/session"; |
- std::string channel_name_a = "chana"; |
- std::string channel_name_b = "chanb"; |
- std::string initiate_xml = InitiateXml( |
- protocol, content_name, content_type); |
- std::string transport_info_xml = TransportInfo4Xml( |
- protocol, content_name, |
- channel_name_a, 0, 1, |
- channel_name_b, 2, 3); |
- std::string transport_info_reply_xml = TransportInfo4Xml( |
- protocol, content_name, |
- channel_name_a, 4, 5, |
- channel_name_b, 6, 7); |
- std::string accept_xml = AcceptXml( |
- protocol, content_name, content_type); |
- std::string responder_full = kResponder + "/full"; |
- |
- rtc::scoped_ptr<cricket::PortAllocator> allocator( |
- new TestPortAllocator()); |
- int next_message_id = 0; |
- |
- rtc::scoped_ptr<TestClient> initiator( |
- new TestClient(allocator.get(), &next_message_id, |
- kInitiator, protocol, |
- content_type, |
- content_name, channel_name_a, |
- content_name, channel_name_b)); |
- |
- rtc::scoped_ptr<TestClient> responder( |
- new TestClient(allocator.get(), &next_message_id, |
- responder_full, protocol, |
- content_type, |
- content_name, channel_name_a, |
- content_name, channel_name_b)); |
- |
- // Create Session and check channels and state. |
- initiator->CreateSession(); |
- EXPECT_EQ(1U, initiator->session_created_count); |
- EXPECT_EQ(kSessionId, initiator->session->id()); |
- EXPECT_EQ(initiator->session->local_name(), kInitiator); |
- EXPECT_EQ(cricket::BaseSession::STATE_INIT, |
- initiator->session_state()); |
- |
- EXPECT_TRUE(initiator->HasChannel(content_name, 1)); |
- EXPECT_TRUE(initiator->HasChannel(content_name, 2)); |
- |
- // Initiate and expect initiate message sent. |
- cricket::SessionDescription* offer = NewTestSessionDescription( |
- content_name, content_type); |
- EXPECT_TRUE(initiator->session->Initiate(kResponder, offer)); |
- EXPECT_EQ(initiator->session->remote_name(), kResponder); |
- EXPECT_EQ(initiator->session->local_description(), offer); |
- |
- EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout); |
- EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE, |
- initiator->session_state()); |
- initiator->ExpectSentStanza( |
- IqSet("0", kInitiator, kResponder, initiate_xml)); |
- |
- // Expect transport-info message from initiator. |
- initiator->DeliverAckToLastStanza(); |
- initiator->PrepareCandidates(); |
- EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout); |
- initiator->ExpectSentStanza( |
- IqSet("1", kInitiator, kResponder, transport_info_xml)); |
- |
- // Send an unauthorized redirect to the initiator and expect it be ignored. |
- initiator->blow_up_on_error = false; |
- const buzz::XmlElement* initiate_stanza = initiator->stanza(); |
- rtc::scoped_ptr<buzz::XmlElement> redirect_stanza( |
- buzz::XmlElement::ForStr( |
- IqError("ER", kResponder, kInitiator, |
- RedirectXml(protocol, initiate_xml, "not@allowed.com")))); |
- initiator->session_manager->OnFailedSend( |
- initiate_stanza, redirect_stanza.get()); |
- EXPECT_EQ(initiator->session->remote_name(), kResponder); |
- initiator->blow_up_on_error = true; |
- EXPECT_EQ(initiator->error_count, 1); |
- } |
- |
- void TestGoodRedirect(SignalingProtocol protocol) { |
- std::string content_name = "main"; |
- std::string content_type = "http://oink.splat/session"; |
- std::string channel_name_a = "chana"; |
- std::string channel_name_b = "chanb"; |
- std::string initiate_xml = InitiateXml( |
- protocol, content_name, content_type); |
- std::string transport_info_xml = TransportInfo4Xml( |
- protocol, content_name, |
- channel_name_a, 0, 1, |
- channel_name_b, 2, 3); |
- std::string transport_info_reply_xml = TransportInfo4Xml( |
- protocol, content_name, |
- channel_name_a, 4, 5, |
- channel_name_b, 6, 7); |
- std::string accept_xml = AcceptXml( |
- protocol, content_name, content_type); |
- std::string responder_full = kResponder + "/full"; |
- |
- rtc::scoped_ptr<cricket::PortAllocator> allocator( |
- new TestPortAllocator()); |
- int next_message_id = 0; |
- |
- rtc::scoped_ptr<TestClient> initiator( |
- new TestClient(allocator.get(), &next_message_id, |
- kInitiator, protocol, |
- content_type, |
- content_name, channel_name_a, |
- content_name, channel_name_b)); |
- |
- rtc::scoped_ptr<TestClient> responder( |
- new TestClient(allocator.get(), &next_message_id, |
- responder_full, protocol, |
- content_type, |
- content_name, channel_name_a, |
- content_name, channel_name_b)); |
- |
- // Create Session and check channels and state. |
- initiator->CreateSession(); |
- EXPECT_EQ(1U, initiator->session_created_count); |
- EXPECT_EQ(kSessionId, initiator->session->id()); |
- EXPECT_EQ(initiator->session->local_name(), kInitiator); |
- EXPECT_EQ(cricket::BaseSession::STATE_INIT, |
- initiator->session_state()); |
- |
- EXPECT_TRUE(initiator->HasChannel(content_name, 1)); |
- EXPECT_TRUE(initiator->HasChannel(content_name, 2)); |
- |
- // Initiate and expect initiate message sent. |
- cricket::SessionDescription* offer = NewTestSessionDescription( |
- content_name, content_type); |
- EXPECT_TRUE(initiator->session->Initiate(kResponder, offer)); |
- EXPECT_EQ(initiator->session->remote_name(), kResponder); |
- EXPECT_EQ(initiator->session->local_description(), offer); |
- |
- EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout); |
- EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE, |
- initiator->session_state()); |
- initiator->ExpectSentStanza( |
- IqSet("0", kInitiator, kResponder, initiate_xml)); |
- |
- // Expect transport-info message from initiator. |
- initiator->DeliverAckToLastStanza(); |
- initiator->PrepareCandidates(); |
- EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout); |
- initiator->ExpectSentStanza( |
- IqSet("1", kInitiator, kResponder, transport_info_xml)); |
- |
- // Send a redirect to the initiator and expect all of the message |
- // to be resent. |
- const buzz::XmlElement* initiate_stanza = initiator->stanza(); |
- rtc::scoped_ptr<buzz::XmlElement> redirect_stanza( |
- buzz::XmlElement::ForStr( |
- IqError("ER2", kResponder, kInitiator, |
- RedirectXml(protocol, initiate_xml, responder_full)))); |
- initiator->session_manager->OnFailedSend( |
- initiate_stanza, redirect_stanza.get()); |
- EXPECT_EQ(initiator->session->remote_name(), responder_full); |
- |
- EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout); |
- initiator->ExpectSentStanza( |
- IqSet("2", kInitiator, responder_full, initiate_xml)); |
- initiator->ExpectSentStanza( |
- IqSet("3", kInitiator, responder_full, transport_info_xml)); |
- |
- // Deliver the initiate. Expect ack and session created with |
- // transports. |
- responder->DeliverStanza( |
- IqSet("2", kInitiator, responder_full, initiate_xml)); |
- responder->ExpectSentStanza( |
- IqAck("2", responder_full, kInitiator)); |
- EXPECT_EQ(0U, responder->sent_stanza_count()); |
- |
- EXPECT_EQ(1U, responder->session_created_count); |
- EXPECT_EQ(kSessionId, responder->session->id()); |
- EXPECT_EQ(responder->session->local_name(), responder_full); |
- EXPECT_EQ(responder->session->remote_name(), kInitiator); |
- EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE, |
- responder->session_state()); |
- |
- EXPECT_TRUE(responder->HasChannel(content_name, 1)); |
- EXPECT_TRUE(responder->HasChannel(content_name, 2)); |
- |
- // Deliver transport-info and expect ack. |
- responder->DeliverStanza( |
- IqSet("3", kInitiator, responder_full, transport_info_xml)); |
- responder->ExpectSentStanza( |
- IqAck("3", responder_full, kInitiator)); |
- |
- // Expect reply transport-infos sent to new remote JID |
- responder->PrepareCandidates(); |
- EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout); |
- responder->ExpectSentStanza( |
- IqSet("4", responder_full, kInitiator, transport_info_reply_xml)); |
- |
- initiator->DeliverStanza(responder->stanza()); |
- initiator->ExpectSentStanza( |
- IqAck("4", kInitiator, responder_full)); |
- |
- // The channels should be able to become writable at this point. This |
- // requires pinging, so it may take a little while. |
- EXPECT_TRUE_WAIT(initiator->chan_a->writable() && |
- initiator->chan_a->readable(), kEventTimeout); |
- EXPECT_TRUE_WAIT(initiator->chan_b->writable() && |
- initiator->chan_b->readable(), kEventTimeout); |
- EXPECT_TRUE_WAIT(responder->chan_a->writable() && |
- responder->chan_a->readable(), kEventTimeout); |
- EXPECT_TRUE_WAIT(responder->chan_b->writable() && |
- responder->chan_b->readable(), kEventTimeout); |
- |
- // Accept the session and expect accept stanza. |
- cricket::SessionDescription* answer = NewTestSessionDescription( |
- content_name, content_type); |
- EXPECT_TRUE(responder->session->Accept(answer)); |
- EXPECT_EQ(responder->session->local_description(), answer); |
- |
- responder->ExpectSentStanza( |
- IqSet("5", responder_full, kInitiator, accept_xml)); |
- EXPECT_EQ(0U, responder->sent_stanza_count()); |
- |
- // Deliver the accept message and expect an ack. |
- initiator->DeliverStanza(responder->stanza()); |
- EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout); |
- initiator->ExpectSentStanza( |
- IqAck("5", kInitiator, responder_full)); |
- EXPECT_EQ(0U, initiator->sent_stanza_count()); |
- |
- // Both sessions should be in progress and have functioning |
- // channels. |
- EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS, |
- initiator->session_state(), kEventTimeout); |
- EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS, |
- responder->session_state(), kEventTimeout); |
- TestSendRecv(initiator->chan_a.get(), initiator->chan_b.get(), |
- responder->chan_a.get(), responder->chan_b.get()); |
- } |
- |
- void TestCandidatesInInitiateAndAccept(const std::string& test_name) { |
- std::string content_name = "main"; |
- std::string content_type = "http://oink.splat/session"; |
- std::string channel_name_a = "rtp"; |
- std::string channel_name_b = "rtcp"; |
- cricket::SignalingProtocol protocol = PROTOCOL_JINGLE; |
- |
- rtc::scoped_ptr<cricket::PortAllocator> allocator( |
- new TestPortAllocator()); |
- int next_message_id = 0; |
- |
- rtc::scoped_ptr<TestClient> initiator( |
- new TestClient(allocator.get(), &next_message_id, |
- kInitiator, protocol, |
- content_type, |
- content_name, channel_name_a, |
- content_name, channel_name_b)); |
- |
- rtc::scoped_ptr<TestClient> responder( |
- new TestClient(allocator.get(), &next_message_id, |
- kResponder, protocol, |
- content_type, |
- content_name, channel_name_a, |
- content_name, channel_name_b)); |
- |
- // Create Session and check channels and state. |
- initiator->CreateSession(); |
- EXPECT_TRUE(initiator->HasTransport(content_name)); |
- EXPECT_TRUE(initiator->HasChannel(content_name, 1)); |
- EXPECT_TRUE(initiator->HasTransport(content_name)); |
- EXPECT_TRUE(initiator->HasChannel(content_name, 2)); |
- |
- // Initiate and expect initiate message sent. |
- cricket::SessionDescription* offer = NewTestSessionDescription( |
- content_name, content_type); |
- EXPECT_TRUE(initiator->session->Initiate(kResponder, offer)); |
- |
- EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout); |
- EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE, |
- initiator->session_state()); |
- initiator->ExpectSentStanza( |
- IqSet("0", kInitiator, kResponder, |
- InitiateXml(protocol, content_name, content_type))); |
- |
- // Fake the delivery the initiate and candidates together. |
- responder->DeliverStanza( |
- IqSet("A", kInitiator, kResponder, |
- JingleInitiateActionXml( |
- JingleContentXml( |
- content_name, content_type, kTransportType, |
- P2pCandidateXml(channel_name_a, 0) + |
- P2pCandidateXml(channel_name_a, 1) + |
- P2pCandidateXml(channel_name_b, 2) + |
- P2pCandidateXml(channel_name_b, 3))))); |
- responder->ExpectSentStanza( |
- IqAck("A", kResponder, kInitiator)); |
- EXPECT_EQ(0U, responder->sent_stanza_count()); |
- |
- EXPECT_EQ(1U, responder->session_created_count); |
- EXPECT_EQ(kSessionId, responder->session->id()); |
- EXPECT_EQ(responder->session->local_name(), kResponder); |
- EXPECT_EQ(responder->session->remote_name(), kInitiator); |
- EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE, |
- responder->session_state()); |
- |
- EXPECT_TRUE(responder->HasTransport(content_name)); |
- EXPECT_TRUE(responder->HasChannel(content_name, 1)); |
- EXPECT_TRUE(responder->HasTransport(content_name)); |
- EXPECT_TRUE(responder->HasChannel(content_name, 2)); |
- |
- // Expect transport-info message from initiator. |
- // But don't send candidates until initiate ack is received. |
- initiator->DeliverAckToLastStanza(); |
- initiator->PrepareCandidates(); |
- EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout); |
- initiator->ExpectSentStanza( |
- IqSet("1", kInitiator, kResponder, |
- TransportInfo4Xml(protocol, content_name, |
- channel_name_a, 0, 1, |
- channel_name_b, 2, 3))); |
- |
- responder->PrepareCandidates(); |
- EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout); |
- responder->ExpectSentStanza( |
- IqSet("2", kResponder, kInitiator, |
- TransportInfo4Xml(protocol, content_name, |
- channel_name_a, 4, 5, |
- channel_name_b, 6, 7))); |
- |
- // Accept the session and expect accept stanza. |
- cricket::SessionDescription* answer = NewTestSessionDescription( |
- content_name, content_type); |
- EXPECT_TRUE(responder->session->Accept(answer)); |
- |
- responder->ExpectSentStanza( |
- IqSet("3", kResponder, kInitiator, |
- AcceptXml(protocol, content_name, content_type))); |
- EXPECT_EQ(0U, responder->sent_stanza_count()); |
- |
- // Fake the delivery the accept and candidates together. |
- initiator->DeliverStanza( |
- IqSet("B", kResponder, kInitiator, |
- JingleActionXml("session-accept", |
- JingleContentXml( |
- content_name, content_type, kTransportType, |
- P2pCandidateXml(channel_name_a, 4) + |
- P2pCandidateXml(channel_name_a, 5) + |
- P2pCandidateXml(channel_name_b, 6) + |
- P2pCandidateXml(channel_name_b, 7))))); |
- EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout); |
- initiator->ExpectSentStanza( |
- IqAck("B", kInitiator, kResponder)); |
- EXPECT_EQ(0U, initiator->sent_stanza_count()); |
- |
- // The channels should be able to become writable at this point. This |
- // requires pinging, so it may take a little while. |
- EXPECT_TRUE_WAIT(initiator->chan_a->writable() && |
- initiator->chan_a->readable(), kEventTimeout); |
- EXPECT_TRUE_WAIT(initiator->chan_b->writable() && |
- initiator->chan_b->readable(), kEventTimeout); |
- EXPECT_TRUE_WAIT(responder->chan_a->writable() && |
- responder->chan_a->readable(), kEventTimeout); |
- EXPECT_TRUE_WAIT(responder->chan_b->writable() && |
- responder->chan_b->readable(), kEventTimeout); |
- |
- |
- // Both sessions should be in progress and have functioning |
- // channels. |
- EXPECT_EQ(protocol, initiator->session->current_protocol()); |
- EXPECT_EQ(protocol, responder->session->current_protocol()); |
- EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS, |
- initiator->session_state(), kEventTimeout); |
- EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS, |
- responder->session_state(), kEventTimeout); |
- TestSendRecv(initiator->chan_a.get(), initiator->chan_b.get(), |
- responder->chan_a.get(), responder->chan_b.get()); |
- } |
- |
- // Tests that when an initiator terminates right after initiate, |
- // everything behaves correctly. |
- void TestEarlyTerminationFromInitiator(SignalingProtocol protocol) { |
- std::string content_name = "main"; |
- std::string content_type = "http://oink.splat/session"; |
- |
- rtc::scoped_ptr<cricket::PortAllocator> allocator( |
- new TestPortAllocator()); |
- int next_message_id = 0; |
- |
- rtc::scoped_ptr<TestClient> initiator( |
- new TestClient(allocator.get(), &next_message_id, |
- kInitiator, protocol, |
- content_type, |
- content_name, "a", |
- content_name, "b")); |
- |
- rtc::scoped_ptr<TestClient> responder( |
- new TestClient(allocator.get(), &next_message_id, |
- kResponder, protocol, |
- content_type, |
- content_name, "a", |
- content_name, "b")); |
- |
- // Send initiate |
- initiator->CreateSession(); |
- EXPECT_TRUE(initiator->session->Initiate( |
- kResponder, NewTestSessionDescription(content_name, content_type))); |
- initiator->ExpectSentStanza( |
- IqSet("0", kInitiator, kResponder, |
- InitiateXml(protocol, content_name, content_type))); |
- EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE, |
- initiator->session_state()); |
- |
- responder->DeliverStanza(initiator->stanza()); |
- responder->ExpectSentStanza( |
- IqAck("0", kResponder, kInitiator)); |
- EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE, |
- responder->session_state()); |
- |
- initiator->session->TerminateWithReason(cricket::STR_TERMINATE_ERROR); |
- initiator->ExpectSentStanza( |
- IqSet("1", kInitiator, kResponder, |
- TerminateXml(protocol, cricket::STR_TERMINATE_ERROR))); |
- EXPECT_EQ(cricket::BaseSession::STATE_SENTTERMINATE, |
- initiator->session_state()); |
- |
- responder->DeliverStanza(initiator->stanza()); |
- responder->ExpectSentStanza( |
- IqAck("1", kResponder, kInitiator)); |
- EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDTERMINATE, |
- responder->session_state()); |
- } |
- |
- // Tests that when the responder rejects, everything behaves |
- // correctly. |
- void TestRejection(SignalingProtocol protocol) { |
- std::string content_name = "main"; |
- std::string content_type = "http://oink.splat/session"; |
- |
- rtc::scoped_ptr<cricket::PortAllocator> allocator( |
- new TestPortAllocator()); |
- int next_message_id = 0; |
- |
- rtc::scoped_ptr<TestClient> initiator( |
- new TestClient(allocator.get(), &next_message_id, |
- kInitiator, protocol, |
- content_type, |
- content_name, "a", |
- content_name, "b")); |
- |
- // Send initiate |
- initiator->CreateSession(); |
- EXPECT_TRUE(initiator->session->Initiate( |
- kResponder, NewTestSessionDescription(content_name, content_type))); |
- initiator->ExpectSentStanza( |
- IqSet("0", kInitiator, kResponder, |
- InitiateXml(protocol, content_name, content_type))); |
- EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE, |
- initiator->session_state()); |
- |
- initiator->DeliverStanza( |
- IqSet("1", kResponder, kInitiator, |
- RejectXml(protocol, cricket::STR_TERMINATE_ERROR))); |
- initiator->ExpectSentStanza( |
- IqAck("1", kInitiator, kResponder)); |
- if (protocol == PROTOCOL_JINGLE) { |
- EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDTERMINATE, |
- initiator->session_state()); |
- } else { |
- EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDREJECT, |
- initiator->session_state()); |
- } |
- } |
- |
- void TestTransportMux() { |
- SignalingProtocol initiator_protocol = PROTOCOL_JINGLE; |
- SignalingProtocol responder_protocol = PROTOCOL_JINGLE; |
- SignalingProtocol resulting_protocol = PROTOCOL_JINGLE; |
- std::string content_type = cricket::NS_JINGLE_RTP; |
- std::string gingle_content_type = cricket::NS_GINGLE_VIDEO; |
- std::string content_name_a = cricket::CN_AUDIO; |
- std::string channel_name_a = "rtp"; |
- std::string content_name_b = cricket::CN_VIDEO; |
- std::string channel_name_b = "video_rtp"; |
- |
- std::string initiate_xml = InitiateXml( |
- initiator_protocol, |
- gingle_content_type, |
- content_name_a, content_type, |
- content_name_b, content_type, true); |
- std::string transport_info_a_xml = TransportInfo2Xml( |
- initiator_protocol, content_name_a, |
- channel_name_a, 0, 1); |
- std::string transport_info_b_xml = TransportInfo2Xml( |
- initiator_protocol, content_name_b, |
- channel_name_b, 2, 3); |
- std::string transport_info_reply_a_xml = TransportInfo2Xml( |
- resulting_protocol, content_name_a, |
- channel_name_a, 4, 5); |
- std::string transport_info_reply_b_xml = TransportInfo2Xml( |
- resulting_protocol, content_name_b, |
- channel_name_b, 6, 7); |
- std::string accept_xml = AcceptXml( |
- resulting_protocol, |
- gingle_content_type, |
- content_name_a, content_type, |
- content_name_b, content_type, true); |
- |
- TestSession(initiator_protocol, responder_protocol, resulting_protocol, |
- gingle_content_type, |
- content_type, |
- content_name_a, channel_name_a, |
- content_name_b, channel_name_b, |
- initiate_xml, |
- transport_info_a_xml, transport_info_b_xml, |
- transport_info_reply_a_xml, transport_info_reply_b_xml, |
- accept_xml, |
- true); |
- } |
- |
- void TestSendDescriptionInfo() { |
- rtc::scoped_ptr<cricket::PortAllocator> allocator( |
- new TestPortAllocator()); |
- int next_message_id = 0; |
- |
- std::string content_name = "content-name"; |
- std::string content_type = "content-type"; |
- rtc::scoped_ptr<TestClient> initiator( |
- new TestClient(allocator.get(), &next_message_id, |
- kInitiator, PROTOCOL_JINGLE, |
- content_type, |
- content_name, "", |
- "", "")); |
- |
- initiator->CreateSession(); |
- cricket::SessionDescription* offer = NewTestSessionDescription( |
- content_name, content_type); |
- std::string initiate_xml = InitiateXml( |
- PROTOCOL_JINGLE, content_name, content_type); |
- |
- cricket::ContentInfos contents; |
- TestContentDescription content(content_type, content_type); |
- contents.push_back( |
- cricket::ContentInfo(content_name, content_type, &content)); |
- std::string description_info_xml = JingleDescriptionInfoXml( |
- content_name, content_type); |
- |
- EXPECT_TRUE(initiator->session->Initiate(kResponder, offer)); |
- initiator->ExpectSentStanza( |
- IqSet("0", kInitiator, kResponder, initiate_xml)); |
- |
- EXPECT_TRUE(initiator->session->SendDescriptionInfoMessage(contents)); |
- initiator->ExpectSentStanza( |
- IqSet("1", kInitiator, kResponder, description_info_xml)); |
- } |
- |
- void DoTestSignalNewDescription( |
- TestClient* client, |
- cricket::BaseSession::State state, |
- cricket::ContentAction expected_content_action, |
- cricket::ContentSource expected_content_source) { |
- // Clean up before the new test. |
- client->new_local_description = false; |
- client->new_remote_description = false; |
- |
- client->SetSessionState(state); |
- EXPECT_EQ((expected_content_source == cricket::CS_LOCAL), |
- client->new_local_description); |
- EXPECT_EQ((expected_content_source == cricket::CS_REMOTE), |
- client->new_remote_description); |
- EXPECT_EQ(expected_content_action, client->last_content_action); |
- EXPECT_EQ(expected_content_source, client->last_content_source); |
- } |
- |
- void TestCallerSignalNewDescription() { |
- rtc::scoped_ptr<cricket::PortAllocator> allocator( |
- new TestPortAllocator()); |
- int next_message_id = 0; |
- |
- std::string content_name = "content-name"; |
- std::string content_type = "content-type"; |
- rtc::scoped_ptr<TestClient> initiator( |
- new TestClient(allocator.get(), &next_message_id, |
- kInitiator, PROTOCOL_JINGLE, |
- content_type, |
- content_name, "", |
- "", "")); |
- |
- initiator->CreateSession(); |
- |
- // send offer -> send update offer -> |
- // receive pr answer -> receive update pr answer -> |
- // receive answer |
- DoTestSignalNewDescription( |
- initiator.get(), cricket::BaseSession::STATE_SENTINITIATE, |
- cricket::CA_OFFER, cricket::CS_LOCAL); |
- |
- DoTestSignalNewDescription( |
- initiator.get(), cricket::BaseSession::STATE_SENTINITIATE, |
- cricket::CA_OFFER, cricket::CS_LOCAL); |
- |
- DoTestSignalNewDescription( |
- initiator.get(), cricket::BaseSession::STATE_RECEIVEDPRACCEPT, |
- cricket::CA_PRANSWER, cricket::CS_REMOTE); |
- |
- DoTestSignalNewDescription( |
- initiator.get(), cricket::BaseSession::STATE_RECEIVEDPRACCEPT, |
- cricket::CA_PRANSWER, cricket::CS_REMOTE); |
- |
- DoTestSignalNewDescription( |
- initiator.get(), cricket::BaseSession::STATE_RECEIVEDACCEPT, |
- cricket::CA_ANSWER, cricket::CS_REMOTE); |
- } |
- |
- void TestCalleeSignalNewDescription() { |
- rtc::scoped_ptr<cricket::PortAllocator> allocator( |
- new TestPortAllocator()); |
- int next_message_id = 0; |
- |
- std::string content_name = "content-name"; |
- std::string content_type = "content-type"; |
- rtc::scoped_ptr<TestClient> initiator( |
- new TestClient(allocator.get(), &next_message_id, |
- kInitiator, PROTOCOL_JINGLE, |
- content_type, |
- content_name, "", |
- "", "")); |
- |
- initiator->CreateSession(); |
- |
- // receive offer -> receive update offer -> |
- // send pr answer -> send update pr answer -> |
- // send answer |
- DoTestSignalNewDescription( |
- initiator.get(), cricket::BaseSession::STATE_RECEIVEDINITIATE, |
- cricket::CA_OFFER, cricket::CS_REMOTE); |
- |
- DoTestSignalNewDescription( |
- initiator.get(), cricket::BaseSession::STATE_RECEIVEDINITIATE, |
- cricket::CA_OFFER, cricket::CS_REMOTE); |
- |
- DoTestSignalNewDescription( |
- initiator.get(), cricket::BaseSession::STATE_SENTPRACCEPT, |
- cricket::CA_PRANSWER, cricket::CS_LOCAL); |
- |
- DoTestSignalNewDescription( |
- initiator.get(), cricket::BaseSession::STATE_SENTPRACCEPT, |
- cricket::CA_PRANSWER, cricket::CS_LOCAL); |
- |
- DoTestSignalNewDescription( |
- initiator.get(), cricket::BaseSession::STATE_SENTACCEPT, |
- cricket::CA_ANSWER, cricket::CS_LOCAL); |
- } |
- |
- void TestGetTransportStats() { |
- rtc::scoped_ptr<cricket::PortAllocator> allocator( |
- new TestPortAllocator()); |
- int next_message_id = 0; |
- |
- std::string content_name = "content-name"; |
- std::string content_type = "content-type"; |
- rtc::scoped_ptr<TestClient> initiator( |
- new TestClient(allocator.get(), &next_message_id, |
- kInitiator, PROTOCOL_JINGLE, |
- content_type, |
- content_name, "", |
- "", "")); |
- initiator->CreateSession(); |
- |
- cricket::SessionStats stats; |
- EXPECT_TRUE(initiator->session->GetStats(&stats)); |
- // At initiation, there are 2 transports. |
- EXPECT_EQ(2ul, stats.proxy_to_transport.size()); |
- EXPECT_EQ(2ul, stats.transport_stats.size()); |
- } |
-}; |
- |
-// For each of these, "X => Y = Z" means "if a client with protocol X |
-// initiates to a client with protocol Y, they end up speaking protocol Z. |
- |
-// Gingle => Gingle = Gingle (with other content) |
-TEST_F(SessionTest, GingleToGingleOtherContent) { |
- TestOtherContent(PROTOCOL_GINGLE, PROTOCOL_GINGLE, PROTOCOL_GINGLE); |
-} |
- |
-// Gingle => Gingle = Gingle (with audio content) |
-TEST_F(SessionTest, GingleToGingleAudioContent) { |
- TestAudioContent(PROTOCOL_GINGLE, PROTOCOL_GINGLE, PROTOCOL_GINGLE); |
-} |
- |
-// Gingle => Gingle = Gingle (with video contents) |
-TEST_F(SessionTest, GingleToGingleVideoContents) { |
- TestVideoContents(PROTOCOL_GINGLE, PROTOCOL_GINGLE, PROTOCOL_GINGLE); |
-} |
- |
-// Jingle => Jingle = Jingle (with other content) |
-TEST_F(SessionTest, JingleToJingleOtherContent) { |
- TestOtherContent(PROTOCOL_JINGLE, PROTOCOL_JINGLE, PROTOCOL_JINGLE); |
-} |
- |
-// Jingle => Jingle = Jingle (with audio content) |
-TEST_F(SessionTest, JingleToJingleAudioContent) { |
- TestAudioContent(PROTOCOL_JINGLE, PROTOCOL_JINGLE, PROTOCOL_JINGLE); |
-} |
- |
-// Jingle => Jingle = Jingle (with video contents) |
-TEST_F(SessionTest, JingleToJingleVideoContents) { |
- TestVideoContents(PROTOCOL_JINGLE, PROTOCOL_JINGLE, PROTOCOL_JINGLE); |
-} |
- |
-// Hybrid => Hybrid = Jingle (with other content) |
-TEST_F(SessionTest, HybridToHybridOtherContent) { |
- TestOtherContent(PROTOCOL_HYBRID, PROTOCOL_HYBRID, PROTOCOL_JINGLE); |
-} |
- |
-// Hybrid => Hybrid = Jingle (with audio content) |
-TEST_F(SessionTest, HybridToHybridAudioContent) { |
- TestAudioContent(PROTOCOL_HYBRID, PROTOCOL_HYBRID, PROTOCOL_JINGLE); |
-} |
- |
-// Hybrid => Hybrid = Jingle (with video contents) |
-TEST_F(SessionTest, HybridToHybridVideoContents) { |
- TestVideoContents(PROTOCOL_HYBRID, PROTOCOL_HYBRID, PROTOCOL_JINGLE); |
-} |
- |
-// Gingle => Hybrid = Gingle (with other content) |
-TEST_F(SessionTest, GingleToHybridOtherContent) { |
- TestOtherContent(PROTOCOL_GINGLE, PROTOCOL_HYBRID, PROTOCOL_GINGLE); |
-} |
- |
-// Gingle => Hybrid = Gingle (with audio content) |
-TEST_F(SessionTest, GingleToHybridAudioContent) { |
- TestAudioContent(PROTOCOL_GINGLE, PROTOCOL_HYBRID, PROTOCOL_GINGLE); |
-} |
- |
-// Gingle => Hybrid = Gingle (with video contents) |
-TEST_F(SessionTest, GingleToHybridVideoContents) { |
- TestVideoContents(PROTOCOL_GINGLE, PROTOCOL_HYBRID, PROTOCOL_GINGLE); |
-} |
- |
-// Jingle => Hybrid = Jingle (with other content) |
-TEST_F(SessionTest, JingleToHybridOtherContent) { |
- TestOtherContent(PROTOCOL_JINGLE, PROTOCOL_HYBRID, PROTOCOL_JINGLE); |
-} |
- |
-// Jingle => Hybrid = Jingle (with audio content) |
-TEST_F(SessionTest, JingleToHybridAudioContent) { |
- TestAudioContent(PROTOCOL_JINGLE, PROTOCOL_HYBRID, PROTOCOL_JINGLE); |
-} |
- |
-// Jingle => Hybrid = Jingle (with video contents) |
-TEST_F(SessionTest, JingleToHybridVideoContents) { |
- TestVideoContents(PROTOCOL_JINGLE, PROTOCOL_HYBRID, PROTOCOL_JINGLE); |
-} |
- |
-// Hybrid => Gingle = Gingle (with other content) |
-TEST_F(SessionTest, HybridToGingleOtherContent) { |
- TestOtherContent(PROTOCOL_HYBRID, PROTOCOL_GINGLE, PROTOCOL_GINGLE); |
-} |
- |
-// Hybrid => Gingle = Gingle (with audio content) |
-TEST_F(SessionTest, HybridToGingleAudioContent) { |
- TestAudioContent(PROTOCOL_HYBRID, PROTOCOL_GINGLE, PROTOCOL_GINGLE); |
-} |
- |
-// Hybrid => Gingle = Gingle (with video contents) |
-TEST_F(SessionTest, HybridToGingleVideoContents) { |
- TestVideoContents(PROTOCOL_HYBRID, PROTOCOL_GINGLE, PROTOCOL_GINGLE); |
-} |
- |
-// Hybrid => Jingle = Jingle (with other content) |
-TEST_F(SessionTest, HybridToJingleOtherContent) { |
- TestOtherContent(PROTOCOL_HYBRID, PROTOCOL_JINGLE, PROTOCOL_JINGLE); |
-} |
- |
-// Hybrid => Jingle = Jingle (with audio content) |
-TEST_F(SessionTest, HybridToJingleAudioContent) { |
- TestAudioContent(PROTOCOL_HYBRID, PROTOCOL_JINGLE, PROTOCOL_JINGLE); |
-} |
- |
-// Hybrid => Jingle = Jingle (with video contents) |
-TEST_F(SessionTest, HybridToJingleVideoContents) { |
- TestVideoContents(PROTOCOL_HYBRID, PROTOCOL_JINGLE, PROTOCOL_JINGLE); |
-} |
- |
-TEST_F(SessionTest, GingleEarlyTerminationFromInitiator) { |
- TestEarlyTerminationFromInitiator(PROTOCOL_GINGLE); |
-} |
- |
-TEST_F(SessionTest, JingleEarlyTerminationFromInitiator) { |
- TestEarlyTerminationFromInitiator(PROTOCOL_JINGLE); |
-} |
- |
-TEST_F(SessionTest, HybridEarlyTerminationFromInitiator) { |
- TestEarlyTerminationFromInitiator(PROTOCOL_HYBRID); |
-} |
- |
-TEST_F(SessionTest, GingleRejection) { |
- TestRejection(PROTOCOL_GINGLE); |
-} |
- |
-TEST_F(SessionTest, JingleRejection) { |
- TestRejection(PROTOCOL_JINGLE); |
-} |
- |
-TEST_F(SessionTest, GingleGoodRedirect) { |
- TestGoodRedirect(PROTOCOL_GINGLE); |
-} |
- |
-TEST_F(SessionTest, JingleGoodRedirect) { |
- TestGoodRedirect(PROTOCOL_JINGLE); |
-} |
- |
-TEST_F(SessionTest, GingleBadRedirect) { |
- TestBadRedirect(PROTOCOL_GINGLE); |
-} |
- |
-TEST_F(SessionTest, JingleBadRedirect) { |
- TestBadRedirect(PROTOCOL_JINGLE); |
-} |
- |
-TEST_F(SessionTest, TestCandidatesInInitiateAndAccept) { |
- TestCandidatesInInitiateAndAccept("Candidates in initiate/accept"); |
-} |
- |
-TEST_F(SessionTest, TestTransportMux) { |
- TestTransportMux(); |
-} |
- |
-TEST_F(SessionTest, TestSendDescriptionInfo) { |
- TestSendDescriptionInfo(); |
-} |
- |
-TEST_F(SessionTest, TestCallerSignalNewDescription) { |
- TestCallerSignalNewDescription(); |
-} |
- |
-TEST_F(SessionTest, TestCalleeSignalNewDescription) { |
- TestCalleeSignalNewDescription(); |
-} |
- |
-TEST_F(SessionTest, TestGetTransportStats) { |
- TestGetTransportStats(); |
-} |