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