• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libjingle
3  * Copyright 2012 Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include <vector>
29 
30 #include "talk/base/fakenetwork.h"
31 #include "talk/base/gunit.h"
32 #include "talk/base/thread.h"
33 #include "talk/p2p/base/basicpacketsocketfactory.h"
34 #include "talk/p2p/base/portallocatorsessionproxy.h"
35 #include "talk/p2p/client/basicportallocator.h"
36 #include "talk/p2p/client/fakeportallocator.h"
37 
38 using cricket::Candidate;
39 using cricket::PortAllocatorSession;
40 using cricket::PortAllocatorSessionMuxer;
41 using cricket::PortAllocatorSessionProxy;
42 
43 // Based on ICE_UFRAG_LENGTH
44 static const char kIceUfrag0[] = "TESTICEUFRAG0000";
45 // Based on ICE_PWD_LENGTH
46 static const char kIcePwd0[] = "TESTICEPWD00000000000000";
47 
48 class TestSessionChannel : public sigslot::has_slots<> {
49  public:
TestSessionChannel(PortAllocatorSessionProxy * proxy)50   explicit TestSessionChannel(PortAllocatorSessionProxy* proxy)
51       : proxy_session_(proxy),
52         candidates_count_(0),
53         allocation_complete_(false),
54         ports_count_(0) {
55     proxy_session_->SignalCandidatesAllocationDone.connect(
56         this, &TestSessionChannel::OnCandidatesAllocationDone);
57     proxy_session_->SignalCandidatesReady.connect(
58         this, &TestSessionChannel::OnCandidatesReady);
59     proxy_session_->SignalPortReady.connect(
60         this, &TestSessionChannel::OnPortReady);
61   }
~TestSessionChannel()62   virtual ~TestSessionChannel() {
63     delete proxy_session_;
64   }
OnCandidatesReady(PortAllocatorSession * session,const std::vector<Candidate> & candidates)65   void OnCandidatesReady(PortAllocatorSession* session,
66                          const std::vector<Candidate>& candidates) {
67     EXPECT_EQ(proxy_session_, session);
68     candidates_count_ += static_cast<int>(candidates.size());
69   }
OnCandidatesAllocationDone(PortAllocatorSession * session)70   void OnCandidatesAllocationDone(PortAllocatorSession* session) {
71     EXPECT_EQ(proxy_session_, session);
72     allocation_complete_ = true;
73   }
OnPortReady(PortAllocatorSession * session,cricket::PortInterface * port)74   void OnPortReady(PortAllocatorSession* session,
75                    cricket::PortInterface* port) {
76     EXPECT_EQ(proxy_session_, session);
77     ++ports_count_;
78   }
candidates_count()79   int candidates_count() { return candidates_count_; }
allocation_complete()80   bool allocation_complete() { return allocation_complete_; }
ports_count()81   int ports_count() { return ports_count_; }
82 
StartGettingPorts()83   void StartGettingPorts() {
84     proxy_session_->StartGettingPorts();
85   }
86 
StopGettingPorts()87   void StopGettingPorts() {
88     proxy_session_->StopGettingPorts();
89   }
90 
IsGettingPorts()91   bool IsGettingPorts() {
92     return proxy_session_->IsGettingPorts();
93   }
94 
95  private:
96   PortAllocatorSessionProxy* proxy_session_;
97   int candidates_count_;
98   bool allocation_complete_;
99   int ports_count_;
100 };
101 
102 class PortAllocatorSessionProxyTest : public testing::Test {
103  public:
PortAllocatorSessionProxyTest()104   PortAllocatorSessionProxyTest()
105       : socket_factory_(talk_base::Thread::Current()),
106         allocator_(talk_base::Thread::Current(), NULL),
107         session_(new cricket::FakePortAllocatorSession(
108                      talk_base::Thread::Current(), &socket_factory_,
109                      "test content", 1,
110                      kIceUfrag0, kIcePwd0)),
111         session_muxer_(new PortAllocatorSessionMuxer(session_)) {
112   }
~PortAllocatorSessionProxyTest()113   virtual ~PortAllocatorSessionProxyTest() {}
RegisterSessionProxy(PortAllocatorSessionProxy * proxy)114   void RegisterSessionProxy(PortAllocatorSessionProxy* proxy) {
115     session_muxer_->RegisterSessionProxy(proxy);
116   }
117 
CreateChannel()118   TestSessionChannel* CreateChannel() {
119     PortAllocatorSessionProxy* proxy =
120         new PortAllocatorSessionProxy("test content", 1, 0);
121     TestSessionChannel* channel = new TestSessionChannel(proxy);
122     session_muxer_->RegisterSessionProxy(proxy);
123     channel->StartGettingPorts();
124     return channel;
125   }
126 
127  protected:
128   talk_base::BasicPacketSocketFactory socket_factory_;
129   cricket::FakePortAllocator allocator_;
130   cricket::FakePortAllocatorSession* session_;
131   // Muxer object will be delete itself after all registered session proxies
132   // are deleted.
133   PortAllocatorSessionMuxer* session_muxer_;
134 };
135 
TEST_F(PortAllocatorSessionProxyTest,TestBasic)136 TEST_F(PortAllocatorSessionProxyTest, TestBasic) {
137   TestSessionChannel* channel = CreateChannel();
138   EXPECT_EQ_WAIT(1, channel->candidates_count(), 1000);
139   EXPECT_EQ(1, channel->ports_count());
140   EXPECT_TRUE(channel->allocation_complete());
141   delete channel;
142 }
143 
TEST_F(PortAllocatorSessionProxyTest,TestLateBinding)144 TEST_F(PortAllocatorSessionProxyTest, TestLateBinding) {
145   TestSessionChannel* channel1 = CreateChannel();
146   EXPECT_EQ_WAIT(1, channel1->candidates_count(), 1000);
147   EXPECT_EQ(1, channel1->ports_count());
148   EXPECT_TRUE(channel1->allocation_complete());
149   EXPECT_EQ(1, session_->port_config_count());
150   // Creating another PortAllocatorSessionProxy and it also should receive
151   // already happened events.
152   PortAllocatorSessionProxy* proxy =
153       new PortAllocatorSessionProxy("test content", 2, 0);
154   TestSessionChannel* channel2 = new TestSessionChannel(proxy);
155   session_muxer_->RegisterSessionProxy(proxy);
156   EXPECT_TRUE(channel2->IsGettingPorts());
157   EXPECT_EQ_WAIT(1, channel2->candidates_count(), 1000);
158   EXPECT_EQ(1, channel2->ports_count());
159   EXPECT_TRUE_WAIT(channel2->allocation_complete(), 1000);
160   EXPECT_EQ(1, session_->port_config_count());
161   delete channel1;
162   delete channel2;
163 }
164