Commit 6beb5910 authored by Kenton Varda's avatar Kenton Varda

Work around OSX and Cygwin signal issues.

parent b483b77b
......@@ -45,7 +45,10 @@ inline void delay() { usleep(10000); }
class AsyncUnixTest: public testing::Test {
public:
static void SetUpTestCase() {
UnixEventPort::captureSignal(SIGUSR2);
// We use SIGIO and SIGURG as our test signals because they're two signals that we can be
// reasonably confident won't otherwise be delivered to any KJ or Cap'n Proto test. We can't
// use SIGUSR1 because it is reserved by UnixEventPort and SIGUSR2 is used by Valgrind on OSX.
UnixEventPort::captureSignal(SIGURG);
UnixEventPort::captureSignal(SIGIO);
}
};
......@@ -55,10 +58,10 @@ TEST_F(AsyncUnixTest, Signals) {
EventLoop loop(port);
WaitScope waitScope(loop);
kill(getpid(), SIGUSR2);
kill(getpid(), SIGURG);
siginfo_t info = port.onSignal(SIGUSR2).wait(waitScope);
EXPECT_EQ(SIGUSR2, info.si_signo);
siginfo_t info = port.onSignal(SIGURG).wait(waitScope);
EXPECT_EQ(SIGURG, info.si_signo);
EXPECT_SI_CODE(SI_USER, info.si_code);
}
......@@ -66,7 +69,7 @@ TEST_F(AsyncUnixTest, Signals) {
TEST_F(AsyncUnixTest, SignalWithValue) {
// This tests that if we use sigqueue() to attach a value to the signal, that value is received
// correctly. Note that this only works on platforms that support real-time signals -- even
// though the signal we're sending is SIGUSR2, the sigqueue() system call is introduced by RT
// though the signal we're sending is SIGURG, the sigqueue() system call is introduced by RT
// signals. Hence this test won't run on e.g. Mac OSX.
UnixEventPort port;
......@@ -76,10 +79,10 @@ TEST_F(AsyncUnixTest, SignalWithValue) {
union sigval value;
memset(&value, 0, sizeof(value));
value.sival_int = 123;
sigqueue(getpid(), SIGUSR2, value);
sigqueue(getpid(), SIGURG, value);
siginfo_t info = port.onSignal(SIGUSR2).wait(waitScope);
EXPECT_EQ(SIGUSR2, info.si_signo);
siginfo_t info = port.onSignal(SIGURG).wait(waitScope);
EXPECT_EQ(SIGURG, info.si_signo);
EXPECT_SI_CODE(SI_QUEUE, info.si_code);
EXPECT_EQ(123, info.si_value.sival_int);
}
......@@ -96,23 +99,28 @@ TEST_F(AsyncUnixTest, SignalsMultiListen) {
ADD_FAILURE() << kj::str(exception).cStr();
});
kill(getpid(), SIGUSR2);
kill(getpid(), SIGURG);
siginfo_t info = port.onSignal(SIGUSR2).wait(waitScope);
EXPECT_EQ(SIGUSR2, info.si_signo);
siginfo_t info = port.onSignal(SIGURG).wait(waitScope);
EXPECT_EQ(SIGURG, info.si_signo);
EXPECT_SI_CODE(SI_USER, info.si_code);
}
#if !__CYGWIN32__
// Cygwin32 (but not Cygwin64) appears not to deliver SIGURG in the following test (but it does
// deliver SIGIO, if you reverse the order of the waits). Since this doesn't occur on any other
// platform I'm assuming it's a Cygwin bug.
TEST_F(AsyncUnixTest, SignalsMultiReceive) {
UnixEventPort port;
EventLoop loop(port);
WaitScope waitScope(loop);
kill(getpid(), SIGUSR2);
kill(getpid(), SIGURG);
kill(getpid(), SIGIO);
siginfo_t info = port.onSignal(SIGUSR2).wait(waitScope);
EXPECT_EQ(SIGUSR2, info.si_signo);
siginfo_t info = port.onSignal(SIGURG).wait(waitScope);
EXPECT_EQ(SIGURG, info.si_signo);
EXPECT_SI_CODE(SI_USER, info.si_code);
info = port.onSignal(SIGIO).wait(waitScope);
......@@ -120,6 +128,8 @@ TEST_F(AsyncUnixTest, SignalsMultiReceive) {
EXPECT_SI_CODE(SI_USER, info.si_code);
}
#endif // !__CYGWIN32__
TEST_F(AsyncUnixTest, SignalsAsync) {
UnixEventPort port;
EventLoop loop(port);
......@@ -129,16 +139,21 @@ TEST_F(AsyncUnixTest, SignalsAsync) {
pthread_t mainThread = pthread_self();
Thread thread([&]() {
delay();
pthread_kill(mainThread, SIGUSR2);
pthread_kill(mainThread, SIGURG);
});
siginfo_t info = port.onSignal(SIGUSR2).wait(waitScope);
EXPECT_EQ(SIGUSR2, info.si_signo);
siginfo_t info = port.onSignal(SIGURG).wait(waitScope);
EXPECT_EQ(SIGURG, info.si_signo);
#if __linux__
EXPECT_SI_CODE(SI_TKILL, info.si_code);
#endif
}
#if !__CYGWIN32__
// Cygwin32 (but not Cygwin64) appears not to deliver SIGURG in the following test (but it does
// deliver SIGIO, if you reverse the order of the waits). Since this doesn't occur on any other
// platform I'm assuming it's a Cygwin bug.
TEST_F(AsyncUnixTest, SignalsNoWait) {
// Verify that UnixEventPort::poll() correctly receives pending signals.
......@@ -146,11 +161,11 @@ TEST_F(AsyncUnixTest, SignalsNoWait) {
EventLoop loop(port);
WaitScope waitScope(loop);
bool receivedSigusr2 = false;
bool receivedSigurg = false;
bool receivedSigio = false;
port.onSignal(SIGUSR2).then([&](siginfo_t&& info) {
receivedSigusr2 = true;
EXPECT_EQ(SIGUSR2, info.si_signo);
port.onSignal(SIGURG).then([&](siginfo_t&& info) {
receivedSigurg = true;
EXPECT_EQ(SIGURG, info.si_signo);
EXPECT_SI_CODE(SI_USER, info.si_code);
}).detach([](Exception&& e) { ADD_FAILURE() << str(e).cStr(); });
port.onSignal(SIGIO).then([&](siginfo_t&& info) {
......@@ -159,28 +174,30 @@ TEST_F(AsyncUnixTest, SignalsNoWait) {
EXPECT_SI_CODE(SI_USER, info.si_code);
}).detach([](Exception&& e) { ADD_FAILURE() << str(e).cStr(); });
kill(getpid(), SIGUSR2);
kill(getpid(), SIGURG);
kill(getpid(), SIGIO);
EXPECT_FALSE(receivedSigusr2);
EXPECT_FALSE(receivedSigurg);
EXPECT_FALSE(receivedSigio);
loop.run();
EXPECT_FALSE(receivedSigusr2);
EXPECT_FALSE(receivedSigurg);
EXPECT_FALSE(receivedSigio);
port.poll();
EXPECT_FALSE(receivedSigusr2);
EXPECT_FALSE(receivedSigurg);
EXPECT_FALSE(receivedSigio);
loop.run();
EXPECT_TRUE(receivedSigusr2);
EXPECT_TRUE(receivedSigurg);
EXPECT_TRUE(receivedSigio);
}
#endif // !__CYGWIN32__
TEST_F(AsyncUnixTest, Poll) {
UnixEventPort port;
EventLoop loop(port);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment