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