~ubuntu-branches/debian/experimental/kopete/experimental

« back to all changes in this revision

Viewing changes to protocols/jabber/libjingle/talk/base/physicalsocketserver_unittest.cc

  • Committer: Package Import Robot
  • Author(s): Maximiliano Curia
  • Date: 2015-02-24 11:32:57 UTC
  • mfrom: (1.1.41 vivid)
  • Revision ID: package-import@ubuntu.com-20150224113257-gnupg4v7lzz18ij0
Tags: 4:14.12.2-1
* New upstream release (14.12.2).
* Bump Standards-Version to 3.9.6, no changes needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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/thread.h"
 
37
 
 
38
namespace talk_base {
 
39
 
 
40
class PhysicalSocketTest : public SocketTest {
 
41
};
 
42
 
 
43
TEST_F(PhysicalSocketTest, TestConnect) {
 
44
  SocketTest::TestConnect();
 
45
}
 
46
 
 
47
TEST_F(PhysicalSocketTest, TestConnectWithDnsLookup) {
 
48
  SocketTest::TestConnectWithDnsLookup();
 
49
}
 
50
 
 
51
TEST_F(PhysicalSocketTest, TestConnectFail) {
 
52
  SocketTest::TestConnectFail();
 
53
}
 
54
 
 
55
TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFail) {
 
56
  SocketTest::TestConnectWithDnsLookupFail();
 
57
}
 
58
 
 
59
#ifdef OSX
 
60
// This test crashes the OS X kernel on 10.6 (at bsd/netinet/tcp_subr.c:2118).
 
61
TEST_F(PhysicalSocketTest, DISABLED_TestConnectWithClosedSocket) {
 
62
#else
 
63
TEST_F(PhysicalSocketTest, TestConnectWithClosedSocket) {
 
64
#endif
 
65
  SocketTest::TestConnectWithClosedSocket();
 
66
}
 
67
 
 
68
TEST_F(PhysicalSocketTest, TestServerCloseDuringConnect) {
 
69
  SocketTest::TestServerCloseDuringConnect();
 
70
}
 
71
 
 
72
TEST_F(PhysicalSocketTest, TestClientCloseDuringConnect) {
 
73
  SocketTest::TestClientCloseDuringConnect();
 
74
}
 
75
 
 
76
TEST_F(PhysicalSocketTest, TestServerClose) {
 
77
  SocketTest::TestServerClose();
 
78
}
 
79
 
 
80
TEST_F(PhysicalSocketTest, TestCloseInClosedCallback) {
 
81
  SocketTest::TestCloseInClosedCallback();
 
82
}
 
83
 
 
84
TEST_F(PhysicalSocketTest, TestSocketServerWait) {
 
85
  SocketTest::TestSocketServerWait();
 
86
}
 
87
 
 
88
TEST_F(PhysicalSocketTest, TestTcp) {
 
89
  SocketTest::TestTcp();
 
90
}
 
91
 
 
92
TEST_F(PhysicalSocketTest, TestUdp) {
 
93
  SocketTest::TestUdp();
 
94
}
 
95
 
 
96
TEST_F(PhysicalSocketTest, TestGetSetOptions) {
 
97
  SocketTest::TestGetSetOptions();
 
98
}
 
99
 
 
100
#ifdef POSIX
 
101
 
 
102
class PosixSignalDeliveryTest : public testing::Test {
 
103
 public:
 
104
  static void RecordSignal(int signum) {
 
105
    signals_received_.push_back(signum);
 
106
    signaled_thread_ = Thread::Current();
 
107
  }
 
108
 
 
109
 protected:
 
110
  void SetUp() {
 
111
    ss_.reset(new PhysicalSocketServer());
 
112
  }
 
113
 
 
114
  void TearDown() {
 
115
    ss_.reset(NULL);
 
116
    signals_received_.clear();
 
117
    signaled_thread_ = NULL;
 
118
  }
 
119
 
 
120
  bool ExpectSignal(int signum) {
 
121
    if (signals_received_.empty()) {
 
122
      LOG(LS_ERROR) << "ExpectSignal(): No signal received";
 
123
      return false;
 
124
    }
 
125
    if (signals_received_[0] != signum) {
 
126
      LOG(LS_ERROR) << "ExpectSignal(): Received signal " <<
 
127
          signals_received_[0] << ", expected " << signum;
 
128
      return false;
 
129
    }
 
130
    signals_received_.erase(signals_received_.begin());
 
131
    return true;
 
132
  }
 
133
 
 
134
  bool ExpectNone() {
 
135
    bool ret = signals_received_.empty();
 
136
    if (!ret) {
 
137
      LOG(LS_ERROR) << "ExpectNone(): Received signal " << signals_received_[0]
 
138
          << ", expected none";
 
139
    }
 
140
    return ret;
 
141
  }
 
142
 
 
143
  static std::vector<int> signals_received_;
 
144
  static Thread *signaled_thread_;
 
145
 
 
146
  scoped_ptr<PhysicalSocketServer> ss_;
 
147
};
 
148
 
 
149
std::vector<int> PosixSignalDeliveryTest::signals_received_;
 
150
Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL;
 
151
 
 
152
// Test receiving a synchronous signal while not in Wait() and then entering
 
153
// Wait() afterwards.
 
154
TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
 
155
  ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
 
156
  raise(SIGTERM);
 
157
  EXPECT_TRUE(ss_->Wait(0, true));
 
158
  EXPECT_TRUE(ExpectSignal(SIGTERM));
 
159
  EXPECT_TRUE(ExpectNone());
 
160
}
 
161
 
 
162
// Test that we can handle getting tons of repeated signals and that we see all
 
163
// the different ones.
 
164
TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) {
 
165
  ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
 
166
  ss_->SetPosixSignalHandler(SIGINT, &RecordSignal);
 
167
  for (int i = 0; i < 10000; ++i) {
 
168
    raise(SIGTERM);
 
169
  }
 
170
  raise(SIGINT);
 
171
  EXPECT_TRUE(ss_->Wait(0, true));
 
172
  // Order will be lowest signal numbers first.
 
173
  EXPECT_TRUE(ExpectSignal(SIGINT));
 
174
  EXPECT_TRUE(ExpectSignal(SIGTERM));
 
175
  EXPECT_TRUE(ExpectNone());
 
176
}
 
177
 
 
178
// Test that a signal during a Wait() call is detected.
 
179
TEST_F(PosixSignalDeliveryTest, SignalDuringWait) {
 
180
  ss_->SetPosixSignalHandler(SIGALRM, &RecordSignal);
 
181
  alarm(1);
 
182
  EXPECT_TRUE(ss_->Wait(1500, true));
 
183
  EXPECT_TRUE(ExpectSignal(SIGALRM));
 
184
  EXPECT_TRUE(ExpectNone());
 
185
}
 
186
 
 
187
class RaiseSigTermRunnable : public Runnable {
 
188
  void Run(Thread *thread) {
 
189
    thread->socketserver()->Wait(1000, false);
 
190
 
 
191
    // Allow SIGTERM. This will be the only thread with it not masked so it will
 
192
    // be delivered to us.
 
193
    sigset_t mask;
 
194
    sigemptyset(&mask);
 
195
    pthread_sigmask(SIG_SETMASK, &mask, NULL);
 
196
 
 
197
    // Raise it.
 
198
    raise(SIGTERM);
 
199
  }
 
200
};
 
201
 
 
202
// Test that it works no matter what thread the kernel chooses to give the
 
203
// signal to (since it's not guaranteed to be the one that Wait() runs on).
 
204
TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) {
 
205
  ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
 
206
  // Mask out SIGTERM so that it can't be delivered to this thread.
 
207
  sigset_t mask;
 
208
  sigemptyset(&mask);
 
209
  sigaddset(&mask, SIGTERM);
 
210
  EXPECT_EQ(0, pthread_sigmask(SIG_SETMASK, &mask, NULL));
 
211
  // Start a new thread that raises it. It will have to be delivered to that
 
212
  // thread. Our implementation should safely handle it and dispatch
 
213
  // RecordSignal() on this thread.
 
214
  scoped_ptr<Thread> thread(new Thread());
 
215
  thread->Start(new RaiseSigTermRunnable());
 
216
  EXPECT_TRUE(ss_->Wait(1500, true));
 
217
  EXPECT_TRUE(ExpectSignal(SIGTERM));
 
218
  EXPECT_EQ(Thread::Current(), signaled_thread_);
 
219
  EXPECT_TRUE(ExpectNone());
 
220
}
 
221
 
 
222
#endif
 
223
 
 
224
}  // namespace talk_base