ctdb-scripts: Add test variable CTDB_NFS_DISTRO_STYLE
[vlendec/samba-autobuild/.git] / ctdb / event / event_protocol_test.c
1 /*
2    CTDB event daemon - protocol test
3
4    Copyright (C) Amitay Isaacs  2018
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "replace.h"
21
22 #include <talloc.h>
23 #include <assert.h>
24
25 #define EVENT_PROTOCOL_TEST
26 #include "event/event_protocol.c"
27
28 #include "tests/src/protocol_common_basic.h"
29
30 /*
31  * Functions to fill and verify event protocol structures
32  */
33
34 static void fill_ctdb_event_script(TALLOC_CTX *mem_ctx,
35                                    struct ctdb_event_script *p)
36 {
37         fill_ctdb_stringn(mem_ctx, &p->name);
38         fill_ctdb_timeval(&p->begin);
39         fill_ctdb_timeval(&p->end);
40         p->result = rand32i();
41         fill_ctdb_stringn(mem_ctx, &p->output);
42 }
43
44 static void verify_ctdb_event_script(struct ctdb_event_script *p1,
45                                      struct ctdb_event_script *p2)
46 {
47         verify_ctdb_stringn(&p1->name, &p2->name);
48         verify_ctdb_timeval(&p1->begin, &p2->begin);
49         verify_ctdb_timeval(&p1->end, &p2->end);
50         assert(p1->result == p2->result);
51         verify_ctdb_stringn(&p1->output, &p2->output);
52 }
53
54 static void fill_ctdb_event_script_list(TALLOC_CTX *mem_ctx,
55                                         struct ctdb_event_script_list *p)
56 {
57         int i;
58
59         p->num_scripts = rand_int(32);
60         if (p->num_scripts > 0) {
61                 p->script = talloc_array(mem_ctx,
62                                          struct ctdb_event_script,
63                                          p->num_scripts);
64                 assert(p->script != NULL);
65
66                 for (i=0; i<p->num_scripts; i++) {
67                         fill_ctdb_event_script(mem_ctx, &p->script[i]);
68                 }
69         } else {
70                 p->script = NULL;
71         }
72 }
73
74 static void verify_ctdb_event_script_list(struct ctdb_event_script_list *p1,
75                                           struct ctdb_event_script_list *p2)
76 {
77         int i;
78
79         assert(p1->num_scripts == p2->num_scripts);
80         for (i=0; i<p1->num_scripts; i++) {
81                 verify_ctdb_event_script(&p1->script[i], &p2->script[i]);
82         }
83 }
84
85 static void fill_ctdb_event_request_run(TALLOC_CTX *mem_ctx,
86                                         struct ctdb_event_request_run *p)
87 {
88         fill_ctdb_stringn(mem_ctx, &p->component);
89         fill_ctdb_stringn(mem_ctx, &p->event);
90         fill_ctdb_stringn(mem_ctx, &p->args);
91         p->timeout = rand32();
92         p->flags = rand32();
93 }
94
95 static void verify_ctdb_event_request_run(struct ctdb_event_request_run *p1,
96                                           struct ctdb_event_request_run *p2)
97 {
98         verify_ctdb_stringn(&p1->component, &p2->component);
99         verify_ctdb_stringn(&p1->event, &p2->event);
100         verify_ctdb_stringn(&p1->args, &p2->args);
101         assert(p1->timeout == p2->timeout);
102         assert(p1->flags == p2->flags);
103 }
104
105 static void fill_ctdb_event_request_status(TALLOC_CTX *mem_ctx,
106                                            struct ctdb_event_request_status *p)
107 {
108         fill_ctdb_stringn(mem_ctx, &p->component);
109         fill_ctdb_stringn(mem_ctx, &p->event);
110 }
111
112 static void verify_ctdb_event_request_status(
113                                         struct ctdb_event_request_status *p1,
114                                         struct ctdb_event_request_status *p2)
115 {
116         verify_ctdb_stringn(&p1->component, &p2->component);
117         verify_ctdb_stringn(&p1->event, &p2->event);
118 }
119
120 static void fill_ctdb_event_request_script(TALLOC_CTX *mem_ctx,
121                                            struct ctdb_event_request_script *p)
122 {
123         fill_ctdb_stringn(mem_ctx, &p->component);
124         fill_ctdb_stringn(mem_ctx, &p->script);
125         if (rand_int(1) == 0) {
126                 p->action = CTDB_EVENT_SCRIPT_DISABLE;
127         } else {
128                 p->action = CTDB_EVENT_SCRIPT_ENABLE;
129         }
130 }
131
132 static void fill_ctdb_event_reply_status(TALLOC_CTX *mem_ctx,
133                                          struct ctdb_event_reply_status *p)
134 {
135         p->summary = rand32i();
136         p->script_list = talloc(mem_ctx, struct ctdb_event_script_list);
137         assert(p->script_list != NULL);
138
139         fill_ctdb_event_script_list(mem_ctx, p->script_list);
140 }
141
142 static void verify_ctdb_event_reply_status(struct ctdb_event_reply_status *p1,
143                                            struct ctdb_event_reply_status *p2)
144 {
145         assert(p1->summary == p2->summary);
146         verify_ctdb_event_script_list(p1->script_list, p2->script_list);
147 }
148
149 static void verify_ctdb_event_request_script(
150                                         struct ctdb_event_request_script *p1,
151                                         struct ctdb_event_request_script *p2)
152 {
153         verify_ctdb_stringn(&p1->component, &p2->component);
154         verify_ctdb_stringn(&p1->script, &p2->script);
155         assert(p1->action == p2->action);
156 }
157
158 static void fill_ctdb_event_request_data(TALLOC_CTX *mem_ctx,
159                                          struct ctdb_event_request *p,
160                                          uint32_t cmd)
161 {
162         p->cmd = cmd;
163
164         switch (cmd) {
165         case CTDB_EVENT_CMD_RUN:
166                 p->data.run = talloc(mem_ctx, struct ctdb_event_request_run);
167                 assert(p->data.run != NULL);
168
169                 fill_ctdb_event_request_run(mem_ctx, p->data.run);
170                 break;
171
172         case CTDB_EVENT_CMD_STATUS:
173                 p->data.status = talloc(mem_ctx,
174                                         struct ctdb_event_request_status);
175                 assert(p->data.status != NULL);
176
177                 fill_ctdb_event_request_status(mem_ctx, p->data.status);
178                 break;
179
180         case CTDB_EVENT_CMD_SCRIPT:
181                 p->data.script = talloc(mem_ctx,
182                                         struct ctdb_event_request_script);
183                 assert(p->data.script != NULL);
184
185                 fill_ctdb_event_request_script(mem_ctx, p->data.script);
186                 break;
187
188         default:
189                 assert(cmd > 0 && cmd < CTDB_EVENT_CMD_MAX);
190         }
191 }
192
193 static void verify_ctdb_event_request_data(struct ctdb_event_request *p1,
194                                            struct ctdb_event_request *p2)
195 {
196         assert(p1->cmd == p2->cmd);
197
198         switch (p1->cmd) {
199         case CTDB_EVENT_CMD_RUN:
200                 verify_ctdb_event_request_run(p1->data.run, p2->data.run);
201                 break;
202
203         case CTDB_EVENT_CMD_STATUS:
204                 verify_ctdb_event_request_status(p1->data.status,
205                                                  p2->data.status);
206                 break;
207
208         case CTDB_EVENT_CMD_SCRIPT:
209                 verify_ctdb_event_request_script(p1->data.script,
210                                                  p2->data.script);
211                 break;
212
213         default:
214                 assert(p1->cmd > 0 && p1->cmd < CTDB_EVENT_CMD_MAX);
215         }
216 }
217
218 static void fill_ctdb_event_reply_data(TALLOC_CTX *mem_ctx,
219                                        struct ctdb_event_reply *p,
220                                        uint32_t cmd)
221 {
222         p->cmd = cmd;
223         p->result = rand32i();
224
225         if (p->result != 0) {
226                 return;
227         }
228
229         switch (cmd) {
230         case CTDB_EVENT_CMD_STATUS:
231                 p->data.status = talloc(mem_ctx,
232                                         struct ctdb_event_reply_status);
233                 assert(p->data.status != NULL);
234
235                 fill_ctdb_event_reply_status(mem_ctx, p->data.status);
236                 break;
237
238         default:
239                 assert(cmd > 0 && cmd < CTDB_EVENT_CMD_MAX);
240         }
241 }
242
243 static void verify_ctdb_event_reply_data(struct ctdb_event_reply *p1,
244                                          struct ctdb_event_reply *p2)
245 {
246         assert(p1->cmd == p2->cmd);
247         assert(p1->result == p2->result);
248
249         if (p1->result != 0) {
250                 return;
251         }
252
253         switch (p1->cmd) {
254         case CTDB_EVENT_CMD_STATUS:
255                 verify_ctdb_event_reply_status(p1->data.status,
256                                                p2->data.status);
257                 break;
258
259         default:
260                 assert(p1->cmd > 0 && p1->cmd < CTDB_EVENT_CMD_MAX);
261         }
262 }
263
264 static void fill_ctdb_event_header(struct ctdb_event_header *p)
265 {
266         p->length = 0; /* updated by push functions */
267         p->version = 0; /* updated by push functions */
268         p->reqid = rand32();
269 }
270
271 static void verify_ctdb_event_header(struct ctdb_event_header *p1,
272                                      struct ctdb_event_header *p2)
273 {
274         assert(p1->length == p2->length);
275         assert(p1->version == p2->version);
276         assert(p1->reqid == p2->reqid);
277 }
278
279 static void fill_ctdb_event_request(TALLOC_CTX *mem_ctx,
280                                     struct ctdb_event_request *p,
281                                     uint32_t cmd)
282 {
283         fill_ctdb_event_request_data(mem_ctx, p, cmd);
284 }
285
286 static void verify_ctdb_event_request(struct ctdb_event_request *p1,
287                                       struct ctdb_event_request *p2)
288 {
289         verify_ctdb_event_request_data(p1, p2);
290 }
291
292 static void fill_ctdb_event_reply(TALLOC_CTX *mem_ctx,
293                                   struct ctdb_event_reply *p,
294                                   uint32_t cmd)
295 {
296         fill_ctdb_event_reply_data(mem_ctx, p, cmd);
297 }
298
299 static void verify_ctdb_event_reply(struct ctdb_event_reply *p1,
300                                     struct ctdb_event_reply *p2)
301 {
302         verify_ctdb_event_reply_data(p1, p2);
303 }
304
305 #define EVENT_PROTOCOL1_TEST(TYPE, NAME) \
306 static void TEST_FUNC(NAME)(uint32_t cmd) \
307 { \
308         TALLOC_CTX *mem_ctx; \
309         TYPE c1, *c2; \
310         uint8_t *buf; \
311         size_t buflen, np; \
312         int ret; \
313 \
314         printf("%s %u\n", #NAME, cmd); \
315         fflush(stdout); \
316         mem_ctx = talloc_new(NULL); \
317         assert(mem_ctx != NULL); \
318         FILL_FUNC(NAME)(mem_ctx, &c1, cmd); \
319         buflen = LEN_FUNC(NAME)(&c1); \
320         buf = talloc_size(mem_ctx, buflen); \
321         assert(buf != NULL); \
322         np = 0; \
323         PUSH_FUNC(NAME)(&c1, buf, &np); \
324         assert(np == buflen); \
325         np = 0; \
326         ret = PULL_FUNC(NAME)(buf, buflen, mem_ctx, &c2, &np); \
327         assert(ret == 0); \
328         assert(np == buflen); \
329         VERIFY_FUNC(NAME)(&c1, c2); \
330         talloc_free(mem_ctx); \
331 }
332
333 #define EVENT_PROTOCOL2_TEST(TYPE, NAME) \
334 static void TEST_FUNC(NAME)(uint32_t cmd) \
335 { \
336         TALLOC_CTX *mem_ctx; \
337         struct ctdb_event_header h1, h2; \
338         TYPE c1, *c2; \
339         uint8_t *buf; \
340         size_t buflen, len; \
341         int ret; \
342 \
343         printf("%s %u\n", #NAME, cmd); \
344         fflush(stdout); \
345         mem_ctx = talloc_new(NULL); \
346         assert(mem_ctx != NULL); \
347         fill_ctdb_event_header(&h1); \
348         FILL_FUNC(NAME)(mem_ctx, &c1, cmd); \
349         buflen = LEN_FUNC(NAME)(&h1, &c1); \
350         buf = talloc_size(mem_ctx, buflen); \
351         assert(buf != NULL); \
352         len = 0; \
353         ret = PUSH_FUNC(NAME)(&h1, &c1, buf, &len); \
354         assert(ret == EMSGSIZE); \
355         assert(len == buflen); \
356         ret = PUSH_FUNC(NAME)(&h1, &c1, buf, &buflen); \
357         assert(ret == 0); \
358         ret = PULL_FUNC(NAME)(buf, buflen, &h2, mem_ctx, &c2); \
359         assert(ret == 0); \
360         verify_ctdb_event_header(&h1, &h2); \
361         VERIFY_FUNC(NAME)(&c1, c2); \
362         talloc_free(mem_ctx); \
363 }
364
365 PROTOCOL_TYPE3_TEST(struct ctdb_event_script, ctdb_event_script);
366 PROTOCOL_TYPE3_TEST(struct ctdb_event_script_list, ctdb_event_script_list);
367
368 PROTOCOL_TYPE3_TEST(struct ctdb_event_request_run, ctdb_event_request_run);
369 PROTOCOL_TYPE3_TEST(struct ctdb_event_request_status,
370                     ctdb_event_request_status);
371 PROTOCOL_TYPE3_TEST(struct ctdb_event_request_script,
372                     ctdb_event_request_script);
373
374 PROTOCOL_TYPE3_TEST(struct ctdb_event_reply_status, ctdb_event_reply_status);
375
376 EVENT_PROTOCOL1_TEST(struct ctdb_event_request, ctdb_event_request_data);
377 EVENT_PROTOCOL1_TEST(struct ctdb_event_reply, ctdb_event_reply_data);
378
379 EVENT_PROTOCOL2_TEST(struct ctdb_event_request, ctdb_event_request);
380 EVENT_PROTOCOL2_TEST(struct ctdb_event_reply, ctdb_event_reply);
381
382 int main(int argc, const char **argv)
383 {
384         uint32_t cmd;
385
386         if (argc == 2) {
387                 int seed = atoi(argv[1]);
388                 srandom(seed);
389         }
390
391         TEST_FUNC(ctdb_event_script)();
392         TEST_FUNC(ctdb_event_script_list)();
393
394         TEST_FUNC(ctdb_event_request_run)();
395         TEST_FUNC(ctdb_event_request_status)();
396         TEST_FUNC(ctdb_event_request_script)();
397
398         TEST_FUNC(ctdb_event_reply_status)();
399
400         for (cmd=1; cmd<CTDB_EVENT_CMD_MAX; cmd++) {
401                 TEST_FUNC(ctdb_event_request_data)(cmd);
402         }
403         for (cmd=1; cmd<CTDB_EVENT_CMD_MAX; cmd++) {
404                 TEST_FUNC(ctdb_event_reply_data)(cmd);
405         }
406
407         for (cmd=1; cmd<CTDB_EVENT_CMD_MAX; cmd++) {
408                 TEST_FUNC(ctdb_event_request)(cmd);
409         }
410         for (cmd=1; cmd<CTDB_EVENT_CMD_MAX; cmd++) {
411                 TEST_FUNC(ctdb_event_reply)(cmd);
412         }
413
414         return 0;
415 }