TEST(ProcessTest, Remote) { ASSERT_TRUE(GTEST_IS_THREADSAFE); RemoteProcess process; spawn(process); Future<Nothing> handler; EXPECT_CALL(process, handler(_, _)) .WillOnce(FutureSatisfy(&handler)); Try<Socket> create = Socket::create(); ASSERT_SOME(create); Socket socket = create.get(); AWAIT_READY(socket.connect(process.self().address)); Message message; message.name = "handler"; message.from = UPID(); message.to = process.self(); const string data = MessageEncoder::encode(&message); AWAIT_READY(socket.send(data)); AWAIT_READY(handler); terminate(process); wait(process); }
// Like the 'remote' test but uses http::connect. TEST(ProcessTest, Http1) { ASSERT_TRUE(GTEST_IS_THREADSAFE); RemoteProcess process; spawn(process); http::URL url = http::URL( "http", process.self().address.ip, process.self().address.port, process.self().id + "/handler"); Future<http::Connection> connect = http::connect(url); AWAIT_READY(connect); http::Connection connection = connect.get(); Future<UPID> pid; Future<string> body; EXPECT_CALL(process, handler(_, _)) .WillOnce(DoAll(FutureArg<0>(&pid), FutureArg<1>(&body))); http::Request request; request.method = "POST"; request.url = url; request.headers["User-Agent"] = "libprocess/"; request.body = "hello world"; // Send the libprocess request. Note that we will not // receive a 202 due to the use of the `User-Agent` // header, therefore we need to explicitly disconnect! Future<http::Response> response = connection.send(request); AWAIT_READY(body); ASSERT_EQ("hello world", body.get()); AWAIT_READY(pid); ASSERT_EQ(UPID(), pid.get()); EXPECT_TRUE(response.isPending()); AWAIT_READY(connection.disconnect()); terminate(process); wait(process); }
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); }
// Like 'http1' but uses the 'Libprocess-From' header. We can // also use http::post here since we expect a 202 response. TEST(ProcessTest, Http2) { ASSERT_TRUE(GTEST_IS_THREADSAFE); RemoteProcess process; spawn(process); // Create a receiving socket so we can get messages back. Try<Socket> create = Socket::create(); ASSERT_SOME(create); Socket socket = create.get(); ASSERT_SOME(socket.bind(Address())); // Create a UPID for 'Libprocess-From' based on the IP and port we // got assigned. Try<Address> address = socket.address(); ASSERT_SOME(address); UPID from("", address.get()); ASSERT_SOME(socket.listen(1)); Future<UPID> pid; Future<string> body; EXPECT_CALL(process, handler(_, _)) .WillOnce(DoAll(FutureArg<0>(&pid), FutureArg<1>(&body))); http::Headers headers; headers["Libprocess-From"] = stringify(from); Future<http::Response> response = http::post(process.self(), "handler", headers, "hello world"); AWAIT_READY(response); ASSERT_EQ(http::Status::ACCEPTED, response->code); ASSERT_EQ(http::Status::string(http::Status::ACCEPTED), response->status); AWAIT_READY(body); ASSERT_EQ("hello world", body.get()); AWAIT_READY(pid); ASSERT_EQ(from, pid.get()); // Now post a message as though it came from the process. const string name = "reply"; post(process.self(), from, name); // Accept the incoming connection. Future<Socket> accept = socket.accept(); AWAIT_READY(accept); Socket client = accept.get(); const string data = "POST /" + name + " HTTP/1.1"; AWAIT_EXPECT_EQ(data, client.recv(data.size())); terminate(process); wait(process); }