4 Copyright (C) Amitay Isaacs 2015
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.
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.
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/>.
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"
30 #include "tests/src/protocol_common.h"
31 #include "tests/src/protocol_common_ctdb.h"
34 #define GENERATION 0xabcdef12
35 #define OPERATION CTDB_REQ_KEEPALIVE
36 #define REQID 0x34567890
41 * Functions to test marshalling
44 /* for ctdb_req_header */
45 #define PROTOCOL_CTDB1_TEST(TYPE, NAME) \
46 static void TEST_FUNC(NAME)(void) \
48 TALLOC_CTX *mem_ctx; \
51 size_t pkt_len, buflen, np; \
54 printf("%s\n", #NAME); \
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); \
62 assert(pkt != NULL); \
63 assert(pkt_len >= buflen); \
65 PUSH_FUNC(NAME)(&c1, pkt, &np); \
66 assert(np == buflen); \
68 ret = PULL_FUNC(NAME)(pkt, pkt_len, &c2, &np); \
70 assert(np == buflen); \
71 VERIFY_FUNC(NAME)(&c1, &c2); \
72 talloc_free(mem_ctx); \
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) \
79 TALLOC_CTX *mem_ctx; \
82 size_t pkt_len, buflen, np; \
85 printf("%s %u\n", #NAME, opcode); \
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); \
93 assert(pkt != NULL); \
94 assert(pkt_len >= buflen); \
96 PUSH_FUNC(NAME)(&c1, pkt, &np); \
97 assert(np == buflen); \
99 ret = PULL_FUNC(NAME)(pkt, pkt_len, opcode, mem_ctx, &c2, &np); \
101 assert(np == buflen); \
102 VERIFY_FUNC(NAME)(&c1, &c2); \
103 talloc_free(mem_ctx); \
106 /* for ctdb_message_data */
107 #define PROTOCOL_CTDB3_TEST(TYPE, NAME) \
108 static void TEST_FUNC(NAME)(uint64_t srvid) \
110 TALLOC_CTX *mem_ctx; \
113 size_t pkt_len, buflen, np; \
116 printf("%s %"PRIx64"\n", #NAME, srvid); \
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); \
124 assert(pkt != NULL); \
125 assert(pkt_len >= buflen); \
127 PUSH_FUNC(NAME)(&c1, srvid, pkt, &np); \
128 assert(np == buflen); \
130 ret = PULL_FUNC(NAME)(pkt, pkt_len, srvid, mem_ctx, &c2, &np); \
132 assert(np == buflen); \
133 VERIFY_FUNC(NAME)(&c1, &c2, srvid); \
134 talloc_free(mem_ctx); \
137 /* for ctdb_req_call, ctdb_reply_call, etc. */
138 #define PROTOCOL_CTDB4_TEST(TYPE, NAME, OPER) \
139 static void TEST_FUNC(NAME)(void) \
141 TALLOC_CTX *mem_ctx; \
142 struct ctdb_req_header h1, h2; \
145 size_t pkt_len, buflen, len; \
148 printf("%s\n", #NAME); \
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); \
157 assert(pkt != NULL); \
158 assert(pkt_len >= buflen); \
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); \
165 ret = PULL_FUNC(NAME)(pkt, pkt_len, &h2, mem_ctx, &c2); \
167 verify_ctdb_req_header(&h1, &h2); \
168 assert(h2.length == pkt_len); \
169 VERIFY_FUNC(NAME)(&c1, &c2); \
170 talloc_free(mem_ctx); \
173 /* for ctdb_req_control */
174 #define PROTOCOL_CTDB5_TEST(TYPE, NAME, OPER) \
175 static void TEST_FUNC(NAME)(uint32_t opcode) \
177 TALLOC_CTX *mem_ctx; \
178 struct ctdb_req_header h1, h2; \
181 size_t pkt_len, buflen, len; \
184 printf("%s %u\n", #NAME, opcode); \
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); \
193 assert(pkt != NULL); \
194 assert(pkt_len >= buflen); \
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); \
201 ret = PULL_FUNC(NAME)(pkt, pkt_len, &h2, mem_ctx, &c2); \
203 verify_ctdb_req_header(&h1, &h2); \
204 assert(h2.length == pkt_len); \
205 VERIFY_FUNC(NAME)(&c1, &c2); \
206 talloc_free(mem_ctx); \
209 /* for ctdb_reply_control */
210 #define PROTOCOL_CTDB6_TEST(TYPE, NAME, OPER) \
211 static void TEST_FUNC(NAME)(uint32_t opcode) \
213 TALLOC_CTX *mem_ctx; \
214 struct ctdb_req_header h1, h2; \
217 size_t pkt_len, buflen, len; \
220 printf("%s %u\n", #NAME, opcode); \
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); \
229 assert(pkt != NULL); \
230 assert(pkt_len >= buflen); \
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); \
237 ret = PULL_FUNC(NAME)(pkt, pkt_len, opcode, &h2, mem_ctx, &c2); \
239 verify_ctdb_req_header(&h1, &h2); \
240 assert(h2.length == pkt_len); \
241 VERIFY_FUNC(NAME)(&c1, &c2); \
242 talloc_free(mem_ctx); \
245 /* for ctdb_req_message */
246 #define PROTOCOL_CTDB7_TEST(TYPE, NAME, OPER) \
247 static void TEST_FUNC(NAME)(uint64_t srvid) \
249 TALLOC_CTX *mem_ctx; \
250 struct ctdb_req_header h1, h2; \
253 size_t pkt_len, buflen, len; \
256 printf("%s %"PRIx64"\n", #NAME, srvid); \
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); \
265 assert(pkt != NULL); \
266 assert(pkt_len >= buflen); \
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); \
273 ret = PULL_FUNC(NAME)(pkt, pkt_len, &h2, mem_ctx, &c2); \
275 verify_ctdb_req_header(&h1, &h2); \
276 assert(h2.length == pkt_len); \
277 VERIFY_FUNC(NAME)(&c1, &c2); \
278 talloc_free(mem_ctx); \
281 static void test_ctdb_req_header(void)
286 struct ctdb_req_header h, h2;
289 printf("ctdb_req_header\n");
292 mem_ctx = talloc_new(NULL);
293 assert(mem_ctx != NULL);
295 ctdb_req_header_fill(&h, GENERATION, OPERATION, DESTNODE, SRCNODE,
298 ret = ctdb_allocate_pkt(mem_ctx, ctdb_req_header_len(&h),
302 assert(pkt_len >= ctdb_req_header_len(&h));
304 ctdb_req_header_push(&h, pkt);
306 ret = ctdb_req_header_pull(pkt, pkt_len, &h2);
309 verify_ctdb_req_header(&h, &h2);
311 talloc_free(mem_ctx);
314 static void test_ctdb_req_call(void)
318 size_t datalen, pkt_len, len;
320 struct ctdb_req_header h, h2;
321 struct ctdb_req_call c, c2;
323 printf("ctdb_req_call\n");
326 mem_ctx = talloc_new(NULL);
327 assert(mem_ctx != NULL);
329 ctdb_req_header_fill(&h, GENERATION, CTDB_REQ_CALL,
330 DESTNODE, SRCNODE, REQID);
332 fill_ctdb_req_call(mem_ctx, &c);
333 datalen = ctdb_req_call_len(&h, &c);
334 ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
337 assert(pkt_len >= datalen);
339 ret = ctdb_req_call_push(&h, &c, pkt, &len);
340 assert(ret == EMSGSIZE);
341 assert(len == datalen);
342 ret = ctdb_req_call_push(&h, &c, pkt, &pkt_len);
344 ret = ctdb_req_call_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
346 verify_ctdb_req_header(&h, &h2);
347 assert(h2.length == pkt_len);
348 verify_ctdb_req_call(&c, &c2);
350 talloc_free(mem_ctx);
353 static void test_ctdb_reply_call(void)
357 size_t datalen, pkt_len, len;
359 struct ctdb_req_header h, h2;
360 struct ctdb_reply_call c, c2;
362 printf("ctdb_reply_call\n");
365 mem_ctx = talloc_new(NULL);
366 assert(mem_ctx != NULL);
368 ctdb_req_header_fill(&h, GENERATION, CTDB_REPLY_CALL,
369 DESTNODE, SRCNODE, REQID);
371 fill_ctdb_reply_call(mem_ctx, &c);
372 datalen = ctdb_reply_call_len(&h, &c);
373 ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
376 assert(pkt_len >= datalen);
378 ret = ctdb_reply_call_push(&h, &c, pkt, &len);
379 assert(ret == EMSGSIZE);
380 assert(len == datalen);
381 ret = ctdb_reply_call_push(&h, &c, pkt, &pkt_len);
383 ret = ctdb_reply_call_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
385 verify_ctdb_req_header(&h, &h2);
386 assert(h2.length == pkt_len);
387 verify_ctdb_reply_call(&c, &c2);
389 talloc_free(mem_ctx);
392 static void test_ctdb_reply_error(void)
396 size_t datalen, pkt_len, len;
398 struct ctdb_req_header h, h2;
399 struct ctdb_reply_error c, c2;
401 printf("ctdb_reply_error\n");
404 mem_ctx = talloc_new(NULL);
405 assert(mem_ctx != NULL);
407 ctdb_req_header_fill(&h, GENERATION, CTDB_REPLY_ERROR,
408 DESTNODE, SRCNODE, REQID);
410 fill_ctdb_reply_error(mem_ctx, &c);
411 datalen = ctdb_reply_error_len(&h, &c);
412 ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
415 assert(pkt_len >= datalen);
417 ret = ctdb_reply_error_push(&h, &c, pkt, &len);
418 assert(ret == EMSGSIZE);
419 assert(len == datalen);
420 ret = ctdb_reply_error_push(&h, &c, pkt, &pkt_len);
422 ret = ctdb_reply_error_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
424 verify_ctdb_req_header(&h, &h2);
425 assert(h2.length == pkt_len);
426 verify_ctdb_reply_error(&c, &c2);
428 talloc_free(mem_ctx);
431 static void test_ctdb_req_dmaster(void)
435 size_t datalen, pkt_len, len;
437 struct ctdb_req_header h, h2;
438 struct ctdb_req_dmaster c, c2;
440 printf("ctdb_req_dmaster\n");
443 mem_ctx = talloc_new(NULL);
444 assert(mem_ctx != NULL);
446 ctdb_req_header_fill(&h, GENERATION, CTDB_REQ_DMASTER,
447 DESTNODE, SRCNODE, REQID);
449 fill_ctdb_req_dmaster(mem_ctx, &c);
450 datalen = ctdb_req_dmaster_len(&h, &c);
451 ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
454 assert(pkt_len >= datalen);
456 ret = ctdb_req_dmaster_push(&h, &c, pkt, &len);
457 assert(ret == EMSGSIZE);
458 assert(len == datalen);
459 ret = ctdb_req_dmaster_push(&h, &c, pkt, &pkt_len);
461 ret = ctdb_req_dmaster_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
463 verify_ctdb_req_header(&h, &h2);
464 assert(h2.length == pkt_len);
465 verify_ctdb_req_dmaster(&c, &c2);
467 talloc_free(mem_ctx);
470 static void test_ctdb_reply_dmaster(void)
474 size_t datalen, pkt_len, len;
476 struct ctdb_req_header h, h2;
477 struct ctdb_reply_dmaster c, c2;
479 printf("ctdb_reply_dmaster\n");
482 mem_ctx = talloc_new(NULL);
483 assert(mem_ctx != NULL);
485 ctdb_req_header_fill(&h, GENERATION, CTDB_REPLY_DMASTER,
486 DESTNODE, SRCNODE, REQID);
488 fill_ctdb_reply_dmaster(mem_ctx, &c);
489 datalen = ctdb_reply_dmaster_len(&h, &c);
490 ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
493 assert(pkt_len >= datalen);
495 ret = ctdb_reply_dmaster_push(&h, &c, pkt, &len);
496 assert(ret == EMSGSIZE);
497 assert(len == datalen);
498 ret = ctdb_reply_dmaster_push(&h, &c, pkt, &pkt_len);
500 ret = ctdb_reply_dmaster_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
502 verify_ctdb_req_header(&h, &h2);
503 assert(h2.length == pkt_len);
504 verify_ctdb_reply_dmaster(&c, &c2);
506 talloc_free(mem_ctx);
509 #define NUM_CONTROLS 151
511 static void test_ctdb_req_control_data(void)
516 struct ctdb_req_control_data cd, cd2;
519 printf("ctdb_req_control_data\n");
522 for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
523 mem_ctx = talloc_new(NULL);
524 assert(mem_ctx != NULL);
526 printf("%u.. ", opcode);
528 fill_ctdb_req_control_data(mem_ctx, &cd, opcode);
529 buflen = ctdb_req_control_data_len(&cd);
530 ctdb_req_control_data_push(&cd, BUFFER);
531 ret = ctdb_req_control_data_pull(BUFFER, buflen, opcode, mem_ctx, &cd2);
533 verify_ctdb_req_control_data(&cd, &cd2);
534 talloc_free(mem_ctx);
541 static void test_ctdb_reply_control_data(void)
546 struct ctdb_reply_control_data cd, cd2;
549 printf("ctdb_reply_control_data\n");
552 for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
553 mem_ctx = talloc_new(NULL);
554 assert(mem_ctx != NULL);
556 printf("%u.. ", opcode);
558 fill_ctdb_reply_control_data(mem_ctx, &cd, opcode);
559 buflen = ctdb_reply_control_data_len(&cd);
560 ctdb_reply_control_data_push(&cd, BUFFER);
561 ret = ctdb_reply_control_data_pull(BUFFER, buflen, opcode, mem_ctx, &cd2);
563 verify_ctdb_reply_control_data(&cd, &cd2);
564 talloc_free(mem_ctx);
571 static void test_ctdb_req_control(void)
575 size_t datalen, pkt_len, len;
577 struct ctdb_req_header h, h2;
578 struct ctdb_req_control c, c2;
581 printf("ctdb_req_control\n");
584 ctdb_req_header_fill(&h, GENERATION, CTDB_REQ_CONTROL,
585 DESTNODE, SRCNODE, REQID);
587 for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
588 mem_ctx = talloc_new(NULL);
589 assert(mem_ctx != NULL);
591 printf("%u.. ", opcode);
593 fill_ctdb_req_control(mem_ctx, &c, opcode);
594 datalen = ctdb_req_control_len(&h, &c);
595 ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
598 assert(pkt_len >= datalen);
600 ret = ctdb_req_control_push(&h, &c, pkt, &len);
601 assert(ret == EMSGSIZE);
602 assert(len == datalen);
603 ret = ctdb_req_control_push(&h, &c, pkt, &pkt_len);
605 ret = ctdb_req_control_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
607 verify_ctdb_req_header(&h, &h2);
608 assert(h2.length == pkt_len);
609 verify_ctdb_req_control(&c, &c2);
611 talloc_free(mem_ctx);
618 static void test_ctdb_reply_control(void)
622 size_t datalen, pkt_len, len;
624 struct ctdb_req_header h, h2;
625 struct ctdb_reply_control c, c2;
628 printf("ctdb_reply_control\n");
631 ctdb_req_header_fill(&h, GENERATION, CTDB_REPLY_CONTROL,
632 DESTNODE, SRCNODE, REQID);
634 for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
635 mem_ctx = talloc_new(NULL);
636 assert(mem_ctx != NULL);
638 printf("%u.. ", opcode);
640 fill_ctdb_reply_control(mem_ctx, &c, opcode);
641 datalen = ctdb_reply_control_len(&h, &c);
642 ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
645 assert(pkt_len >= datalen);
647 ret = ctdb_reply_control_push(&h, &c, pkt, &len);
648 assert(ret == EMSGSIZE);
649 assert(len == datalen);
650 ret = ctdb_reply_control_push(&h, &c, pkt, &pkt_len);
652 ret = ctdb_reply_control_pull(pkt, pkt_len, opcode, &h2, mem_ctx, &c2);
654 verify_ctdb_req_header(&h, &h2);
655 assert(h2.length == pkt_len);
656 verify_ctdb_reply_control(&c, &c2);
658 talloc_free(mem_ctx);
665 static void test_ctdb_req_message_data(void)
669 size_t datalen, pkt_len, len;
671 struct ctdb_req_header h, h2;
672 struct ctdb_req_message_data c, c2;
674 printf("ctdb_req_message\n");
677 mem_ctx = talloc_new(NULL);
678 assert(mem_ctx != NULL);
680 ctdb_req_header_fill(&h, GENERATION, CTDB_REQ_MESSAGE,
681 DESTNODE, SRCNODE, REQID);
683 fill_ctdb_req_message_data(mem_ctx, &c);
684 datalen = ctdb_req_message_data_len(&h, &c);
685 ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len);
688 assert(pkt_len >= datalen);
690 ret = ctdb_req_message_data_push(&h, &c, pkt, &len);
691 assert(ret == EMSGSIZE);
692 assert(len == datalen);
693 ret = ctdb_req_message_data_push(&h, &c, pkt, &pkt_len);
695 ret = ctdb_req_message_data_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
697 verify_ctdb_req_header(&h, &h2);
698 assert(h2.length == pkt_len);
699 verify_ctdb_req_message_data(&c, &c2);
701 talloc_free(mem_ctx);
704 int main(int argc, char *argv[])
707 int seed = atoi(argv[1]);
711 test_ctdb_req_header();
713 test_ctdb_req_call();
714 test_ctdb_reply_call();
715 test_ctdb_reply_error();
716 test_ctdb_req_dmaster();
717 test_ctdb_reply_dmaster();
719 test_ctdb_req_control_data();
720 test_ctdb_reply_control_data();
722 test_ctdb_req_control();
723 test_ctdb_reply_control();
725 test_ctdb_req_message_data();