kdbus: test suite changed to common format
[platform/kernel/linux-exynos.git] / tools / testing / selftests / kdbus / test-timeout.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <time.h>
4 #include <fcntl.h>
5 #include <stdlib.h>
6 #include <stddef.h>
7 #include <unistd.h>
8 #include <stdint.h>
9 #include <errno.h>
10 #include <assert.h>
11 #include <poll.h>
12 #include <stdbool.h>
13
14 #include "kdbus-api.h"
15 #include "kdbus-test.h"
16 #include "kdbus-util.h"
17 #include "kdbus-enum.h"
18
19 wur int timeout_msg_recv(struct kdbus_conn *conn, uint64_t type, uint64_t *cookie_reply, uint64_t *seqnum, uint64_t *monotonic_ns, uint64_t *realtime_ns)
20 {
21         struct kdbus_cmd_recv recv = { .size = sizeof(recv) };
22         struct kdbus_msg *msg;
23         int ret;
24
25         ret = kdbus_cmd_recv(conn->fd, &recv);
26         if (ret < 0) {
27                 kdbus_printf("error receiving message: %d (%m)\n", ret);
28                 return ret;
29         }
30
31         msg = (struct kdbus_msg *)(conn->buf + recv.msg.offset);
32
33         ASSERT_RETURN_VAL(msg->payload_type,==,(typeof(msg->payload_type))KDBUS_PAYLOAD_KERNEL, -EINVAL);
34         ASSERT_RETURN_VAL(msg->src_id,==,(typeof(msg->src_id))KDBUS_SRC_ID_KERNEL, -EINVAL);
35         ASSERT_RETURN_VAL(msg->dst_id,==,conn->id, -EINVAL);
36
37         {
38                 const struct kdbus_item *item;
39                 bool have_type = false;
40                 bool have_timestamp = false;
41
42                 KDBUS_ITEM_FOREACH(item, msg, items) {
43                         if (item->type == type) {
44                                 ASSERT_ZERO(have_type);
45                                 have_type = true;
46                                 ASSERT_RETURN(item->size,==,2*sizeof(uint64_t));
47                                 continue;
48                         }
49                         ASSERT_RETURN(item->type,==,(uint64_t)KDBUS_ITEM_TIMESTAMP);
50                         ASSERT_ZERO(have_timestamp);
51                         have_timestamp = true;
52                         ASSERT_RETURN(item->size,==,2*sizeof(uint64_t) + sizeof(struct kdbus_timestamp));
53                         #define S(P) if (P) *P = item->timestamp.P;
54                                 S(seqnum)
55                                 S(monotonic_ns)
56                                 S(realtime_ns)
57                         #undef S
58                 }
59         }
60
61         *cookie_reply = msg->cookie_reply;
62         kdbus_printf("Got message timeout for cookie %llu\n",
63                      msg->cookie_reply);
64
65         ret = kdbus_free(conn, recv.msg.offset);
66         if (ret < 0)
67                 return ret;
68
69         return 0;
70 }
71
72 wur int kdbus_test_timeout(struct kdbus_test_env *env)
73 {
74         struct kdbus_conn *conn_a, *conn_b;
75         struct pollfd fd;
76         int ret, i, n_msgs = 4;
77         uint64_t expected = 0;
78         uint64_t cookie = 0xdeadbeef;
79
80         ASSERT_NONZERO(conn_a = kdbus_hello(env->buspath, 0, NULL, 0));
81         ASSERT_NONZERO(conn_b = kdbus_hello(env->buspath, 0, NULL, 0));
82
83         fd.fd = conn_b->fd;
84
85         /*
86          * send messages that expect a reply (within 100 msec),
87          * but never answer it.
88          */
89         for (i = 0; i < n_msgs; i++, cookie++) {
90                 kdbus_printf("Sending message with cookie %llu ...\n",
91                              (unsigned long long)cookie);
92                 ASSERT_ZERO(kdbus_msg_send(conn_b, NULL, cookie, KDBUS_MSG_EXPECT_REPLY, (i + 1) * 100ULL * 1000000ULL, 0, conn_a->id));
93                 expected |= 1ULL << cookie;
94         }
95
96         for (;;) {
97                 uint64_t cookie_reply;
98                 fd.events = POLLIN | POLLPRI | POLLHUP;
99                 fd.revents = 0;
100
101                 ret = poll(&fd, 1, (n_msgs + 1) * 100);
102                 if (ret == 0)
103                         kdbus_printf("--- timeout\n");
104                 if (ret <= 0)
105                         break;
106
107                 if (fd.revents & POLLIN)
108                         ASSERT_ZERO(timeout_msg_recv(conn_b, KDBUS_ITEM_REPLY_TIMEOUT, &cookie_reply, NULL, NULL, NULL));
109
110                 if (!(expected &= ~(1ULL << cookie_reply)))
111                         break;
112         }
113
114         ASSERT_ZERO(expected);
115
116         kdbus_conn_free(conn_a);
117         kdbus_conn_free(conn_b);
118
119         return TEST_OK;
120 }