450f5c2aef4a10645eb5b8760702ba5d3add95f7
[vlendec/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_keepalive.c"
29 #include "protocol/protocol_packet.c"
30
31 #include "tests/src/protocol_common.h"
32 #include "tests/src/protocol_common_ctdb.h"
33
34
35 #define GENERATION      0xabcdef12
36 #define OPERATION       CTDB_REQ_KEEPALIVE
37 #define REQID           0x34567890
38 #define SRCNODE         7
39 #define DESTNODE        13
40
41 /*
42  * Functions to test marshalling
43  */
44
45 /* for ctdb_req_header */
46 #define PROTOCOL_CTDB1_TEST(TYPE, NAME) \
47 static void TEST_FUNC(NAME)(void) \
48 { \
49         TALLOC_CTX *mem_ctx; \
50         TYPE c1, c2; \
51         uint8_t *pkt; \
52         size_t pkt_len, buflen, np; \
53         int ret; \
54 \
55         printf("%s\n", #NAME); \
56         fflush(stdout); \
57         mem_ctx = talloc_new(NULL); \
58         assert(mem_ctx != NULL); \
59         FILL_FUNC(NAME)(&c1); \
60         buflen = LEN_FUNC(NAME)(&c1); \
61         ret = ctdb_allocate_pkt(mem_ctx, buflen, &pkt, &pkt_len); \
62         assert(ret == 0); \
63         assert(pkt != NULL); \
64         assert(pkt_len >= buflen); \
65         np = 0; \
66         PUSH_FUNC(NAME)(&c1, pkt, &np); \
67         assert(np == buflen); \
68         np = 0; \
69         ret = PULL_FUNC(NAME)(pkt, pkt_len, &c2, &np); \
70         assert(ret == 0); \
71         assert(np == buflen); \
72         VERIFY_FUNC(NAME)(&c1, &c2); \
73         talloc_free(mem_ctx); \
74 }
75
76 /* for ctdb_req_control_data, ctdb_reply_control_data */
77 #define PROTOCOL_CTDB2_TEST(TYPE, NAME) \
78 static void TEST_FUNC(NAME)(uint32_t opcode) \
79 { \
80         TALLOC_CTX *mem_ctx; \
81         TYPE c1, c2; \
82         uint8_t *pkt; \
83         size_t pkt_len, buflen, np; \
84         int ret; \
85 \
86         printf("%s %u\n", #NAME, opcode); \
87         fflush(stdout); \
88         mem_ctx = talloc_new(NULL); \
89         assert(mem_ctx != NULL); \
90         FILL_FUNC(NAME)(mem_ctx, &c1, opcode); \
91         buflen = LEN_FUNC(NAME)(&c1); \
92         ret = ctdb_allocate_pkt(mem_ctx, buflen, &pkt, &pkt_len); \
93         assert(ret == 0); \
94         assert(pkt != NULL); \
95         assert(pkt_len >= buflen); \
96         np = 0; \
97         PUSH_FUNC(NAME)(&c1, pkt, &np); \
98         assert(np == buflen); \
99         np = 0; \
100         ret = PULL_FUNC(NAME)(pkt, pkt_len, opcode, mem_ctx, &c2, &np); \
101         assert(ret == 0); \
102         assert(np == buflen); \
103         VERIFY_FUNC(NAME)(&c1, &c2); \
104         talloc_free(mem_ctx); \
105 }
106
107 /* for ctdb_message_data */
108 #define PROTOCOL_CTDB3_TEST(TYPE, NAME) \
109 static void TEST_FUNC(NAME)(uint64_t srvid) \
110 { \
111         TALLOC_CTX *mem_ctx; \
112         TYPE c1, c2; \
113         uint8_t *pkt; \
114         size_t pkt_len, buflen, np; \
115         int ret; \
116 \
117         printf("%s %"PRIx64"\n", #NAME, srvid); \
118         fflush(stdout); \
119         mem_ctx = talloc_new(NULL); \
120         assert(mem_ctx != NULL); \
121         FILL_FUNC(NAME)(mem_ctx, &c1, srvid); \
122         buflen = LEN_FUNC(NAME)(&c1, srvid); \
123         ret = ctdb_allocate_pkt(mem_ctx, buflen, &pkt, &pkt_len); \
124         assert(ret == 0); \
125         assert(pkt != NULL); \
126         assert(pkt_len >= buflen); \
127         np = 0; \
128         PUSH_FUNC(NAME)(&c1, srvid, pkt, &np); \
129         assert(np == buflen); \
130         np = 0; \
131         ret = PULL_FUNC(NAME)(pkt, pkt_len, srvid, mem_ctx, &c2, &np); \
132         assert(ret == 0); \
133         assert(np == buflen); \
134         VERIFY_FUNC(NAME)(&c1, &c2, srvid); \
135         talloc_free(mem_ctx); \
136 }
137
138 /* for ctdb_req_call, ctdb_reply_call, etc. */
139 #define PROTOCOL_CTDB4_TEST(TYPE, NAME, OPER) \
140 static void TEST_FUNC(NAME)(void) \
141 { \
142         TALLOC_CTX *mem_ctx; \
143         struct ctdb_req_header h1, h2; \
144         TYPE c1, c2; \
145         uint8_t *pkt; \
146         size_t pkt_len, buflen, len; \
147         int ret; \
148 \
149         printf("%s\n", #NAME); \
150         fflush(stdout); \
151         mem_ctx = talloc_new(NULL); \
152         assert(mem_ctx != NULL); \
153         fill_ctdb_req_header(&h1); \
154         FILL_FUNC(NAME)(mem_ctx, &c1); \
155         buflen = LEN_FUNC(NAME)(&h1, &c1); \
156         ret = ctdb_allocate_pkt(mem_ctx, buflen, &pkt, &pkt_len); \
157         assert(ret == 0); \
158         assert(pkt != NULL); \
159         assert(pkt_len >= buflen); \
160         len = 0; \
161         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &len); \
162         assert(ret == EMSGSIZE); \
163         assert(len == buflen); \
164         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &pkt_len); \
165         assert(ret == 0); \
166         ret = PULL_FUNC(NAME)(pkt, pkt_len, &h2, mem_ctx, &c2); \
167         assert(ret == 0); \
168         verify_ctdb_req_header(&h1, &h2); \
169         assert(h2.length == pkt_len); \
170         VERIFY_FUNC(NAME)(&c1, &c2); \
171         talloc_free(mem_ctx); \
172 }
173
174 /* for ctdb_req_control */
175 #define PROTOCOL_CTDB5_TEST(TYPE, NAME, OPER) \
176 static void TEST_FUNC(NAME)(uint32_t opcode) \
177 { \
178         TALLOC_CTX *mem_ctx; \
179         struct ctdb_req_header h1, h2; \
180         TYPE c1, c2; \
181         uint8_t *pkt; \
182         size_t pkt_len, buflen, len; \
183         int ret; \
184 \
185         printf("%s %u\n", #NAME, opcode); \
186         fflush(stdout); \
187         mem_ctx = talloc_new(NULL); \
188         assert(mem_ctx != NULL); \
189         fill_ctdb_req_header(&h1); \
190         FILL_FUNC(NAME)(mem_ctx, &c1, opcode); \
191         buflen = LEN_FUNC(NAME)(&h1, &c1); \
192         ret = ctdb_allocate_pkt(mem_ctx, buflen, &pkt, &pkt_len); \
193         assert(ret == 0); \
194         assert(pkt != NULL); \
195         assert(pkt_len >= buflen); \
196         len = 0; \
197         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &len); \
198         assert(ret == EMSGSIZE); \
199         assert(len == buflen); \
200         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &pkt_len); \
201         assert(ret == 0); \
202         ret = PULL_FUNC(NAME)(pkt, pkt_len, &h2, mem_ctx, &c2); \
203         assert(ret == 0); \
204         verify_ctdb_req_header(&h1, &h2); \
205         assert(h2.length == pkt_len); \
206         VERIFY_FUNC(NAME)(&c1, &c2); \
207         talloc_free(mem_ctx); \
208 }
209
210 /* for ctdb_reply_control */
211 #define PROTOCOL_CTDB6_TEST(TYPE, NAME, OPER) \
212 static void TEST_FUNC(NAME)(uint32_t opcode) \
213 { \
214         TALLOC_CTX *mem_ctx; \
215         struct ctdb_req_header h1, h2; \
216         TYPE c1, c2; \
217         uint8_t *pkt; \
218         size_t pkt_len, buflen, len; \
219         int ret; \
220 \
221         printf("%s %u\n", #NAME, opcode); \
222         fflush(stdout); \
223         mem_ctx = talloc_new(NULL); \
224         assert(mem_ctx != NULL); \
225         fill_ctdb_req_header(&h1); \
226         FILL_FUNC(NAME)(mem_ctx, &c1, opcode); \
227         buflen = LEN_FUNC(NAME)(&h1, &c1); \
228         ret = ctdb_allocate_pkt(mem_ctx, buflen, &pkt, &pkt_len); \
229         assert(ret == 0); \
230         assert(pkt != NULL); \
231         assert(pkt_len >= buflen); \
232         len = 0; \
233         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &len); \
234         assert(ret == EMSGSIZE); \
235         assert(len == buflen); \
236         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &pkt_len); \
237         assert(ret == 0); \
238         ret = PULL_FUNC(NAME)(pkt, pkt_len, opcode, &h2, mem_ctx, &c2); \
239         assert(ret == 0); \
240         verify_ctdb_req_header(&h1, &h2); \
241         assert(h2.length == pkt_len); \
242         VERIFY_FUNC(NAME)(&c1, &c2); \
243         talloc_free(mem_ctx); \
244 }
245
246 /* for ctdb_req_message */
247 #define PROTOCOL_CTDB7_TEST(TYPE, NAME, OPER) \
248 static void TEST_FUNC(NAME)(uint64_t srvid) \
249 { \
250         TALLOC_CTX *mem_ctx; \
251         struct ctdb_req_header h1, h2; \
252         TYPE c1, c2; \
253         uint8_t *pkt; \
254         size_t pkt_len, buflen, len; \
255         int ret; \
256 \
257         printf("%s %"PRIx64"\n", #NAME, srvid); \
258         fflush(stdout); \
259         mem_ctx = talloc_new(NULL); \
260         assert(mem_ctx != NULL); \
261         fill_ctdb_req_header(&h1); \
262         FILL_FUNC(NAME)(mem_ctx, &c1, srvid); \
263         buflen = LEN_FUNC(NAME)(&h1, &c1); \
264         ret = ctdb_allocate_pkt(mem_ctx, buflen, &pkt, &pkt_len); \
265         assert(ret == 0); \
266         assert(pkt != NULL); \
267         assert(pkt_len >= buflen); \
268         len = 0; \
269         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &len); \
270         assert(ret == EMSGSIZE); \
271         assert(len == buflen); \
272         ret = PUSH_FUNC(NAME)(&h1, &c1, pkt, &pkt_len); \
273         assert(ret == 0); \
274         ret = PULL_FUNC(NAME)(pkt, pkt_len, &h2, mem_ctx, &c2); \
275         assert(ret == 0); \
276         verify_ctdb_req_header(&h1, &h2); \
277         assert(h2.length == pkt_len); \
278         VERIFY_FUNC(NAME)(&c1, &c2); \
279         talloc_free(mem_ctx); \
280 }
281
282 PROTOCOL_CTDB1_TEST(struct ctdb_req_header, ctdb_req_header);
283
284 PROTOCOL_CTDB4_TEST(struct ctdb_req_call, ctdb_req_call, CTDB_REQ_CALL);
285 PROTOCOL_CTDB4_TEST(struct ctdb_reply_call, ctdb_reply_call, CTDB_REPLY_CALL);
286 PROTOCOL_CTDB4_TEST(struct ctdb_reply_error, ctdb_reply_error,
287                         CTDB_REPLY_ERROR);
288 PROTOCOL_CTDB4_TEST(struct ctdb_req_dmaster, ctdb_req_dmaster,
289                         CTDB_REQ_DMASTER);
290 PROTOCOL_CTDB4_TEST(struct ctdb_reply_dmaster, ctdb_reply_dmaster,
291                         CTDB_REPLY_DMASTER);
292
293 #define NUM_CONTROLS    151
294
295 PROTOCOL_CTDB2_TEST(struct ctdb_req_control_data, ctdb_req_control_data);
296 PROTOCOL_CTDB2_TEST(struct ctdb_reply_control_data, ctdb_reply_control_data);
297
298 PROTOCOL_CTDB5_TEST(struct ctdb_req_control, ctdb_req_control,
299                         CTDB_REQ_CONTROL);
300 PROTOCOL_CTDB6_TEST(struct ctdb_reply_control, ctdb_reply_control,
301                         CTDB_REPLY_CONTROL);
302
303 PROTOCOL_CTDB3_TEST(union ctdb_message_data, ctdb_message_data);
304 PROTOCOL_CTDB7_TEST(struct ctdb_req_message, ctdb_req_message,
305                         CTDB_REQ_MESSAGE);
306 PROTOCOL_CTDB4_TEST(struct ctdb_req_message_data, ctdb_req_message_data,
307                         CTDB_REQ_MESSAGE);
308
309 PROTOCOL_CTDB4_TEST(struct ctdb_req_keepalive, ctdb_req_keepalive,
310                         CTDB_REQ_KEEPALIVE);
311
312 int main(int argc, char *argv[])
313 {
314         uint32_t opcode;
315         uint64_t test_srvid[] = {
316                 CTDB_SRVID_BANNING,
317                 CTDB_SRVID_ELECTION,
318                 CTDB_SRVID_RECONFIGURE,
319                 CTDB_SRVID_RELEASE_IP,
320                 CTDB_SRVID_TAKE_IP,
321                 CTDB_SRVID_SET_NODE_FLAGS,
322                 CTDB_SRVID_RECD_UPDATE_IP,
323                 CTDB_SRVID_VACUUM_FETCH,
324                 CTDB_SRVID_DETACH_DATABASE,
325                 CTDB_SRVID_MEM_DUMP,
326                 CTDB_SRVID_GETLOG,
327                 CTDB_SRVID_CLEARLOG,
328                 CTDB_SRVID_PUSH_NODE_FLAGS,
329                 CTDB_SRVID_RELOAD_NODES,
330                 CTDB_SRVID_TAKEOVER_RUN,
331                 CTDB_SRVID_REBALANCE_NODE,
332                 CTDB_SRVID_DISABLE_TAKEOVER_RUNS,
333                 CTDB_SRVID_DISABLE_RECOVERIES,
334                 CTDB_SRVID_DISABLE_IP_CHECK,
335         };
336         int i;
337
338         if (argc == 2) {
339                 int seed = atoi(argv[1]);
340                 srandom(seed);
341         }
342
343         TEST_FUNC(ctdb_req_header)();
344
345         TEST_FUNC(ctdb_req_call)();
346         TEST_FUNC(ctdb_reply_call)();
347         TEST_FUNC(ctdb_reply_error)();
348         TEST_FUNC(ctdb_req_dmaster)();
349         TEST_FUNC(ctdb_reply_dmaster)();
350
351         for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
352                 TEST_FUNC(ctdb_req_control_data)(opcode);
353         }
354         for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
355                 TEST_FUNC(ctdb_reply_control_data)(opcode);
356         }
357
358         for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
359                 TEST_FUNC(ctdb_req_control)(opcode);
360         }
361         for (opcode=0; opcode<NUM_CONTROLS; opcode++) {
362                 TEST_FUNC(ctdb_reply_control)(opcode);
363         }
364
365         for (i=0; i<ARRAY_SIZE(test_srvid); i++) {
366                 TEST_FUNC(ctdb_message_data)(test_srvid[i]);
367         }
368         for (i=0; i<ARRAY_SIZE(test_srvid); i++) {
369                 TEST_FUNC(ctdb_req_message)(test_srvid[i]);
370         }
371         TEST_FUNC(ctdb_req_message_data)();
372
373         TEST_FUNC(ctdb_req_keepalive)();
374
375         return 0;
376 }