swrap: Add support for openat64()
[socket_wrapper.git] / tests / test_swrap_unit.c
1 #include <stdarg.h>
2 #include <stddef.h>
3 #include <setjmp.h>
4 #include <cmocka.h>
5 #include <stdio.h>
6 #include <string.h>
7
8 #include "config.h"
9
10 #include "socket_wrapper.c"
11
12 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
13
14 /**
15  * test wrap_sendmsg_filter_cmsghdr()
16  *
17  * Prepare a message with two cmsg:
18  * - the first cmsg is a char buf with the string "Hello World"
19  * - the second cmsg is a char buf with the string "!\n"
20  *
21  * Both cmsgs will be copied without modification by
22  * wrap_sendmsg_filter_cmsghdr(), so we can check that the msg
23  * controllen, the cmsg sizes and the payload are the same.
24  *
25  * We use an not existing cmsg_type which triggers cmsg copying.
26  */
27 static void test_sendmsg_cmsg(void **state)
28 {
29         int rc = 0;
30         char byte = '!';
31         struct iovec iov;
32         struct msghdr msg = { 0 };
33         struct cmsghdr *cmsg;
34         char *cmsgbuf;
35         int cmsgbuf_size;
36         const char *s1 = "Hello World";
37         const int s1_len = strlen(s1);
38         const char *s2 = "!\n";
39         const int s2_len = strlen(s2);
40         uint8_t *cmbuf = NULL;
41         size_t cmlen = 0;
42
43         (void)state; /* unused */
44
45         iov.iov_base = &byte;
46         iov.iov_len = 1;
47
48         /*
49          * Prepare cmsgbuf and msg
50          */
51         msg.msg_iov = &iov;
52         msg.msg_iovlen = 1;
53         cmsgbuf_size = CMSG_SPACE(s1_len) + CMSG_SPACE(s2_len);
54         cmsgbuf = calloc(cmsgbuf_size, sizeof(char));
55         assert_non_null(cmsgbuf);
56         msg.msg_control = cmsgbuf;
57         msg.msg_controllen = cmsgbuf_size;
58
59         /*
60          * Prepare first cmsg with string "Hello World"
61          */
62         cmsg = CMSG_FIRSTHDR(&msg);
63         assert_non_null(cmsg);
64
65         cmsg->cmsg_level = SOL_SOCKET;
66         cmsg->cmsg_type = ~0 - 1;
67         cmsg->cmsg_len = CMSG_LEN(s1_len);
68         memcpy(CMSG_DATA(cmsg), s1, s1_len);
69
70         /*
71          * Prepare second cmsg with string "!\n"
72          */
73         cmsg = CMSG_NXTHDR(&msg, cmsg);
74         assert_non_null(cmsg);
75
76         cmsg->cmsg_level = SOL_SOCKET;
77         cmsg->cmsg_type = ~0 - 2;
78         cmsg->cmsg_len = CMSG_LEN(s2_len);
79         memcpy(CMSG_DATA(cmsg), s2, s2_len);
80
81         /*
82          * Now call swrap_sendmsg_filter_cmsghdr() on the msg
83          */
84         rc = swrap_sendmsg_filter_cmsghdr(&msg, &cmbuf, &cmlen);
85         assert_return_code(rc, errno);
86         assert_int_equal(cmlen, msg.msg_controllen);
87
88         /*
89          * Insert filtered cmsgbug into msg and validate cmsgs.
90          */
91         msg.msg_control = cmbuf;
92
93         cmsg = CMSG_FIRSTHDR(&msg);
94         assert_non_null(cmsg);
95         assert_int_equal(cmsg->cmsg_len, CMSG_LEN(s1_len));
96         assert_memory_equal(CMSG_DATA(cmsg), s1, s1_len);
97
98         cmsg = CMSG_NXTHDR(&msg, cmsg);
99         assert_non_null(cmsg);
100         assert_int_equal(cmsg->cmsg_len, CMSG_LEN(s2_len));
101         assert_memory_equal(CMSG_DATA(cmsg), s2, s2_len);
102
103         free(cmbuf);
104         free(cmsgbuf);
105 }
106 #endif
107
108 int main(void) {
109         int rc;
110
111         const struct CMUnitTest unit_tests[] = {
112 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
113                 cmocka_unit_test(test_sendmsg_cmsg),
114 #endif
115         };
116
117         rc = cmocka_run_group_tests(unit_tests, NULL, NULL);
118
119         return rc;
120 }