vici: Add a libvici low-level client library
[strongswan.git] / src / libcharon / plugins / vici / suites / test_request.c
1 /*
2 * Copyright (C) 2014 Martin Willi
3 * Copyright (C) 2014 revosec AG
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <test_suite.h>
17
18 #include "../vici_dispatcher.h"
19 #include "../libvici.h"
20
21 #include <unistd.h>
22
23 #define URI "unix:///tmp/strongswan-vici-request-test"
24
25 static void encode_section(vici_req_t *req)
26 {
27 vici_begin_section(req, "section1");
28 vici_add_key_valuef(req, "key1", "value%u", 1);
29 vici_add_key_value(req, "key2", "value2", strlen("value2"));
30 vici_end_section(req);
31 }
32
33 static void decode_section(vici_res_t *res)
34 {
35 char *str;
36 int len;
37
38 ck_assert(vici_parse(res) == VICI_PARSE_BEGIN_SECTION);
39 ck_assert_str_eq(vici_parse_name(res), "section1");
40 ck_assert(vici_parse(res) == VICI_PARSE_KEY_VALUE);
41 ck_assert_str_eq(vici_parse_name(res), "key1");
42 ck_assert_str_eq(vici_parse_value_str(res), "value1");
43 ck_assert(vici_parse(res) == VICI_PARSE_KEY_VALUE);
44 ck_assert_str_eq(vici_parse_name(res), "key2");
45 str = vici_parse_value(res, &len);
46 ck_assert(chunk_equals(chunk_from_str("value2"), chunk_create(str, len)));
47 ck_assert(vici_parse(res) == VICI_PARSE_END_SECTION);
48 ck_assert(vici_parse(res) == VICI_PARSE_END);
49 }
50
51 static void encode_list(vici_req_t *req)
52 {
53 vici_begin_list(req, "list1");
54 vici_add_list_item(req, "item1", strlen("item1"));
55 vici_add_list_itemf(req, "item%u", 2);
56 vici_end_list(req);
57 }
58
59 static void decode_list(vici_res_t *res)
60 {
61 char *str;
62 int len;
63
64 ck_assert(vici_parse(res) == VICI_PARSE_BEGIN_LIST);
65 ck_assert_str_eq(vici_parse_name(res), "list1");
66 ck_assert(vici_parse(res) == VICI_PARSE_LIST_ITEM);
67 ck_assert_str_eq(vici_parse_value_str(res), "item1");
68 ck_assert(vici_parse(res) == VICI_PARSE_LIST_ITEM);
69 str = vici_parse_value(res, &len);
70 ck_assert(chunk_equals(chunk_from_str("item2"), chunk_create(str, len)));
71 ck_assert(vici_parse(res) == VICI_PARSE_END_LIST);
72 ck_assert(vici_parse(res) == VICI_PARSE_END);
73 }
74
75 static struct {
76 void (*encode)(vici_req_t* req);
77 void (*decode)(vici_res_t* res);
78 } echo_tests[] = {
79 { encode_section, decode_section },
80 { encode_list, decode_list },
81 };
82
83 static vici_message_t* echo_cb(void *user, char *name,
84 u_int id, vici_message_t *request)
85 {
86 ck_assert_str_eq(name, "echo");
87 ck_assert_int_eq((uintptr_t)user, 1);
88
89 return vici_message_create_from_enumerator(request->create_enumerator(request));
90 }
91
92 START_TEST(test_echo)
93 {
94 vici_dispatcher_t *dispatcher;
95 vici_conn_t *conn;
96 vici_req_t *req;
97 vici_res_t *res;
98
99 lib->processor->set_threads(lib->processor, 8);
100
101 dispatcher = vici_dispatcher_create(URI);
102 ck_assert(dispatcher);
103
104 dispatcher->manage_command(dispatcher, "echo", echo_cb, (void*)(uintptr_t)1);
105
106 vici_init();
107 conn = vici_connect(URI);
108 ck_assert(conn);
109
110 req = vici_begin("echo");
111 echo_tests[_i].encode(req);
112 res = vici_submit(req, conn);
113 ck_assert(res);
114 echo_tests[_i].decode(res);
115 vici_free_res(res);
116
117 vici_disconnect(conn);
118
119 dispatcher->manage_command(dispatcher, "echo", NULL, NULL);
120
121 lib->processor->cancel(lib->processor);
122 dispatcher->destroy(dispatcher);
123
124 vici_deinit();
125 }
126 END_TEST
127
128 START_TEST(test_missing)
129 {
130 vici_dispatcher_t *dispatcher;
131 vici_conn_t *conn;
132 vici_req_t *req;
133 vici_res_t *res;
134
135 lib->processor->set_threads(lib->processor, 8);
136
137 dispatcher = vici_dispatcher_create(URI);
138 ck_assert(dispatcher);
139
140 vici_init();
141 conn = vici_connect(URI);
142 ck_assert(conn);
143
144 req = vici_begin("nonexistent");
145 encode_section(req);
146 res = vici_submit(req, conn);
147 ck_assert(res == NULL);
148
149 vici_disconnect(conn);
150
151 dispatcher->manage_command(dispatcher, "echo", NULL, NULL);
152
153 lib->processor->cancel(lib->processor);
154 dispatcher->destroy(dispatcher);
155
156 vici_deinit();
157 }
158 END_TEST
159
160 static void event_cb(void *user, char *name, vici_res_t *ev)
161 {
162 int *events = (int*)user;
163
164 (*events)++;
165 }
166
167 START_TEST(test_stress)
168 {
169 vici_dispatcher_t *dispatcher;
170 vici_conn_t *conn;
171 vici_req_t *req;
172 vici_res_t *res;
173 int i, total = 50, events = 0;
174
175 lib->processor->set_threads(lib->processor, 8);
176
177 dispatcher = vici_dispatcher_create(URI);
178 ck_assert(dispatcher);
179
180 dispatcher->manage_command(dispatcher, "echo", echo_cb, (void*)(uintptr_t)1);
181 dispatcher->manage_event(dispatcher, "dummy", TRUE);
182
183 vici_init();
184 conn = vici_connect(URI);
185 ck_assert(conn);
186
187 for (i = 0; i < total; i++)
188 {
189 /* do some event management in between */
190 ck_assert(vici_register(conn, "dummy", event_cb, &events) == 0);
191 dispatcher->raise_event(dispatcher, "dummy",
192 vici_message_create_from_args(
193 VICI_KEY_VALUE, "key1", chunk_from_str("value1"),
194 VICI_END));
195
196 req = vici_begin("echo");
197 encode_section(req);
198 res = vici_submit(req, conn);
199 ck_assert(res);
200 decode_section(res);
201 vici_free_res(res);
202
203 ck_assert(vici_register(conn, "dummy", NULL, NULL) == 0);
204 }
205
206 while (events < total)
207 {
208 usleep(1000);
209 }
210
211 vici_disconnect(conn);
212
213 dispatcher->manage_command(dispatcher, "echo", NULL, NULL);
214 dispatcher->manage_event(dispatcher, "dummy", FALSE);
215
216 lib->processor->cancel(lib->processor);
217 dispatcher->destroy(dispatcher);
218
219 vici_deinit();
220 }
221 END_TEST
222
223 Suite *request_suite_create()
224 {
225 Suite *s;
226 TCase *tc;
227
228 s = suite_create("vici request");
229
230 tc = tcase_create("echo");
231 tcase_add_loop_test(tc, test_echo, 0, countof(echo_tests));
232 suite_add_tcase(s, tc);
233
234 tc = tcase_create("missing");
235 tcase_add_test(tc, test_missing);
236 suite_add_tcase(s, tc);
237
238 tc = tcase_create("stress");
239 tcase_add_test(tc, test_stress);
240 suite_add_tcase(s, tc);
241
242 return s;
243 }