common: compile libcompat as C++
[lttng-tools.git] / tests / unit / test_unix_socket.c
diff --git a/tests/unit/test_unix_socket.c b/tests/unit/test_unix_socket.c
deleted file mode 100644 (file)
index 8752ba9..0000000
+++ /dev/null
@@ -1,682 +0,0 @@
-/*
- * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- */
-
-#include <common/compat/fcntl.h>
-#include <common/sessiond-comm/sessiond-comm.h>
-#include <common/payload.h>
-#include <common/payload-view.h>
-#include <common/unix.h>
-#include <common/utils.h>
-#include <common/defaults.h>
-#include <tap/tap.h>
-#include <stdbool.h>
-#include <common/error.h>
-#include <lttng/constant.h>
-#include <stdio.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <sys/wait.h>
-#include <stdlib.h>
-
-#define HIGH_FD_COUNT LTTCOMM_MAX_SEND_FDS
-#define MESSAGE_COUNT 4
-#define LARGE_PAYLOAD_SIZE 4 * 1024
-#define LARGE_PAYLOAD_RECV_SIZE        100
-
-static const int TEST_COUNT = 37;
-
-/* For error.h */
-int lttng_opt_quiet;
-int lttng_opt_verbose;
-int lttng_opt_mi;
-
-/*
- * Validate that a large number of file descriptors can be received in one shot.
- */
-static void test_high_fd_count(unsigned int fd_count)
-{
-       int sockets[2] = {-1, -1};
-       int ret;
-       unsigned int i;
-       const unsigned int payload_content = 42;
-       struct lttng_payload sent_payload;
-       struct lttng_payload received_payload;
-
-       diag("Send and receive high FD count atomically (%u FDs)", fd_count);
-       lttng_payload_init(&sent_payload);
-       lttng_payload_init(&received_payload);
-
-       ret = lttcomm_create_anon_unix_socketpair(sockets);
-       ok(ret == 0, "Created anonymous unix socket pair");
-       if (ret < 0) {
-               PERROR("Failed to create an anonymous pair of unix sockets");
-               goto error;
-       }
-
-       /* Add dummy content to payload. */
-       ret = lttng_dynamic_buffer_append(&sent_payload.buffer,
-                       &payload_content, sizeof(payload_content));
-       if (ret) {
-               PERROR("Failed to initialize test payload");
-               goto error;
-       }
-
-       for (i = 0; i < fd_count; i++) {
-               struct fd_handle *handle;
-               int fd = fcntl(STDOUT_FILENO, F_DUPFD, 0);
-
-               if (fd < 0) {
-                       PERROR("Failed to create fd while creating test payload");
-                       goto error;
-               }
-
-               handle = fd_handle_create(fd);
-               if (!handle) {
-                       if (close(fd)) {
-                               PERROR("Failed to close fd while preparing test payload");
-                               goto error;
-                       }
-               }
-
-               ret = lttng_payload_push_fd_handle(&sent_payload, handle);
-               fd_handle_put(handle);
-               if (ret) {
-                       PERROR("Failed to add fd handle to test payload");
-                       goto error;
-               }
-       }
-
-       /* Send payload. */
-       {
-               ssize_t sock_ret;
-               struct lttng_payload_view pv = lttng_payload_view_from_payload(
-                               &sent_payload, 0, -1);
-
-               /* Not expected to block considering the size of the payload. */
-               sock_ret = lttcomm_send_unix_sock(
-                               sockets[0], pv.buffer.data, pv.buffer.size);
-               ok(sock_ret == pv.buffer.size, "Sent complete test payload");
-               if (sock_ret != pv.buffer.size) {
-                       ERR("Failed to send test payload bytes: ret = %zd, expected = %zu",
-                                       sock_ret, pv.buffer.size);
-                       goto error;
-               }
-
-               sock_ret = lttcomm_send_payload_view_fds_unix_sock(
-                               sockets[0], &pv);
-               ok(sock_ret == 1, "Sent test payload file descriptors");
-               if (sock_ret != 1) {
-                       if (sock_ret < 0) {
-                               PERROR("Failed to send test payload file descriptors: ret = %zd, expected = %d",
-                                               sock_ret, 1);
-                       } else {
-                               diag("Failed to send test payload file descriptors: ret = %zd, expected = %d",
-                                               sock_ret, 1);
-                       }
-
-                       goto error;
-               }
-       }
-
-       /* Receive payload */
-       {
-               ssize_t sock_ret;
-
-               ret = lttng_dynamic_buffer_set_size(&received_payload.buffer,
-                               sent_payload.buffer.size);
-               if (ret) {
-                       PERROR("Failed to pre-allocate reception buffer");
-                       goto error;
-               }
-
-               sock_ret = lttcomm_recv_unix_sock(sockets[1],
-                               received_payload.buffer.data,
-                               received_payload.buffer.size);
-               ok(sock_ret == received_payload.buffer.size,
-                               "Received payload bytes");
-               if (sock_ret != received_payload.buffer.size) {
-                       ERR("Failed to receive payload bytes: ret = %zd, expected = %zu",
-                                       sock_ret, received_payload.buffer.size);
-                       goto error;
-               }
-
-               sock_ret = lttcomm_recv_payload_fds_unix_sock(
-                               sockets[1], fd_count, &received_payload);
-               ok(sock_ret == (int) (sizeof(int) * fd_count),
-                               "FD reception return value is number of fd * sizeof(int)");
-               if (sock_ret != (int) (sizeof(int) * fd_count)) {
-                       ERR("Failed to receive test payload file descriptors: ret = %zd, expected = %d",
-                                       sock_ret,
-                                       (int) (fd_count * sizeof(int)));
-                       goto error;
-               }
-
-               {
-                       const struct lttng_payload_view pv =
-                                       lttng_payload_view_from_payload(
-                                                       &received_payload, 0,
-                                                       -1);
-                       const int fd_handle_count =
-                                       lttng_payload_view_get_fd_handle_count(
-                                                       &pv);
-
-                       ok(fd_handle_count == fd_count,
-                                       "Received all test payload file descriptors in one invocation");
-               }
-       }
-
-error:
-       for (i = 0; i < 2; i++) {
-               if (sockets[i] < 0) {
-                       continue;
-               }
-
-               if (close(sockets[i])) {
-                       PERROR("Failed to close unix socket");
-               }
-       }
-
-       lttng_payload_reset(&sent_payload);
-       lttng_payload_reset(&received_payload);
-}
-
-/*
- * Validate that if the sender sent multiple messages, each containing 1 fd,
- * the receiver can receive one message at a time (the binary payload and its
- * fd) and is not forced to receive all file descriptors at once.
- */
-static void test_one_fd_per_message(unsigned int message_count)
-{
-       const unsigned int payload_content = 42;
-       int sockets[2] = {-1, -1};
-       int ret;
-       unsigned int i;
-       struct lttng_payload sent_payload;
-       struct lttng_payload received_payload;
-
-       diag("Send and receive small messages with one FD each (%u messages)",
-                       message_count);
-       lttng_payload_init(&sent_payload);
-       lttng_payload_init(&received_payload);
-
-       ret = lttcomm_create_anon_unix_socketpair(sockets);
-       ok(ret == 0, "Created anonymous unix socket pair");
-       if (ret < 0) {
-               PERROR("Failed to create an anonymous pair of unix sockets");
-               goto error;
-       }
-
-       /* Send messages with one fd each. */
-       for (i = 0; i < message_count; i++) {
-               struct fd_handle *handle;
-               int fd;
-
-               /* Add dummy content to payload. */
-               ret = lttng_dynamic_buffer_append(&sent_payload.buffer,
-                               &payload_content, sizeof(payload_content));
-               if (ret) {
-                       PERROR("Failed to initialize test payload");
-                       goto error;
-               }
-
-               fd = fcntl(STDOUT_FILENO, F_DUPFD, 0);
-               if (fd < 0) {
-                       PERROR("Failed to create fd while creating test payload");
-                       goto error;
-               }
-
-               handle = fd_handle_create(fd);
-               if (!handle) {
-                       if (close(fd)) {
-                               PERROR("Failed to close fd while preparing test payload");
-                               goto error;
-                       }
-               }
-
-               ret = lttng_payload_push_fd_handle(&sent_payload, handle);
-               fd_handle_put(handle);
-               if (ret) {
-                       PERROR("Failed to add fd handle to test payload");
-                       goto error;
-               }
-
-               /* Send payload. */
-               {
-                       ssize_t sock_ret;
-                       struct lttng_payload_view pv =
-                                       lttng_payload_view_from_payload(
-                                                       &sent_payload, 0, -1);
-
-                       /* Not expected to block considering the size of the
-                        * payload. */
-                       sock_ret = lttcomm_send_unix_sock(sockets[0],
-                                       pv.buffer.data, pv.buffer.size);
-                       ok(sock_ret == pv.buffer.size,
-                                       "Sent binary payload for message %u",
-                                       i);
-                       if (sock_ret != pv.buffer.size) {
-                               ERR("Failed to send test payload bytes: ret = %zd, expected = %zu",
-                                               sock_ret, pv.buffer.size);
-                               goto error;
-                       }
-
-                       sock_ret = lttcomm_send_payload_view_fds_unix_sock(
-                                       sockets[0], &pv);
-                       ok(sock_ret == 1,
-                                       "Sent file descriptors payload for message %u",
-                                       i);
-                       if (sock_ret != 1) {
-                               if (sock_ret < 0) {
-                                       PERROR("Failed to send test payload file descriptors: ret = %zd, expected = %d",
-                                                       sock_ret, 1);
-                               } else {
-                                       diag("Failed to send test payload file descriptors: ret = %zd, expected = %d",
-                                                       sock_ret, 1);
-                               }
-
-                               goto error;
-                       }
-               }
-
-               lttng_payload_clear(&sent_payload);
-       }
-
-       /* Receive messages one at a time. */
-       for (i = 0; i < message_count; i++) {
-               ssize_t sock_ret;
-
-               ret = lttng_dynamic_buffer_set_size(&received_payload.buffer,
-                               sizeof(payload_content));
-               if (ret) {
-                       PERROR("Failed to pre-allocate reception buffer");
-                       goto error;
-               }
-
-               sock_ret = lttcomm_recv_unix_sock(sockets[1],
-                               received_payload.buffer.data,
-                               received_payload.buffer.size);
-               ok(sock_ret == received_payload.buffer.size,
-                               "Received payload bytes for message %u", i);
-               if (sock_ret != received_payload.buffer.size) {
-                       ERR("Failed to receive payload bytes: ret = %zd, expected = %zu",
-                                       sock_ret, received_payload.buffer.size);
-                       goto error;
-               }
-
-               sock_ret = lttcomm_recv_payload_fds_unix_sock(
-                               sockets[1], 1, &received_payload);
-               ok(sock_ret == (int) sizeof(int), "Received fd for message %u",
-                               i);
-               if (sock_ret != (int) sizeof(int)) {
-                       ERR("Failed to receive test payload file descriptors: ret = %zd, expected = %u",
-                                       sock_ret, (int) sizeof(int));
-                       goto error;
-               }
-
-               {
-                       const struct lttng_payload_view pv =
-                                       lttng_payload_view_from_payload(
-                                                       &received_payload, 0,
-                                                       -1);
-                       const int fd_handle_count =
-                                       lttng_payload_view_get_fd_handle_count(
-                                                       &pv);
-
-                       ok(fd_handle_count == 1,
-                                       "Payload contains 1 fd for message %u",
-                                       i);
-               }
-
-               lttng_payload_clear(&received_payload);
-       }
-
-error:
-       for (i = 0; i < 2; i++) {
-               if (sockets[i] < 0) {
-                       continue;
-               }
-
-               if (close(sockets[i])) {
-                       PERROR("Failed to close unix socket");
-               }
-       }
-
-       lttng_payload_reset(&sent_payload);
-       lttng_payload_reset(&received_payload);
-}
-
-/*
- * Validate that a large message can be received in multiple chunks.
- */
-static void test_receive_in_chunks(
-               unsigned int payload_size, unsigned int max_recv_size)
-{
-       int sockets[2] = {-1, -1};
-       int ret;
-       unsigned int i;
-       struct lttng_payload sent_payload;
-       struct lttng_payload received_payload;
-       struct fd_handle *handle;
-       int fd;
-       ssize_t sock_ret, received = 0;
-
-       diag("Receive a message in multiple chunks");
-       lttng_payload_init(&sent_payload);
-       lttng_payload_init(&received_payload);
-
-       ret = lttcomm_create_anon_unix_socketpair(sockets);
-       ok(ret == 0, "Created anonymous unix socket pair");
-       if (ret < 0) {
-               PERROR("Failed to create an anonymous pair of unix sockets");
-               goto error;
-       }
-
-       /* Add dummy content to payload. */
-       ret = lttng_dynamic_buffer_set_size(&sent_payload.buffer, payload_size);
-       if (ret) {
-               PERROR("Failed to initialize test payload");
-               goto error;
-       }
-
-       fd = fcntl(STDOUT_FILENO, F_DUPFD, 0);
-       if (fd < 0) {
-               PERROR("Failed to create fd while creating test payload");
-               goto error;
-       }
-
-       handle = fd_handle_create(fd);
-       if (!handle) {
-               if (close(fd)) {
-                       PERROR("Failed to close fd while preparing test payload");
-                       goto error;
-               }
-       }
-
-       ret = lttng_payload_push_fd_handle(&sent_payload, handle);
-       fd_handle_put(handle);
-       if (ret) {
-               PERROR("Failed to add fd handle to test payload");
-               goto error;
-       }
-
-       /* Send payload. */
-       {
-               struct lttng_payload_view pv = lttng_payload_view_from_payload(
-                               &sent_payload, 0, -1);
-
-               /* Not expected to block considering the size of the payload. */
-               sock_ret = lttcomm_send_unix_sock(
-                               sockets[0], pv.buffer.data, pv.buffer.size);
-               ok(sock_ret == pv.buffer.size, "Sent complete test payload");
-               if (sock_ret != pv.buffer.size) {
-                       ERR("Failed to send test payload bytes: ret = %zd, expected = %zu",
-                                       sock_ret, pv.buffer.size);
-                       goto error;
-               }
-
-               sock_ret = lttcomm_send_payload_view_fds_unix_sock(
-                               sockets[0], &pv);
-               ok(sock_ret == 1, "Sent test payload file descriptors");
-               if (sock_ret != 1) {
-                       if (sock_ret < 0) {
-                               PERROR("Failed to send test payload file descriptors: ret = %zd, expected = %d",
-                                               sock_ret, 1);
-                       } else {
-                               diag("Failed to send test payload file descriptors: ret = %zd, expected = %d",
-                                               sock_ret, 1);
-                       }
-
-                       goto error;
-               }
-       }
-
-       /* Receive payload */
-       ret = lttng_dynamic_buffer_set_size(
-                       &received_payload.buffer, sent_payload.buffer.size);
-       if (ret) {
-               PERROR("Failed to pre-allocate reception buffer");
-               goto error;
-       }
-
-       do {
-               const ssize_t to_receive_this_pass = min(max_recv_size,
-                               sent_payload.buffer.size - received);
-
-               sock_ret = lttcomm_recv_unix_sock(sockets[1],
-                               received_payload.buffer.data + received,
-                               to_receive_this_pass);
-               if (sock_ret != to_receive_this_pass) {
-                       ERR("Failed to receive payload bytes: ret = %zd, expected = %zu",
-                                       sock_ret, to_receive_this_pass);
-                       break;
-               }
-
-               received += sock_ret;
-       } while (received < sent_payload.buffer.size);
-
-       ok(received == sent_payload.buffer.size,
-                       "Received complete payload in chunks of %u bytes",
-                       max_recv_size);
-       if (received != sent_payload.buffer.size) {
-               goto error;
-       }
-
-       sock_ret = lttcomm_recv_payload_fds_unix_sock(
-                       sockets[1], 1, &received_payload);
-       ok(sock_ret == (int) sizeof(int),
-                       "Received file descriptor after receiving payload in chunks");
-       if (sock_ret != (int) sizeof(int)) {
-               ERR("Failed to receive test payload file descriptors: ret = %zd, expected = %d",
-                               sock_ret, (int) sizeof(int));
-               goto error;
-       }
-
-       {
-               const struct lttng_payload_view pv =
-                               lttng_payload_view_from_payload(
-                                               &received_payload, 0, -1);
-               const int fd_handle_count =
-                               lttng_payload_view_get_fd_handle_count(&pv);
-
-               ok(fd_handle_count == 1,
-                               "Payload contains 1 fd after receiving payload in chunks");
-       }
-
-error:
-       for (i = 0; i < 2; i++) {
-               if (sockets[i] < 0) {
-                       continue;
-               }
-
-               if (close(sockets[i])) {
-                       PERROR("Failed to close unix socket");
-               }
-       }
-
-       lttng_payload_reset(&sent_payload);
-       lttng_payload_reset(&received_payload);
-}
-
-static
-void test_creds_passing(void)
-{
-       pid_t fork_ret = -1;
-       int ret, parent_socket = -1, child_connection_socket = -1;
-       ssize_t sock_ret;
-       char socket_dir_path[] = "/tmp/test.unix.socket.creds.passing.XXXXXX";
-       char socket_path[PATH_MAX] = {};
-       struct expected_creds {
-               uid_t euid;
-               gid_t egid;
-               pid_t pid;
-       } expected_creds;
-
-       diag("Receive peer's effective uid, effective gid, and pid from a unix socket");
-
-       if (!mkdtemp(socket_dir_path)) {
-               PERROR("Failed to generate temporary socket location");
-               goto error;
-       }
-
-       strncat(socket_path, socket_dir_path,
-                       sizeof(socket_path) - strlen(socket_path) - 1);
-       strncat(socket_path, "/test_unix_socket",
-                       sizeof(socket_path) - strlen(socket_path) - 1);
-
-       parent_socket = lttcomm_create_unix_sock(socket_path);
-       ok(parent_socket >= 0, "Created unix socket at path `%s`", socket_path);
-       if (parent_socket < 0) {
-               PERROR("Failed to create unix socket at path `%s`", socket_path);
-               goto error;
-       }
-
-       ret = lttcomm_listen_unix_sock(parent_socket);
-       if (ret < 0) {
-               PERROR("Failed to mark parent socket as a passive socket");
-               goto error;
-       }
-
-       ret = lttcomm_setsockopt_creds_unix_sock(parent_socket);
-       if (ret) {
-               PERROR("Failed to set SO_PASSCRED on parent socket");
-               goto error;
-       }
-
-       fork_ret = fork();
-       if (fork_ret < 0) {
-               PERROR("Failed to fork");
-               goto error;
-       }
-
-       if (fork_ret == 0) {
-               /* Child. */
-               int child_socket;
-
-               expected_creds = (struct expected_creds){
-                       .euid = geteuid(),
-                       .egid = getegid(),
-                       .pid = getpid(),
-               };
-
-               child_socket = lttcomm_connect_unix_sock(socket_path);
-               if (child_socket < 0) {
-                       PERROR("Failed to connect to parent socket");
-                       goto error;
-               }
-
-               ret = lttcomm_setsockopt_creds_unix_sock(child_socket);
-               if (ret) {
-                       PERROR("Failed to set SO_PASSCRED on child socket");
-               }
-
-               sock_ret = lttcomm_send_creds_unix_sock(child_socket, &expected_creds,
-                               sizeof(expected_creds));
-               if (sock_ret < 0) {
-                       PERROR("Failed to send expected credentials");
-               }
-
-               ret = close(child_socket);
-               if (ret) {
-                       PERROR("Failed to close child socket");
-               }
-       } else {
-               /* Parent. */
-               int child_status;
-               pid_t wait_pid_ret;
-               lttng_sock_cred received_creds = {};
-
-               child_connection_socket =
-                               lttcomm_accept_unix_sock(parent_socket);
-               if (child_connection_socket < 0) {
-                       PERROR();
-                       goto error;
-               }
-
-               ret = lttcomm_setsockopt_creds_unix_sock(
-                               child_connection_socket);
-               if (ret) {
-                       PERROR("Failed to set SO_PASSCRED on child connection socket");
-                       goto error;
-               }
-
-               sock_ret = lttcomm_recv_creds_unix_sock(child_connection_socket,
-                               &expected_creds, sizeof(expected_creds),
-                               &received_creds);
-               if (sock_ret < 0) {
-                       PERROR("Failed to receive credentials");
-                       goto error;
-               }
-
-               wait_pid_ret = waitpid(fork_ret, &child_status, 0);
-               if (wait_pid_ret == -1) {
-                       PERROR("Failed to wait for termination of child process");
-                       goto error;
-               }
-               if (!WIFEXITED(child_status) || WEXITSTATUS(child_status)) {
-                       diag("Child process reported an error, test failed");
-                       goto error;
-               }
-
-               ok(expected_creds.euid == received_creds.uid,
-                               "Received the expected effective uid (%d == %d)",
-                               expected_creds.euid, received_creds.uid);
-               ok(expected_creds.egid == received_creds.gid,
-                               "Received the expected effective gid (%d == %d)",
-                               expected_creds.egid, received_creds.gid);
-               ok(expected_creds.pid == received_creds.pid,
-                               "Received the expected pid (%d == %d)",
-                               expected_creds.pid, received_creds.pid);
-       }
-
-error:
-       if (parent_socket >= 0) {
-               ret = close(parent_socket);
-               if (ret) {
-                       PERROR("Failed to close parent socket");
-               }
-       }
-
-       if (fork_ret == 0) {
-               /* Prevent libtap from printing a result for the child. */
-               fclose(stdout);
-               fclose(stderr);
-
-               /* Child exits at the end of this test. */
-               exit(0);
-       } else if (parent_socket >= 0) {
-               if (child_connection_socket >= 0) {
-                       ret = close(child_connection_socket);
-                       if (ret) {
-                               PERROR("Failed to close child connection socket");
-                       }
-               }
-
-               ret = unlink(socket_path);
-               if (ret) {
-                       PERROR("Failed to unlink socket at path `%s`",
-                                       socket_path);
-               }
-
-               ret = rmdir(socket_dir_path);
-               if (ret) {
-                       PERROR("Failed to remove test directory at `%s`",
-                                       socket_dir_path);
-               }
-       }
-}
-
-int main(void)
-{
-       plan_tests(TEST_COUNT);
-
-       test_high_fd_count(HIGH_FD_COUNT);
-       test_one_fd_per_message(MESSAGE_COUNT);
-       test_receive_in_chunks(LARGE_PAYLOAD_SIZE, LARGE_PAYLOAD_RECV_SIZE);
-       test_creds_passing();
-
-       return exit_status();
-}
This page took 0.031021 seconds and 4 git commands to generate.