ctdb-protocol: Fix marshalling for ctdb_req_header
[sfrench/samba-autobuild/.git] / ctdb / tests / src / protocol_ctdb_test.c
1 /*
2    protocol tests
3
4    Copyright (C) Amitay Isaacs  2015
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 <assert.h>
21
22 #include "protocol/protocol_basic.c"
23 #include "protocol/protocol_types.c"
24 #include "protocol/protocol_header.c"
25 #include "protocol/protocol_call.c"
26 #include "protocol/protocol_control.c"
27 #include "protocol/protocol_message.c"
28 #include "protocol/protocol_packet.c"
29
30 #include "tests/src/protocol_common.h"
31 #include "tests/src/protocol_common_ctdb.h"
32
33
34 #define GENERATION      0xabcdef12
35 #define OPERATION       CTDB_REQ_KEEPALIVE
36 #define REQID           0x34567890
37 #define SRCNODE         7
38 #define DESTNODE        13
39
40 /*
41  * Functions to test marshalling
42  */
43
44 /* for ctdb_req_header */
45 #define PROTOCOL_CTDB1_TEST(TYPE, NAME) \
46 static void TEST_FUNC(NAME)(void) \
47 { \
48         TALLOC_CTX *mem_ctx; \
49         TYPE c1, c2; \
50         uint8_t *pkt; \
51         size_t pkt_len, buflen, np; \
52         int ret; \
53 \
54         printf("%s\n", #NAME); \
55         fflush(stdout); \
56         mem_ctx = talloc_new(NULL); \
57         assert(mem_ctx != NULL); \
58         FILL_FUNC(NAME)(&c1); \
59         buflen = LEN_FUNC(NAME)(&c1); \
60         ret = ctdb_allocate_pkt(mem_ctx, buflen, &pkt, &pkt_len); \
61         assert(ret == 0); \
62         assert(pkt != NULL); \
63         assert(pkt_len >= buflen); \
64         np = 0; \
65         PUSH_FUNC(NAME)(&c1, pkt, &np); \
66         assert(np == buflen); \
67         np = 0; \
68         ret = PULL_FUNC(NAME)(pkt, pkt_len, &c2, &np); \
69         assert(ret == 0); \
70         assert(np == buflen); \
71         VERIFY_FUNC(NAME)(&c1, &c2); \
72         talloc_free(mem_ctx); \
73 }
74
75 /* for ctdb_req_control_data, ctdb_reply_control_data */
76 #define PROTOCOL_CTDB2_TEST(TYPE, NAME) \
77 static void TEST_FUNC(NAME)(uint32_t opcode) \
78 { \
79         TALLOC_CTX *mem_ctx; \
80         TYPE c1, c2; \
81         uint8_t *pkt; \
82         size_t pkt_len, buflen, np; \
83         int ret; \
84 \
85         printf("%s %u\n", #NAME, opcode); \
86         fflush(stdout); \
87         mem_ctx = talloc_new(NULL); \
88         assert(mem_ctx != NULL); \
89         FILL_FUNC(NAME)(mem_ctx, &c1, opcode); \
90         buflen = LEN_FUNC(NAME)(&c1); \
91         ret = ctdb_allocate_pkt(mem_ctx, buflen, &pkt, &pkt_len); \
92         assert(ret == 0); \
93         assert(pkt != NULL); \
94         assert(pkt_len >= buflen); \
95         np = 0; \
96         PUSH_FUNC(NAME)(&c1, pkt, &np); \
97         assert(np == buflen); \
98         np = 0; \
99         ret = PULL_FUNC(NAME)(pkt, pkt_len, opcode, mem_ctx, &c2, &np); \
100         assert(ret == 0); \
101         assert(np == buflen); \
102         VERIFY_FUNC(NAME)(&c1, &c2); \
103         talloc_free(mem_ctx); \
104 }
105
106 /* for ctdb_message_data */
107 #define PROTOCOL_CTDB3_TEST(TYPE, NAME) \
108 static void TEST_FUNC(NAME)(uint64_t srvid) \
109 { \
110         TALLOC_CTX *mem_ctx; \
111         TYPE c1, c2; \
112         uint8_t *pkt; \
113         size_t pkt_len, buflen, np; \
114         int ret; \
115 \
116         printf("%s %"PRIx64"\n", #NAME, srvid); \
117         fflush(stdout); \
118         mem_ctx = talloc_new(NULL); \
119         assert(mem_ctx != NULL); \
120         FILL_FUNC(NAME)(mem_ctx, &c1, srvid); \
121         buflen = LEN_FUNC(NAME)(&c1, srvid); \
122         ret = ctdb_allocate_pkt(mem_ctx, buflen, &pkt, &pkt_len); \
123         assert(ret == 0); \
124         assert(pkt != NULL); \
125         assert(pkt_len >= buflen); \
126         np = 0; \
127         PUSH_FUNC(NAME)(&c1, srvid, pkt, &np); \
128         assert(np == buflen); \
129         np = 0; \
130         ret = PULL_FUNC(NAME)(pkt, pkt_len, srvid, mem_ctx, &c2, &np); \
131         assert(ret == 0); \
132         assert(np == buflen); \
133         VERIFY_FUNC(NAME)(&c1, &c2, srvid); \
134         talloc_free(mem_ctx); \
135 }
136
137 /* for ctdb_req_call, ctdb_reply_call, etc. */
138 #define PROTOCOL_CTDB4_TEST(TYPE, NAME, OPER) \
139 static void TEST_FUNC(NAME)(void) \
140 { \
141         TALLOC_CTX *mem_ctx; \
142         struct ctdb_req_header h1, h2; \
143         TYPE c1, c2; \
144         uint8_t *pkt; \
145         size_t pkt_len, buflen, len; \
146         int ret; \
147 \
148         printf("%s\n", #NAME); \
149         fflush(stdout); \
150         mem_ctx = talloc_new(NULL); \
151         assert(mem_ctx != NULL); \
152         fill_ctdb_req_header(&h1); \
153         FILL_FUNC(NAME)(mem_ctx, &c1); \
154         buflen = LEN_FUNC(NAME)(&h1, &c1); \
155         ret = ctdb_allocate_pkt(mem_ctx, buflen, &pkt, &pkt_len); \
156         assert(ret == 0); \
157         assert(pkt != NULL); \
158         assert(pkt_len >= buflen); \
159         len = 0; \
160         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &len); \
161         assert(ret == EMSGSIZE); \
162         assert(len == buflen); \
163         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &pkt_len); \
164         assert(ret == 0); \
165         ret = PULL_FUNC(NAME)(pkt, pkt_len, &h2, mem_ctx, &c2); \
166         assert(ret == 0); \
167         verify_ctdb_req_header(&h1, &h2); \
168         assert(h2.length == pkt_len); \
169         VERIFY_FUNC(NAME)(&c1, &c2); \
170         talloc_free(mem_ctx); \
171 }
172
173 /* for ctdb_req_control */
174 #define PROTOCOL_CTDB5_TEST(TYPE, NAME, OPER) \
175 static void TEST_FUNC(NAME)(uint32_t opcode) \
176 { \
177         TALLOC_CTX *mem_ctx; \
178         struct ctdb_req_header h1, h2; \
179         TYPE c1, c2; \
180         uint8_t *pkt; \
181         size_t pkt_len, buflen, len; \
182         int ret; \
183 \
184         printf("%s %u\n", #NAME, opcode); \
185         fflush(stdout); \
186         mem_ctx = talloc_new(NULL); \
187         assert(mem_ctx != NULL); \
188         fill_ctdb_req_header(&h1); \
189         FILL_FUNC(NAME)(mem_ctx, &c1, opcode); \
190         buflen = LEN_FUNC(NAME)(&h1, &c1); \
191         ret = ctdb_allocate_pkt(mem_ctx, buflen, &pkt, &pkt_len); \
192         assert(ret == 0); \
193         assert(pkt != NULL); \
194         assert(pkt_len >= buflen); \
195         len = 0; \
196         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &len); \
197         assert(ret == EMSGSIZE); \
198         assert(len == buflen); \
199         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &pkt_len); \
200         assert(ret == 0); \
201         ret = PULL_FUNC(NAME)(pkt, pkt_len, &h2, mem_ctx, &c2); \
202         assert(ret == 0); \
203         verify_ctdb_req_header(&h1, &h2); \
204         assert(h2.length == pkt_len); \
205         VERIFY_FUNC(NAME)(&c1, &c2); \
206         talloc_free(mem_ctx); \
207 }
208
209 /* for ctdb_reply_control */
210 #define PROTOCOL_CTDB6_TEST(TYPE, NAME, OPER) \
211 static void TEST_FUNC(NAME)(uint32_t opcode) \
212 { \
213         TALLOC_CTX *mem_ctx; \
214         struct ctdb_req_header h1, h2; \
215         TYPE c1, c2; \
216         uint8_t *pkt; \
217         size_t pkt_len, buflen, len; \
218         int ret; \
219 \
220         printf("%s %u\n", #NAME, opcode); \
221         fflush(stdout); \
222         mem_ctx = talloc_new(NULL); \
223         assert(mem_ctx != NULL); \
224         fill_ctdb_req_header(&h1); \
225         FILL_FUNC(NAME)(mem_ctx, &c1, opcode); \
226         buflen = LEN_FUNC(NAME)(&h1, &c1); \
227         ret = ctdb_allocate_pkt(mem_ctx, buflen, &pkt, &pkt_len); \
228         assert(ret == 0); \
229         assert(pkt != NULL); \
230         assert(pkt_len >= buflen); \
231         len = 0; \
232         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &len); \
233         assert(ret == EMSGSIZE); \
234         assert(len == buflen); \
235         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &pkt_len); \
236         assert(ret == 0); \
237         ret = PULL_FUNC(NAME)(pkt, pkt_len, opcode, &h2, mem_ctx, &c2); \
238         assert(ret == 0); \
239         verify_ctdb_req_header(&h1, &h2); \
240         assert(h2.length == pkt_len); \
241         VERIFY_FUNC(NAME)(&c1, &c2); \
242         talloc_free(mem_ctx); \
243 }
244
245 /* for ctdb_req_message */
246 #define PROTOCOL_CTDB7_TEST(TYPE, NAME, OPER) \
247 static void TEST_FUNC(NAME)(uint64_t srvid) \
248 { \
249         TALLOC_CTX *mem_ctx; \
250         struct ctdb_req_header h1, h2; \
251         TYPE c1, c2; \
252         uint8_t *pkt; \
253         size_t pkt_len, buflen, len; \
254         int ret; \
255 \
256         printf("%s %"PRIx64"\n", #NAME, srvid); \
257         fflush(stdout); \
258         mem_ctx = talloc_new(NULL); \
259         assert(mem_ctx != NULL); \
260         fill_ctdb_req_header(&h1); \
261         FILL_FUNC(NAME)(mem_ctx, &c1, srvid); \
262         buflen = LEN_FUNC(NAME)(&h1, &c1); \
263         ret = ctdb_allocate_pkt(mem_ctx, buflen, &pkt, &pkt_len); \
264         assert(ret == 0); \
265         assert(pkt != NULL); \
266         assert(pkt_len >= buflen); \
267         len = 0; \
268         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &len); \
269         assert(ret == EMSGSIZE); \
270         assert(len == buflen); \
271         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &pkt_len); \
272         assert(ret == 0); \
273         ret = PULL_FUNC(NAME)(pkt, pkt_len, &h2, mem_ctx, &c2); \
274         assert(ret == 0); \
275         verify_ctdb_req_header(&h1, &h2); \
276         assert(h2.length == pkt_len); \
277         VERIFY_FUNC(NAME)(&c1, &c2); \
278         talloc_free(mem_ctx); \
279 }
280
281 PROTOCOL_CTDB1_TEST(struct ctdb_req_header, ctdb_req_header);
282
283 static void test_ctdb_req_call(void)
284 {
285         TALLOC_CTX *mem_ctx;
286         uint8_t *pkt;
287         size_t datalen, pkt_len, len;
288         int ret;
289         struct ctdb_req_header h, h2;
290         struct ctdb_req_call c, c2;
291
292         printf("ctdb_req_call\n");
293         fflush(stdout);
294
295         mem_ctx = talloc_new(NULL);
296         assert(mem_ctx != NULL);
297
298         ctdb_req_header_fill(&h, GENERATION, CTDB_REQ_CALL,
299                              DESTNODE, SRCNODE, REQID);
300
301         fill_ctdb_req_call(mem_ctx, &c);
302         datalen = ctdb_req_call_len(&h, &c);
303         ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
304         assert(ret == 0);
305         assert(pkt != NULL);
306         assert(pkt_len >= datalen);
307         len = 0;
308         ret = ctdb_req_call_push(&h, &c, pkt, &len);
309         assert(ret == EMSGSIZE);
310         assert(len == datalen);
311         ret = ctdb_req_call_push(&h, &c, pkt, &pkt_len);
312         assert(ret == 0);
313         ret = ctdb_req_call_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
314         assert(ret == 0);
315         verify_ctdb_req_header(&h, &h2);
316         assert(h2.length == pkt_len);
317         verify_ctdb_req_call(&c, &c2);
318
319         talloc_free(mem_ctx);
320 }
321
322 static void test_ctdb_reply_call(void)
323 {
324         TALLOC_CTX *mem_ctx;
325         uint8_t *pkt;
326         size_t datalen, pkt_len, len;
327         int ret;
328         struct ctdb_req_header h, h2;
329         struct ctdb_reply_call c, c2;
330
331         printf("ctdb_reply_call\n");
332         fflush(stdout);
333
334         mem_ctx = talloc_new(NULL);
335         assert(mem_ctx != NULL);
336
337         ctdb_req_header_fill(&h, GENERATION, CTDB_REPLY_CALL,
338                              DESTNODE, SRCNODE, REQID);
339
340         fill_ctdb_reply_call(mem_ctx, &c);
341         datalen = ctdb_reply_call_len(&h, &c);
342         ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
343         assert(ret == 0);
344         assert(pkt != NULL);
345         assert(pkt_len >= datalen);
346         len = 0;
347         ret = ctdb_reply_call_push(&h, &c, pkt, &len);
348         assert(ret == EMSGSIZE);
349         assert(len == datalen);
350         ret = ctdb_reply_call_push(&h, &c, pkt, &pkt_len);
351         assert(ret == 0);
352         ret = ctdb_reply_call_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
353         assert(ret == 0);
354         verify_ctdb_req_header(&h, &h2);
355         assert(h2.length == pkt_len);
356         verify_ctdb_reply_call(&c, &c2);
357
358         talloc_free(mem_ctx);
359 }
360
361 static void test_ctdb_reply_error(void)
362 {
363         TALLOC_CTX *mem_ctx;
364         uint8_t *pkt;
365         size_t datalen, pkt_len, len;
366         int ret;
367         struct ctdb_req_header h, h2;
368         struct ctdb_reply_error c, c2;
369
370         printf("ctdb_reply_error\n");
371         fflush(stdout);
372
373         mem_ctx = talloc_new(NULL);
374         assert(mem_ctx != NULL);
375
376         ctdb_req_header_fill(&h, GENERATION, CTDB_REPLY_ERROR,
377                              DESTNODE, SRCNODE, REQID);
378
379         fill_ctdb_reply_error(mem_ctx, &c);
380         datalen = ctdb_reply_error_len(&h, &c);
381         ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
382         assert(ret == 0);
383         assert(pkt != NULL);
384         assert(pkt_len >= datalen);
385         len = 0;
386         ret = ctdb_reply_error_push(&h, &c, pkt, &len);
387         assert(ret == EMSGSIZE);
388         assert(len == datalen);
389         ret = ctdb_reply_error_push(&h, &c, pkt, &pkt_len);
390         assert(ret == 0);
391         ret = ctdb_reply_error_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
392         assert(ret == 0);
393         verify_ctdb_req_header(&h, &h2);
394         assert(h2.length == pkt_len);
395         verify_ctdb_reply_error(&c, &c2);
396
397         talloc_free(mem_ctx);
398 }
399
400 static void test_ctdb_req_dmaster(void)
401 {
402         TALLOC_CTX *mem_ctx;
403         uint8_t *pkt;
404         size_t datalen, pkt_len, len;
405         int ret;
406         struct ctdb_req_header h, h2;
407         struct ctdb_req_dmaster c, c2;
408
409         printf("ctdb_req_dmaster\n");
410         fflush(stdout);
411
412         mem_ctx = talloc_new(NULL);
413         assert(mem_ctx != NULL);
414
415         ctdb_req_header_fill(&h, GENERATION, CTDB_REQ_DMASTER,
416                              DESTNODE, SRCNODE, REQID);
417
418         fill_ctdb_req_dmaster(mem_ctx, &c);
419         datalen = ctdb_req_dmaster_len(&h, &c);
420         ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
421         assert(ret == 0);
422         assert(pkt != NULL);
423         assert(pkt_len >= datalen);
424         len = 0;
425         ret = ctdb_req_dmaster_push(&h, &c, pkt, &len);
426         assert(ret == EMSGSIZE);
427         assert(len == datalen);
428         ret = ctdb_req_dmaster_push(&h, &c, pkt, &pkt_len);
429         assert(ret == 0);
430         ret = ctdb_req_dmaster_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
431         assert(ret == 0);
432         verify_ctdb_req_header(&h, &h2);
433         assert(h2.length == pkt_len);
434         verify_ctdb_req_dmaster(&c, &c2);
435
436         talloc_free(mem_ctx);
437 }
438
439 static void test_ctdb_reply_dmaster(void)
440 {
441         TALLOC_CTX *mem_ctx;
442         uint8_t *pkt;
443         size_t datalen, pkt_len, len;
444         int ret;
445         struct ctdb_req_header h, h2;
446         struct ctdb_reply_dmaster c, c2;
447
448         printf("ctdb_reply_dmaster\n");
449         fflush(stdout);
450
451         mem_ctx = talloc_new(NULL);
452         assert(mem_ctx != NULL);
453
454         ctdb_req_header_fill(&h, GENERATION, CTDB_REPLY_DMASTER,
455                              DESTNODE, SRCNODE, REQID);
456
457         fill_ctdb_reply_dmaster(mem_ctx, &c);
458         datalen = ctdb_reply_dmaster_len(&h, &c);
459         ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
460         assert(ret == 0);
461         assert(pkt != NULL);
462         assert(pkt_len >= datalen);
463         len = 0;
464         ret = ctdb_reply_dmaster_push(&h, &c, pkt, &len);
465         assert(ret == EMSGSIZE);
466         assert(len == datalen);
467         ret = ctdb_reply_dmaster_push(&h, &c, pkt, &pkt_len);
468         assert(ret == 0);
469         ret = ctdb_reply_dmaster_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
470         assert(ret == 0);
471         verify_ctdb_req_header(&h, &h2);
472         assert(h2.length == pkt_len);
473         verify_ctdb_reply_dmaster(&c, &c2);
474
475         talloc_free(mem_ctx);
476 }
477
478 #define NUM_CONTROLS    151
479
480 static void test_ctdb_req_control_data(void)
481 {
482         TALLOC_CTX *mem_ctx;
483         size_t buflen;
484         int ret;
485         struct ctdb_req_control_data cd, cd2;
486         uint32_t opcode;
487
488         printf("ctdb_req_control_data\n");
489         fflush(stdout);
490
491         for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
492                 mem_ctx = talloc_new(NULL);
493                 assert(mem_ctx != NULL);
494
495                 printf("%u.. ", opcode);
496                 fflush(stdout);
497                 fill_ctdb_req_control_data(mem_ctx, &cd, opcode);
498                 buflen = ctdb_req_control_data_len(&cd);
499                 ctdb_req_control_data_push(&cd, BUFFER);
500                 ret = ctdb_req_control_data_pull(BUFFER, buflen, opcode, mem_ctx, &cd2);
501                 assert(ret == 0);
502                 verify_ctdb_req_control_data(&cd, &cd2);
503                 talloc_free(mem_ctx);
504         }
505
506         printf("\n");
507         fflush(stdout);
508 }
509
510 static void test_ctdb_reply_control_data(void)
511 {
512         TALLOC_CTX *mem_ctx;
513         size_t buflen;
514         int ret;
515         struct ctdb_reply_control_data cd, cd2;
516         uint32_t opcode;
517
518         printf("ctdb_reply_control_data\n");
519         fflush(stdout);
520
521         for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
522                 mem_ctx = talloc_new(NULL);
523                 assert(mem_ctx != NULL);
524
525                 printf("%u.. ", opcode);
526                 fflush(stdout);
527                 fill_ctdb_reply_control_data(mem_ctx, &cd, opcode);
528                 buflen = ctdb_reply_control_data_len(&cd);
529                 ctdb_reply_control_data_push(&cd, BUFFER);
530                 ret = ctdb_reply_control_data_pull(BUFFER, buflen, opcode, mem_ctx, &cd2);
531                 assert(ret == 0);
532                 verify_ctdb_reply_control_data(&cd, &cd2);
533                 talloc_free(mem_ctx);
534         }
535
536         printf("\n");
537         fflush(stdout);
538 }
539
540 static void test_ctdb_req_control(void)
541 {
542         TALLOC_CTX *mem_ctx;
543         uint8_t *pkt;
544         size_t datalen, pkt_len, len;
545         int ret;
546         struct ctdb_req_header h, h2;
547         struct ctdb_req_control c, c2;
548         uint32_t opcode;
549
550         printf("ctdb_req_control\n");
551         fflush(stdout);
552
553         ctdb_req_header_fill(&h, GENERATION, CTDB_REQ_CONTROL,
554                              DESTNODE, SRCNODE, REQID);
555
556         for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
557                 mem_ctx = talloc_new(NULL);
558                 assert(mem_ctx != NULL);
559
560                 printf("%u.. ", opcode);
561                 fflush(stdout);
562                 fill_ctdb_req_control(mem_ctx, &c, opcode);
563                 datalen = ctdb_req_control_len(&h, &c);
564                 ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
565                 assert(ret == 0);
566                 assert(pkt != NULL);
567                 assert(pkt_len >= datalen);
568                 len = 0;
569                 ret = ctdb_req_control_push(&h, &c, pkt, &len);
570                 assert(ret == EMSGSIZE);
571                 assert(len == datalen);
572                 ret = ctdb_req_control_push(&h, &c, pkt, &pkt_len);
573                 assert(ret == 0);
574                 ret = ctdb_req_control_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
575                 assert(ret == 0);
576                 verify_ctdb_req_header(&h, &h2);
577                 assert(h2.length == pkt_len);
578                 verify_ctdb_req_control(&c, &c2);
579
580                 talloc_free(mem_ctx);
581         }
582
583         printf("\n");
584         fflush(stdout);
585 }
586
587 static void test_ctdb_reply_control(void)
588 {
589         TALLOC_CTX *mem_ctx;
590         uint8_t *pkt;
591         size_t datalen, pkt_len, len;
592         int ret;
593         struct ctdb_req_header h, h2;
594         struct ctdb_reply_control c, c2;
595         uint32_t opcode;
596
597         printf("ctdb_reply_control\n");
598         fflush(stdout);
599
600         ctdb_req_header_fill(&h, GENERATION, CTDB_REPLY_CONTROL,
601                              DESTNODE, SRCNODE, REQID);
602
603         for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
604                 mem_ctx = talloc_new(NULL);
605                 assert(mem_ctx != NULL);
606
607                 printf("%u.. ", opcode);
608                 fflush(stdout);
609                 fill_ctdb_reply_control(mem_ctx, &c, opcode);
610                 datalen = ctdb_reply_control_len(&h, &c);
611                 ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
612                 assert(ret == 0);
613                 assert(pkt != NULL);
614                 assert(pkt_len >= datalen);
615                 len = 0;
616                 ret = ctdb_reply_control_push(&h, &c, pkt, &len);
617                 assert(ret == EMSGSIZE);
618                 assert(len == datalen);
619                 ret = ctdb_reply_control_push(&h, &c, pkt, &pkt_len);
620                 assert(ret == 0);
621                 ret = ctdb_reply_control_pull(pkt, pkt_len, opcode, &h2, mem_ctx, &c2);
622                 assert(ret == 0);
623                 verify_ctdb_req_header(&h, &h2);
624                 assert(h2.length == pkt_len);
625                 verify_ctdb_reply_control(&c, &c2);
626
627                 talloc_free(mem_ctx);
628         }
629
630         printf("\n");
631         fflush(stdout);
632 }
633
634 static void test_ctdb_req_message_data(void)
635 {
636         TALLOC_CTX *mem_ctx;
637         uint8_t *pkt;
638         size_t datalen, pkt_len, len;
639         int ret;
640         struct ctdb_req_header h, h2;
641         struct ctdb_req_message_data c, c2;
642
643         printf("ctdb_req_message\n");
644         fflush(stdout);
645
646         mem_ctx = talloc_new(NULL);
647         assert(mem_ctx != NULL);
648
649         ctdb_req_header_fill(&h, GENERATION, CTDB_REQ_MESSAGE,
650                              DESTNODE, SRCNODE, REQID);
651
652         fill_ctdb_req_message_data(mem_ctx, &c);
653         datalen = ctdb_req_message_data_len(&h, &c);
654         ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
655         assert(ret == 0);
656         assert(pkt != NULL);
657         assert(pkt_len >= datalen);
658         len = 0;
659         ret = ctdb_req_message_data_push(&h, &c, pkt, &len);
660         assert(ret == EMSGSIZE);
661         assert(len == datalen);
662         ret = ctdb_req_message_data_push(&h, &c, pkt, &pkt_len);
663         assert(ret == 0);
664         ret = ctdb_req_message_data_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
665         assert(ret == 0);
666         verify_ctdb_req_header(&h, &h2);
667         assert(h2.length == pkt_len);
668         verify_ctdb_req_message_data(&c, &c2);
669
670         talloc_free(mem_ctx);
671 }
672
673 int main(int argc, char *argv[])
674 {
675         if (argc == 2) {
676                 int seed = atoi(argv[1]);
677                 srandom(seed);
678         }
679
680         TEST_FUNC(ctdb_req_header)();
681
682         test_ctdb_req_call();
683         test_ctdb_reply_call();
684         test_ctdb_reply_error();
685         test_ctdb_req_dmaster();
686         test_ctdb_reply_dmaster();
687
688         test_ctdb_req_control_data();
689         test_ctdb_reply_control_data();
690
691         test_ctdb_req_control();
692         test_ctdb_reply_control();
693
694         test_ctdb_req_message_data();
695
696         return 0;
697 }