Add Linux Hafnium module socket unit test
Add a Linux module unit test that covers more cases than the basic load/unload.
This test create a secondary VM, and using the socket interface sends a message
and received the same payload as a response.
Bug: 138977432
Change-Id: Ibbc313c1a788924b2f227a28bf0ecd3bf21304a1
diff --git a/test/linux/linux.c b/test/linux/linux.c
index 3300799..f0798e9 100644
--- a/test/linux/linux.c
+++ b/test/linux/linux.c
@@ -14,13 +14,23 @@
* limitations under the License.
*/
+#include <errno.h>
#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include "hf/dlog.h"
+#include "hf/socket.h"
#include "hftest.h"
+#include <sys/socket.h>
#include <sys/syscall.h>
+#include <sys/types.h>
+
+#define MAX_BUF_SIZE 256
static int finit_module(int fd, const char *param_values, int flags)
{
@@ -48,8 +58,75 @@
EXPECT_EQ(delete_module("hafnium", 0), 0);
}
+/**
+ * Loads and unloads the Hafnium kernel module.
+ */
TEST(linux, load_hafnium)
{
insmod_hafnium();
rmmod_hafnium();
}
+
+/**
+ * Uses the kernel module to send a socket message from the primary VM to a
+ * secondary VM and echoes it back to the primary.
+ */
+TEST(linux, socket_echo_hafnium)
+{
+ spci_vm_id_t vm_id = HF_VM_ID_OFFSET + 1;
+ int port = 10;
+ int socket_id;
+ struct hf_sockaddr addr;
+ const char send_buf[] = "The quick brown fox jumps over the lazy dogs.";
+ size_t send_len = strlen(send_buf);
+ char resp_buf[MAX_BUF_SIZE];
+ ssize_t recv_len;
+
+ ASSERT_LT(send_len, MAX_BUF_SIZE);
+
+ insmod_hafnium();
+
+ /* Create Hafnium socket. */
+ socket_id = socket(PF_HF, SOCK_DGRAM, 0);
+ if (socket_id == -1) {
+ FAIL("Socket creation failed: %s", strerror(errno));
+ return;
+ }
+ HFTEST_LOG("Socket created successfully.");
+
+ /* Connect to requested VM & port. */
+ addr.family = PF_HF;
+ addr.vm_id = vm_id;
+ addr.port = port;
+ if (connect(socket_id, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+ FAIL("Socket connection failed: %s", strerror(errno));
+ return;
+ }
+ HFTEST_LOG("Socket to secondary VM %d connected on port %d.", vm_id,
+ port);
+
+ /*
+ * Send a message to the secondary VM.
+ * Enable the confirm flag to try again in case port is busy.
+ */
+ if (send(socket_id, send_buf, send_len, MSG_CONFIRM) < 0) {
+ FAIL("Socket send() failed: %s", strerror(errno));
+ return;
+ }
+ HFTEST_LOG("Packet with length %d sent.", send_len);
+
+ /* Receive a response, which should be an echo of the sent packet. */
+ recv_len = recv(socket_id, resp_buf, sizeof(resp_buf) - 1, 0);
+
+ if (recv_len == -1) {
+ FAIL("Socket recv() failed: %s", strerror(errno));
+ return;
+ }
+ HFTEST_LOG("Packet with length %d received.", recv_len);
+
+ EXPECT_EQ(recv_len, send_len);
+ EXPECT_EQ(memcmp(send_buf, resp_buf, send_len), 0);
+
+ EXPECT_EQ(close(socket_id), 0);
+ rmmod_hafnium();
+}