2013-07-10 02:45:36 +02:00
|
|
|
/*
|
|
|
|
* libjingle
|
|
|
|
* Copyright 2012 Google Inc.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
|
|
* and/or other materials provided with the distribution.
|
|
|
|
* 3. The name of the author may not be used to endorse or promote products
|
|
|
|
* derived from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
|
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
|
|
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
|
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
2014-10-18 00:03:39 +02:00
|
|
|
#include "talk/p2p/base/basicpacketsocketfactory.h"
|
|
|
|
#include "talk/p2p/base/portallocatorsessionproxy.h"
|
|
|
|
#include "talk/p2p/client/basicportallocator.h"
|
|
|
|
#include "talk/p2p/client/fakeportallocator.h"
|
2014-08-13 19:26:08 +02:00
|
|
|
#include "webrtc/base/fakenetwork.h"
|
|
|
|
#include "webrtc/base/gunit.h"
|
|
|
|
#include "webrtc/base/thread.h"
|
2013-07-10 02:45:36 +02:00
|
|
|
|
|
|
|
using cricket::Candidate;
|
|
|
|
using cricket::PortAllocatorSession;
|
|
|
|
using cricket::PortAllocatorSessionMuxer;
|
|
|
|
using cricket::PortAllocatorSessionProxy;
|
|
|
|
|
|
|
|
// Based on ICE_UFRAG_LENGTH
|
|
|
|
static const char kIceUfrag0[] = "TESTICEUFRAG0000";
|
|
|
|
// Based on ICE_PWD_LENGTH
|
|
|
|
static const char kIcePwd0[] = "TESTICEPWD00000000000000";
|
|
|
|
|
|
|
|
class TestSessionChannel : public sigslot::has_slots<> {
|
|
|
|
public:
|
|
|
|
explicit TestSessionChannel(PortAllocatorSessionProxy* proxy)
|
|
|
|
: proxy_session_(proxy),
|
|
|
|
candidates_count_(0),
|
|
|
|
allocation_complete_(false),
|
|
|
|
ports_count_(0) {
|
|
|
|
proxy_session_->SignalCandidatesAllocationDone.connect(
|
|
|
|
this, &TestSessionChannel::OnCandidatesAllocationDone);
|
|
|
|
proxy_session_->SignalCandidatesReady.connect(
|
|
|
|
this, &TestSessionChannel::OnCandidatesReady);
|
|
|
|
proxy_session_->SignalPortReady.connect(
|
|
|
|
this, &TestSessionChannel::OnPortReady);
|
|
|
|
}
|
2013-08-20 23:14:39 +02:00
|
|
|
virtual ~TestSessionChannel() {
|
|
|
|
delete proxy_session_;
|
|
|
|
}
|
2013-07-10 02:45:36 +02:00
|
|
|
void OnCandidatesReady(PortAllocatorSession* session,
|
|
|
|
const std::vector<Candidate>& candidates) {
|
|
|
|
EXPECT_EQ(proxy_session_, session);
|
2013-07-22 23:07:49 +02:00
|
|
|
candidates_count_ += static_cast<int>(candidates.size());
|
2013-07-10 02:45:36 +02:00
|
|
|
}
|
|
|
|
void OnCandidatesAllocationDone(PortAllocatorSession* session) {
|
|
|
|
EXPECT_EQ(proxy_session_, session);
|
|
|
|
allocation_complete_ = true;
|
|
|
|
}
|
|
|
|
void OnPortReady(PortAllocatorSession* session,
|
|
|
|
cricket::PortInterface* port) {
|
|
|
|
EXPECT_EQ(proxy_session_, session);
|
|
|
|
++ports_count_;
|
|
|
|
}
|
|
|
|
int candidates_count() { return candidates_count_; }
|
|
|
|
bool allocation_complete() { return allocation_complete_; }
|
|
|
|
int ports_count() { return ports_count_; }
|
|
|
|
|
|
|
|
void StartGettingPorts() {
|
|
|
|
proxy_session_->StartGettingPorts();
|
|
|
|
}
|
|
|
|
|
|
|
|
void StopGettingPorts() {
|
|
|
|
proxy_session_->StopGettingPorts();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsGettingPorts() {
|
|
|
|
return proxy_session_->IsGettingPorts();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
PortAllocatorSessionProxy* proxy_session_;
|
|
|
|
int candidates_count_;
|
|
|
|
bool allocation_complete_;
|
|
|
|
int ports_count_;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PortAllocatorSessionProxyTest : public testing::Test {
|
|
|
|
public:
|
|
|
|
PortAllocatorSessionProxyTest()
|
2014-07-29 19:36:52 +02:00
|
|
|
: socket_factory_(rtc::Thread::Current()),
|
|
|
|
allocator_(rtc::Thread::Current(), NULL),
|
2013-08-20 23:14:39 +02:00
|
|
|
session_(new cricket::FakePortAllocatorSession(
|
2014-07-29 19:36:52 +02:00
|
|
|
rtc::Thread::Current(), &socket_factory_,
|
2013-08-20 23:14:39 +02:00
|
|
|
"test content", 1,
|
|
|
|
kIceUfrag0, kIcePwd0)),
|
|
|
|
session_muxer_(new PortAllocatorSessionMuxer(session_)) {
|
2013-07-10 02:45:36 +02:00
|
|
|
}
|
|
|
|
virtual ~PortAllocatorSessionProxyTest() {}
|
|
|
|
void RegisterSessionProxy(PortAllocatorSessionProxy* proxy) {
|
|
|
|
session_muxer_->RegisterSessionProxy(proxy);
|
|
|
|
}
|
|
|
|
|
|
|
|
TestSessionChannel* CreateChannel() {
|
|
|
|
PortAllocatorSessionProxy* proxy =
|
|
|
|
new PortAllocatorSessionProxy("test content", 1, 0);
|
|
|
|
TestSessionChannel* channel = new TestSessionChannel(proxy);
|
|
|
|
session_muxer_->RegisterSessionProxy(proxy);
|
|
|
|
channel->StartGettingPorts();
|
|
|
|
return channel;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2014-07-29 19:36:52 +02:00
|
|
|
rtc::BasicPacketSocketFactory socket_factory_;
|
2013-07-10 02:45:36 +02:00
|
|
|
cricket::FakePortAllocator allocator_;
|
2013-08-20 23:14:39 +02:00
|
|
|
cricket::FakePortAllocatorSession* session_;
|
2013-07-10 02:45:36 +02:00
|
|
|
// Muxer object will be delete itself after all registered session proxies
|
|
|
|
// are deleted.
|
|
|
|
PortAllocatorSessionMuxer* session_muxer_;
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(PortAllocatorSessionProxyTest, TestBasic) {
|
|
|
|
TestSessionChannel* channel = CreateChannel();
|
|
|
|
EXPECT_EQ_WAIT(1, channel->candidates_count(), 1000);
|
|
|
|
EXPECT_EQ(1, channel->ports_count());
|
|
|
|
EXPECT_TRUE(channel->allocation_complete());
|
|
|
|
delete channel;
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(PortAllocatorSessionProxyTest, TestLateBinding) {
|
|
|
|
TestSessionChannel* channel1 = CreateChannel();
|
|
|
|
EXPECT_EQ_WAIT(1, channel1->candidates_count(), 1000);
|
|
|
|
EXPECT_EQ(1, channel1->ports_count());
|
|
|
|
EXPECT_TRUE(channel1->allocation_complete());
|
2013-08-20 23:14:39 +02:00
|
|
|
EXPECT_EQ(1, session_->port_config_count());
|
2013-07-10 02:45:36 +02:00
|
|
|
// Creating another PortAllocatorSessionProxy and it also should receive
|
|
|
|
// already happened events.
|
|
|
|
PortAllocatorSessionProxy* proxy =
|
|
|
|
new PortAllocatorSessionProxy("test content", 2, 0);
|
|
|
|
TestSessionChannel* channel2 = new TestSessionChannel(proxy);
|
|
|
|
session_muxer_->RegisterSessionProxy(proxy);
|
|
|
|
EXPECT_TRUE(channel2->IsGettingPorts());
|
|
|
|
EXPECT_EQ_WAIT(1, channel2->candidates_count(), 1000);
|
|
|
|
EXPECT_EQ(1, channel2->ports_count());
|
|
|
|
EXPECT_TRUE_WAIT(channel2->allocation_complete(), 1000);
|
2013-08-20 23:14:39 +02:00
|
|
|
EXPECT_EQ(1, session_->port_config_count());
|
2013-07-10 02:45:36 +02:00
|
|
|
delete channel1;
|
|
|
|
delete channel2;
|
|
|
|
}
|