Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / base / physicalsocketserver_unittest.cc
1 /*
2  * libjingle
3  * Copyright 2004--2011, 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 <signal.h>
29 #include <stdarg.h>
30
31 #include "talk/base/gunit.h"
32 #include "talk/base/logging.h"
33 #include "talk/base/physicalsocketserver.h"
34 #include "talk/base/scoped_ptr.h"
35 #include "talk/base/socket_unittest.h"
36 #include "talk/base/testutils.h"
37 #include "talk/base/thread.h"
38
39 namespace talk_base {
40
41 class PhysicalSocketTest : public SocketTest {
42 };
43
44 TEST_F(PhysicalSocketTest, TestConnectIPv4) {
45   SocketTest::TestConnectIPv4();
46 }
47
48 TEST_F(PhysicalSocketTest, TestConnectIPv6) {
49   SocketTest::TestConnectIPv6();
50 }
51
52 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) {
53   SocketTest::TestConnectWithDnsLookupIPv4();
54 }
55
56 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) {
57   SocketTest::TestConnectWithDnsLookupIPv6();
58 }
59
60 TEST_F(PhysicalSocketTest, TestConnectFailIPv4) {
61   SocketTest::TestConnectFailIPv4();
62 }
63
64 TEST_F(PhysicalSocketTest, TestConnectFailIPv6) {
65   SocketTest::TestConnectFailIPv6();
66 }
67
68 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) {
69   SocketTest::TestConnectWithDnsLookupFailIPv4();
70 }
71
72
73 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv6) {
74   SocketTest::TestConnectWithDnsLookupFailIPv6();
75 }
76
77
78 TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) {
79   SocketTest::TestConnectWithClosedSocketIPv4();
80 }
81
82 TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv6) {
83   SocketTest::TestConnectWithClosedSocketIPv6();
84 }
85
86 TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) {
87   SocketTest::TestConnectWhileNotClosedIPv4();
88 }
89
90 TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv6) {
91   SocketTest::TestConnectWhileNotClosedIPv6();
92 }
93
94 TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) {
95   SocketTest::TestServerCloseDuringConnectIPv4();
96 }
97
98 TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv6) {
99   SocketTest::TestServerCloseDuringConnectIPv6();
100 }
101
102 TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) {
103   SocketTest::TestClientCloseDuringConnectIPv4();
104 }
105
106 TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv6) {
107   SocketTest::TestClientCloseDuringConnectIPv6();
108 }
109
110 TEST_F(PhysicalSocketTest, TestServerCloseIPv4) {
111   SocketTest::TestServerCloseIPv4();
112 }
113
114 TEST_F(PhysicalSocketTest, TestServerCloseIPv6) {
115   SocketTest::TestServerCloseIPv6();
116 }
117
118 TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) {
119   SocketTest::TestCloseInClosedCallbackIPv4();
120 }
121
122 TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv6) {
123   SocketTest::TestCloseInClosedCallbackIPv6();
124 }
125
126 TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) {
127   SocketTest::TestSocketServerWaitIPv4();
128 }
129
130 TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv6) {
131   SocketTest::TestSocketServerWaitIPv6();
132 }
133
134 TEST_F(PhysicalSocketTest, TestTcpIPv4) {
135   SocketTest::TestTcpIPv4();
136 }
137
138 TEST_F(PhysicalSocketTest, TestTcpIPv6) {
139   SocketTest::TestTcpIPv6();
140 }
141
142 TEST_F(PhysicalSocketTest, TestUdpIPv4) {
143   SocketTest::TestUdpIPv4();
144 }
145
146 TEST_F(PhysicalSocketTest, TestUdpIPv6) {
147   SocketTest::TestUdpIPv6();
148 }
149
150 TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv4) {
151   SocketTest::TestUdpReadyToSendIPv4();
152 }
153
154 TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv6) {
155   SocketTest::TestUdpReadyToSendIPv6();
156 }
157
158 TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) {
159   SocketTest::TestGetSetOptionsIPv4();
160 }
161
162 TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) {
163   SocketTest::TestGetSetOptionsIPv6();
164 }
165
166 #ifdef POSIX
167
168 class PosixSignalDeliveryTest : public testing::Test {
169  public:
170   static void RecordSignal(int signum) {
171     signals_received_.push_back(signum);
172     signaled_thread_ = Thread::Current();
173   }
174
175  protected:
176   void SetUp() {
177     ss_.reset(new PhysicalSocketServer());
178   }
179
180   void TearDown() {
181     ss_.reset(NULL);
182     signals_received_.clear();
183     signaled_thread_ = NULL;
184   }
185
186   bool ExpectSignal(int signum) {
187     if (signals_received_.empty()) {
188       LOG(LS_ERROR) << "ExpectSignal(): No signal received";
189       return false;
190     }
191     if (signals_received_[0] != signum) {
192       LOG(LS_ERROR) << "ExpectSignal(): Received signal " <<
193           signals_received_[0] << ", expected " << signum;
194       return false;
195     }
196     signals_received_.erase(signals_received_.begin());
197     return true;
198   }
199
200   bool ExpectNone() {
201     bool ret = signals_received_.empty();
202     if (!ret) {
203       LOG(LS_ERROR) << "ExpectNone(): Received signal " << signals_received_[0]
204           << ", expected none";
205     }
206     return ret;
207   }
208
209   static std::vector<int> signals_received_;
210   static Thread *signaled_thread_;
211
212   scoped_ptr<PhysicalSocketServer> ss_;
213 };
214
215 std::vector<int> PosixSignalDeliveryTest::signals_received_;
216 Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL;
217
218 // Test receiving a synchronous signal while not in Wait() and then entering
219 // Wait() afterwards.
220 TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
221   ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal));
222   raise(SIGTERM);
223   EXPECT_TRUE(ss_->Wait(0, true));
224   EXPECT_TRUE(ExpectSignal(SIGTERM));
225   EXPECT_TRUE(ExpectNone());
226 }
227
228 // Test that we can handle getting tons of repeated signals and that we see all
229 // the different ones.
230 TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) {
231   ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
232   ss_->SetPosixSignalHandler(SIGINT, &RecordSignal);
233   for (int i = 0; i < 10000; ++i) {
234     raise(SIGTERM);
235   }
236   raise(SIGINT);
237   EXPECT_TRUE(ss_->Wait(0, true));
238   // Order will be lowest signal numbers first.
239   EXPECT_TRUE(ExpectSignal(SIGINT));
240   EXPECT_TRUE(ExpectSignal(SIGTERM));
241   EXPECT_TRUE(ExpectNone());
242 }
243
244 // Test that a signal during a Wait() call is detected.
245 TEST_F(PosixSignalDeliveryTest, SignalDuringWait) {
246   ss_->SetPosixSignalHandler(SIGALRM, &RecordSignal);
247   alarm(1);
248   EXPECT_TRUE(ss_->Wait(1500, true));
249   EXPECT_TRUE(ExpectSignal(SIGALRM));
250   EXPECT_TRUE(ExpectNone());
251 }
252
253 class RaiseSigTermRunnable : public Runnable {
254   void Run(Thread *thread) {
255     thread->socketserver()->Wait(1000, false);
256
257     // Allow SIGTERM. This will be the only thread with it not masked so it will
258     // be delivered to us.
259     sigset_t mask;
260     sigemptyset(&mask);
261     pthread_sigmask(SIG_SETMASK, &mask, NULL);
262
263     // Raise it.
264     raise(SIGTERM);
265   }
266 };
267
268 // Test that it works no matter what thread the kernel chooses to give the
269 // signal to (since it's not guaranteed to be the one that Wait() runs on).
270 TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) {
271   ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
272   // Mask out SIGTERM so that it can't be delivered to this thread.
273   sigset_t mask;
274   sigemptyset(&mask);
275   sigaddset(&mask, SIGTERM);
276   EXPECT_EQ(0, pthread_sigmask(SIG_SETMASK, &mask, NULL));
277   // Start a new thread that raises it. It will have to be delivered to that
278   // thread. Our implementation should safely handle it and dispatch
279   // RecordSignal() on this thread.
280   scoped_ptr<Thread> thread(new Thread());
281   scoped_ptr<RaiseSigTermRunnable> runnable(new RaiseSigTermRunnable());
282   thread->Start(runnable.get());
283   EXPECT_TRUE(ss_->Wait(1500, true));
284   EXPECT_TRUE(ExpectSignal(SIGTERM));
285   EXPECT_EQ(Thread::Current(), signaled_thread_);
286   EXPECT_TRUE(ExpectNone());
287 }
288
289 #endif
290
291 }  // namespace talk_base