TEST(ProcessTest, Executor) { ASSERT_TRUE(GTEST_IS_THREADSAFE); std::atomic_bool event1Called(false); std::atomic_bool event2Called(false); EventReceiver receiver; EXPECT_CALL(receiver, event1(42)) .WillOnce(Assign(&event1Called, true)); EXPECT_CALL(receiver, event2("event2")) .WillOnce(Assign(&event2Called, true)); Executor executor; Deferred<void(int)> event1 = executor.defer([&receiver](int i) { return receiver.event1(i); }); event1(42); Deferred<void(const string&)> event2 = executor.defer([&receiver](const string& s) { return receiver.event2(s); }); event2("event2"); while (event1Called.load() == false); while (event2Called.load() == false); }
TEST(Process, executor) { ASSERT_TRUE(GTEST_IS_THREADSAFE); volatile bool event1Called = false; volatile bool event2Called = false; EventReceiver receiver; EXPECT_CALL(receiver, event1(42)) .WillOnce(Assign(&event1Called, true)); EXPECT_CALL(receiver, event2("event2")) .WillOnce(Assign(&event2Called, true)); Executor executor; deferred<void(int)> event1 = executor.defer(std::tr1::bind(&EventReceiver::event1, &receiver, std::tr1::placeholders::_1)); event1(42); deferred<void(const std::string&)> event2 = executor.defer(std::tr1::bind(&EventReceiver::event2, &receiver, std::tr1::placeholders::_1)); event2("event2"); while (!event1Called); while (!event2Called); }
TEST(ProcessTest, Delay) { ASSERT_TRUE(GTEST_IS_THREADSAFE); Clock::pause(); std::atomic_bool timeoutCalled(false); TimeoutProcess process; EXPECT_CALL(process, timeout()) .WillOnce(Assign(&timeoutCalled, true)); spawn(process); delay(Seconds(5), process.self(), &TimeoutProcess::timeout); Clock::advance(Seconds(5)); while (timeoutCalled.load() == false); terminate(process); wait(process); Clock::resume(); }
TEST(Process, delay) { ASSERT_TRUE(GTEST_IS_THREADSAFE); Clock::pause(); volatile bool timeoutCalled = false; TimeoutProcess process; EXPECT_CALL(process, timeout()) .WillOnce(Assign(&timeoutCalled, true)); spawn(process); double seconds = 5.0; delay(seconds, process.self(), &TimeoutProcess::timeout); Clock::advance(seconds); while (!timeoutCalled); terminate(process); wait(process); Clock::resume(); }
TEST(Process, remote) { ASSERT_TRUE(GTEST_IS_THREADSAFE); RemoteProcess process; volatile bool handlerCalled = false; EXPECT_CALL(process, handler(_, _)) .WillOnce(Assign(&handlerCalled, true)); spawn(process); int s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); ASSERT_LE(0, s); sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = PF_INET; addr.sin_port = htons(process.self().port); addr.sin_addr.s_addr = process.self().ip; ASSERT_EQ(0, connect(s, (sockaddr*) &addr, sizeof(addr))); Message message; message.name = "handler"; message.from = UPID(); message.to = process.self(); const std::string& data = MessageEncoder::encode(&message); ASSERT_EQ(data.size(), write(s, data.data(), data.size())); ASSERT_EQ(0, close(s)); while (!handlerCalled); terminate(process); wait(process); }
TEST(ProcessTest, Order) { ASSERT_TRUE(GTEST_IS_THREADSAFE); Clock::pause(); TimeoutProcess process1; std::atomic_bool timeoutCalled(false); EXPECT_CALL(process1, timeout()) .WillOnce(Assign(&timeoutCalled, true)); spawn(process1); Time now = Clock::now(&process1); Seconds seconds(1); Clock::advance(Seconds(1)); EXPECT_EQ(now, Clock::now(&process1)); OrderProcess process2; spawn(process2); dispatch(process2, &OrderProcess::order, process1.self()); while (timeoutCalled.load() == false); EXPECT_EQ(now + seconds, Clock::now(&process1)); terminate(process1); wait(process1); terminate(process2); wait(process2); Clock::resume(); }
TEST(Process, order) { ASSERT_TRUE(GTEST_IS_THREADSAFE); Clock::pause(); TimeoutProcess process1; volatile bool timeoutCalled = false; EXPECT_CALL(process1, timeout()) .WillOnce(Assign(&timeoutCalled, true)); spawn(process1); double now = Clock::now(&process1); double seconds = 1.0; Clock::advance(1.0); EXPECT_EQ(now, Clock::now(&process1)); OrderProcess process2; spawn(process2); dispatch(process2, &OrderProcess::order, process1.self()); while (!timeoutCalled); EXPECT_EQ(now + seconds, Clock::now(&process1)); terminate(process1); wait(process1); terminate(process2); wait(process2); Clock::resume(); }
TEST(ProcessTest, InjectExited) { ASSERT_TRUE(GTEST_IS_THREADSAFE); UPID pid = spawn(new ProcessBase(), true); ExitedProcess process(pid); std::atomic_bool exitedCalled(false); EXPECT_CALL(process, exited(pid)) .WillOnce(Assign(&exitedCalled, true)); spawn(process); inject::exited(pid, process.self()); while (exitedCalled.load() == false); terminate(process); wait(process); }
TEST(Process, exited) { ASSERT_TRUE(GTEST_IS_THREADSAFE); UPID pid = spawn(new ProcessBase(), true); ExitedProcess process(pid); volatile bool exitedCalled = false; EXPECT_CALL(process, exited(pid)) .WillOnce(Assign(&exitedCalled, true)); spawn(process); terminate(pid); while (!exitedCalled); terminate(process); wait(process); }
TEST(HTTP, Endpoints) { ASSERT_TRUE(GTEST_IS_THREADSAFE); HttpProcess process; spawn(process); // First hit '/body' (using explicit sockets and HTTP/1.0). int s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); ASSERT_LE(0, s); sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = PF_INET; addr.sin_port = htons(process.self().port); addr.sin_addr.s_addr = process.self().ip; ASSERT_EQ(0, connect(s, (sockaddr*) &addr, sizeof(addr))); std::ostringstream out; out << "GET /" << process.self().id << "/body" << " HTTP/1.0\r\n" << "Connection: Keep-Alive\r\n" << "\r\n"; const std::string& data = out.str(); EXPECT_CALL(process, body(_)) .WillOnce(Return(http::OK())); ASSERT_EQ(data.size(), write(s, data.data(), data.size())); std::string response = "HTTP/1.1 200 OK"; char temp[response.size()]; ASSERT_LT(0, read(s, temp, response.size())); ASSERT_EQ(response, std::string(temp, response.size())); ASSERT_EQ(0, close(s)); // Now hit '/pipe' (by using http::get). int pipes[2]; ASSERT_NE(-1, ::pipe(pipes)); http::OK ok; ok.type = http::Response::PIPE; ok.pipe = pipes[0]; volatile bool pipeCalled = false; EXPECT_CALL(process, pipe(_)) .WillOnce(DoAll(Assign(&pipeCalled, true), Return(ok))); Future<http::Response> future = http::get(process.self(), "pipe"); while (!pipeCalled); ASSERT_TRUE(os::write(pipes[1], "Hello World\n").isSome()); ASSERT_TRUE(os::close(pipes[1]).isSome()); future.await(Seconds(1.0)); ASSERT_TRUE(future.isReady()); ASSERT_EQ(http::statuses[200], future.get().status); ASSERT_EQ("chunked", future.get().headers["Transfer-Encoding"]); ASSERT_EQ("Hello World\n", future.get().body); terminate(process); wait(process); }