vsock_test: Wait for ACK from server
vsock_test has been flaky - the test in host would receive ECONNRESET
when reading from the client's vsock socket. This was due to the guest
exiting immediately after writing to the socket. This in turn terminated
crosvm, including the vhost-vsock backend, and reset the socket.
Fix this by having the guest wait for a reply from the host before
shutting down and explicitly shutting down the connection.
Bug: 238733740
Test: atest VirtualizationTestCases.64
Change-Id: I36c678f469fc3269902f5d8b1eb73cd431661ae6
diff --git a/tests/vsock_guest.cc b/tests/vsock_guest.cc
index 7a72e11..884c8a4 100644
--- a/tests/vsock_guest.cc
+++ b/tests/vsock_guest.cc
@@ -62,6 +62,16 @@
PLOG(ERROR) << "WriteStringToFd";
return EXIT_FAILURE;
}
+ shutdown(fd.get(), SHUT_WR); // close socket for writing
+
+ // Must not shut down until the server ACKs the message. Shutting down
+ // the VM would otherwise terminate the VMM and reset the server's socket.
+ LOG(INFO) << "Waiting for ACK from the server...";
+ if (!ReadFdToString(fd, &msg)) {
+ PLOG(ERROR) << "ReadFdToString";
+ return EXIT_FAILURE;
+ }
+ shutdown(fd.get(), SHUT_RD); // close socket for reading
LOG(INFO) << "Exiting...";
return EXIT_SUCCESS;
diff --git a/tests/vsock_test.cc b/tests/vsock_test.cc
index 0fc451d..1460660 100644
--- a/tests/vsock_test.cc
+++ b/tests/vsock_test.cc
@@ -48,6 +48,7 @@
static constexpr const char kVmInitrdPath[] = "/data/local/tmp/virt-test/initramfs";
static constexpr const char kVmParams[] = "rdinit=/bin/init bin/vsock_client 2 45678 HelloWorld";
static constexpr const char kTestMessage[] = "HelloWorld";
+static constexpr const char kAckMessage[] = "ACK";
static constexpr const char kPlatformVersion[] = "~1.0";
/** Returns true if the kernel supports unprotected VMs. */
@@ -108,9 +109,13 @@
LOG(INFO) << "Reading message from the client...";
std::string msg;
- ASSERT_TRUE(ReadFdToString(client_fd, &msg));
-
+ ASSERT_TRUE(ReadFdToString(client_fd, &msg)) << strerror(errno);
LOG(INFO) << "Received message: " << msg;
+
+ // The client is waiting for a response to signal it can shut down.
+ LOG(INFO) << "Replying with '" << kAckMessage << "'...";
+ ASSERT_TRUE(WriteStringToFd(kAckMessage, client_fd));
+
ASSERT_EQ(msg, kTestMessage);
}