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 PROTOCOL_CTDB1_TEST(struct ctdb_req_header, ctdb_req_header);
283 static void test_ctdb_req_call(void)
287 size_t datalen, pkt_len, len;
289 struct ctdb_req_header h, h2;
290 struct ctdb_req_call c, c2;
292 printf("ctdb_req_call\n");
295 mem_ctx = talloc_new(NULL);
296 assert(mem_ctx != NULL);
298 ctdb_req_header_fill(&h, GENERATION, CTDB_REQ_CALL,
299 DESTNODE, SRCNODE, REQID);
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);
306 assert(pkt_len >= datalen);
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);
313 ret = ctdb_req_call_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
315 verify_ctdb_req_header(&h, &h2);
316 assert(h2.length == pkt_len);
317 verify_ctdb_req_call(&c, &c2);
319 talloc_free(mem_ctx);
322 static void test_ctdb_reply_call(void)
326 size_t datalen, pkt_len, len;
328 struct ctdb_req_header h, h2;
329 struct ctdb_reply_call c, c2;
331 printf("ctdb_reply_call\n");
334 mem_ctx = talloc_new(NULL);
335 assert(mem_ctx != NULL);
337 ctdb_req_header_fill(&h, GENERATION, CTDB_REPLY_CALL,
338 DESTNODE, SRCNODE, REQID);
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);
345 assert(pkt_len >= datalen);
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);
352 ret = ctdb_reply_call_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
354 verify_ctdb_req_header(&h, &h2);
355 assert(h2.length == pkt_len);
356 verify_ctdb_reply_call(&c, &c2);
358 talloc_free(mem_ctx);
361 static void test_ctdb_reply_error(void)
365 size_t datalen, pkt_len, len;
367 struct ctdb_req_header h, h2;
368 struct ctdb_reply_error c, c2;
370 printf("ctdb_reply_error\n");
373 mem_ctx = talloc_new(NULL);
374 assert(mem_ctx != NULL);
376 ctdb_req_header_fill(&h, GENERATION, CTDB_REPLY_ERROR,
377 DESTNODE, SRCNODE, REQID);
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);
384 assert(pkt_len >= datalen);
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);
391 ret = ctdb_reply_error_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
393 verify_ctdb_req_header(&h, &h2);
394 assert(h2.length == pkt_len);
395 verify_ctdb_reply_error(&c, &c2);
397 talloc_free(mem_ctx);
400 static void test_ctdb_req_dmaster(void)
404 size_t datalen, pkt_len, len;
406 struct ctdb_req_header h, h2;
407 struct ctdb_req_dmaster c, c2;
409 printf("ctdb_req_dmaster\n");
412 mem_ctx = talloc_new(NULL);
413 assert(mem_ctx != NULL);
415 ctdb_req_header_fill(&h, GENERATION, CTDB_REQ_DMASTER,
416 DESTNODE, SRCNODE, REQID);
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);
423 assert(pkt_len >= datalen);
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);
430 ret = ctdb_req_dmaster_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
432 verify_ctdb_req_header(&h, &h2);
433 assert(h2.length == pkt_len);
434 verify_ctdb_req_dmaster(&c, &c2);
436 talloc_free(mem_ctx);
439 static void test_ctdb_reply_dmaster(void)
443 size_t datalen, pkt_len, len;
445 struct ctdb_req_header h, h2;
446 struct ctdb_reply_dmaster c, c2;
448 printf("ctdb_reply_dmaster\n");
451 mem_ctx = talloc_new(NULL);
452 assert(mem_ctx != NULL);
454 ctdb_req_header_fill(&h, GENERATION, CTDB_REPLY_DMASTER,
455 DESTNODE, SRCNODE, REQID);
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);
462 assert(pkt_len >= datalen);
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);
469 ret = ctdb_reply_dmaster_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
471 verify_ctdb_req_header(&h, &h2);
472 assert(h2.length == pkt_len);
473 verify_ctdb_reply_dmaster(&c, &c2);
475 talloc_free(mem_ctx);
478 #define NUM_CONTROLS 151
480 static void test_ctdb_req_control_data(void)
485 struct ctdb_req_control_data cd, cd2;
488 printf("ctdb_req_control_data\n");
491 for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
492 mem_ctx = talloc_new(NULL);
493 assert(mem_ctx != NULL);
495 printf("%u.. ", opcode);
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);
502 verify_ctdb_req_control_data(&cd, &cd2);
503 talloc_free(mem_ctx);
510 static void test_ctdb_reply_control_data(void)
515 struct ctdb_reply_control_data cd, cd2;
518 printf("ctdb_reply_control_data\n");
521 for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
522 mem_ctx = talloc_new(NULL);
523 assert(mem_ctx != NULL);
525 printf("%u.. ", opcode);
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);
532 verify_ctdb_reply_control_data(&cd, &cd2);
533 talloc_free(mem_ctx);
540 static void test_ctdb_req_control(void)
544 size_t datalen, pkt_len, len;
546 struct ctdb_req_header h, h2;
547 struct ctdb_req_control c, c2;
550 printf("ctdb_req_control\n");
553 ctdb_req_header_fill(&h, GENERATION, CTDB_REQ_CONTROL,
554 DESTNODE, SRCNODE, REQID);
556 for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
557 mem_ctx = talloc_new(NULL);
558 assert(mem_ctx != NULL);
560 printf("%u.. ", opcode);
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);
567 assert(pkt_len >= datalen);
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);
574 ret = ctdb_req_control_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
576 verify_ctdb_req_header(&h, &h2);
577 assert(h2.length == pkt_len);
578 verify_ctdb_req_control(&c, &c2);
580 talloc_free(mem_ctx);
587 static void test_ctdb_reply_control(void)
591 size_t datalen, pkt_len, len;
593 struct ctdb_req_header h, h2;
594 struct ctdb_reply_control c, c2;
597 printf("ctdb_reply_control\n");
600 ctdb_req_header_fill(&h, GENERATION, CTDB_REPLY_CONTROL,
601 DESTNODE, SRCNODE, REQID);
603 for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
604 mem_ctx = talloc_new(NULL);
605 assert(mem_ctx != NULL);
607 printf("%u.. ", opcode);
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);
614 assert(pkt_len >= datalen);
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);
621 ret = ctdb_reply_control_pull(pkt, pkt_len, opcode, &h2, mem_ctx, &c2);
623 verify_ctdb_req_header(&h, &h2);
624 assert(h2.length == pkt_len);
625 verify_ctdb_reply_control(&c, &c2);
627 talloc_free(mem_ctx);
634 static void test_ctdb_req_message_data(void)
638 size_t datalen, pkt_len, len;
640 struct ctdb_req_header h, h2;
641 struct ctdb_req_message_data c, c2;
643 printf("ctdb_req_message\n");
646 mem_ctx = talloc_new(NULL);
647 assert(mem_ctx != NULL);
649 ctdb_req_header_fill(&h, GENERATION, CTDB_REQ_MESSAGE,
650 DESTNODE, SRCNODE, REQID);
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);
657 assert(pkt_len >= datalen);
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);
664 ret = ctdb_req_message_data_pull(pkt, pkt_len, &h2, mem_ctx, &c2);
666 verify_ctdb_req_header(&h, &h2);
667 assert(h2.length == pkt_len);
668 verify_ctdb_req_message_data(&c, &c2);
670 talloc_free(mem_ctx);
673 int main(int argc, char *argv[])
676 int seed = atoi(argv[1]);
680 TEST_FUNC(ctdb_req_header)();
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();
688 test_ctdb_req_control_data();
689 test_ctdb_reply_control_data();
691 test_ctdb_req_control();
692 test_ctdb_reply_control();
694 test_ctdb_req_message_data();