s3-smbd: smbclient shows no error if deleting a directory with del failed
[Samba/wip.git] / ctdb / tests / src / ctdb_test_stubs.c
blob456b1fdc0ce8fe66d1724c028687842144ab821e
1 /*
2 Test stubs and support functions for some CTDB client functions
4 Copyright (C) Martin Schwenke 2011
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/>.
20 /* Read a nodemap from stdin. Each line looks like:
21 * <PNN> <FLAGS> [RECMASTER] [CURRENT]
22 * EOF or a blank line terminates input.
24 void ctdb_test_stubs_read_nodemap(struct ctdb_context *ctdb)
26 char line[1024];
28 TALLOC_FREE(ctdb->nodes);
29 ctdb->pnn = -1;
30 ctdb->num_nodes = 0;
32 ctdb->nodes = NULL;
34 while ((fgets(line, sizeof(line), stdin) != NULL) &&
35 (line[0] != '\n')) {
36 uint32_t pnn, flags;
37 char *tok, *t;
38 const char *ip;
39 ctdb_sock_addr saddr;
41 /* Get rid of pesky newline */
42 if ((t = strchr(line, '\n')) != NULL) {
43 *t = '\0';
46 /* Get PNN */
47 tok = strtok(line, " \t");
48 if (tok == NULL) {
49 DEBUG(DEBUG_ERR, (__location__ " WARNING, bad line (PNN) ignored \"%s\"\n", line));
50 continue;
52 pnn = (uint32_t)strtoul(tok, NULL, 0);
54 /* Get IP */
55 tok = strtok(NULL, " \t");
56 if (tok == NULL) {
57 DEBUG(DEBUG_ERR, (__location__ " WARNING, bad line (no IP) ignored \"%s\"\n", line));
58 continue;
60 if (!parse_ip(tok, NULL, 0, &saddr)) {
61 DEBUG(DEBUG_ERR, (__location__ " WARNING, bad line (IP) ignored \"%s\"\n", line));
62 continue;
64 ip = talloc_strdup(ctdb, tok);
66 /* Get flags */
67 tok = strtok(NULL, " \t");
68 if (tok == NULL) {
69 DEBUG(DEBUG_ERR, (__location__ " WARNING, bad line (flags) ignored \"%s\"\n", line));
70 continue;
72 flags = (uint32_t)strtoul(tok, NULL, 0);
74 tok = strtok(NULL, " \t");
75 while (tok != NULL) {
76 if (strcmp(tok, "CURRENT") == 0) {
77 ctdb->pnn = pnn;
78 } else if (strcmp(tok, "RECMASTER") == 0) {
79 ctdb->recovery_master = pnn;
81 tok = strtok(NULL, " \t");
84 ctdb->nodes = talloc_realloc(ctdb, ctdb->nodes, struct ctdb_node *, ctdb->num_nodes + 1);
85 if (ctdb->nodes == NULL) {
86 DEBUG(DEBUG_ERR, ("OOM allocating nodes array\n"));
87 exit (1);
89 ctdb->nodes[ctdb->num_nodes] = talloc_zero(ctdb, struct ctdb_node);
90 if (ctdb->nodes[ctdb->num_nodes] == NULL) {
91 DEBUG(DEBUG_ERR, ("OOM allocating node structure\n"));
92 exit (1);
95 ctdb->nodes[ctdb->num_nodes]->ctdb = ctdb;
96 ctdb->nodes[ctdb->num_nodes]->name = "fakectdb";
97 ctdb->nodes[ctdb->num_nodes]->pnn = pnn;
98 ctdb->nodes[ctdb->num_nodes]->address.address = ip;
99 ctdb->nodes[ctdb->num_nodes]->address.port = 0;
100 ctdb->nodes[ctdb->num_nodes]->flags = flags;
101 ctdb->num_nodes++;
105 void ctdb_test_stubs_print_nodemap(struct ctdb_context *ctdb)
107 int i;
109 for (i = 0; i < ctdb->num_nodes; i++) {
110 printf("%ld\t0x%lx%s%s\n",
111 (unsigned long) ctdb->nodes[i]->pnn,
112 (unsigned long) ctdb->nodes[i]->flags,
113 ctdb->nodes[i]->pnn == ctdb->pnn ? "\tCURRENT" : "",
114 ctdb->nodes[i]->pnn == ctdb->recovery_master ? "\tRECMASTER" : "");
118 /* Read interfaces information. Same format as "ctdb ifaces -Y"
119 * output:
120 * :Name:LinkStatus:References:
121 * :eth2:1:4294967294
122 * :eth1:1:4294967292
125 struct ctdb_iface {
126 struct ctdb_iface *prev, *next;
127 const char *name;
128 bool link_up;
129 uint32_t references;
132 void ctdb_test_stubs_read_ifaces(struct ctdb_context *ctdb)
134 char line[1024];
135 struct ctdb_iface *iface;
137 while ((fgets(line, sizeof(line), stdin) != NULL) &&
138 (line[0] != '\n')) {
139 uint16_t link_state;
140 uint32_t references;
141 char *tok, *t, *name;
143 /* Get rid of pesky newline */
144 if ((t = strchr(line, '\n')) != NULL) {
145 *t = '\0';
148 if (strcmp(line, ":Name:LinkStatus:References:") == 0) {
149 continue;
152 /* name */
153 //tok = strtok(line, ":"); /* Leading colon... */
154 tok = strtok(line, ":");
155 if (tok == NULL) {
156 DEBUG(DEBUG_ERR, (__location__ " WARNING, bad line ignored \"%s\"\n", line));
157 continue;
159 name = tok;
161 /* link_state */
162 tok = strtok(NULL, ":");
163 if (tok == NULL) {
164 DEBUG(DEBUG_ERR, (__location__ " WARNING, bad line ignored \"%s\"\n", line));
165 continue;
167 link_state = (uint16_t)strtoul(tok, NULL, 0);
169 /* references... */
170 tok = strtok(NULL, ":");
171 if (tok == NULL) {
172 DEBUG(DEBUG_ERR, (__location__ " WARNING, bad line ignored \"%s\"\n", line));
173 continue;
175 references = (uint32_t)strtoul(tok, NULL, 0);
177 iface = talloc_zero(ctdb, struct ctdb_iface);
179 if (iface == NULL) {
180 DEBUG(DEBUG_ERR, ("OOM allocating iface\n"));
181 exit (1);
184 iface->name = talloc_strdup(iface, name);
185 iface->link_up = link_state;
186 iface->references = references;
188 DLIST_ADD(ctdb->ifaces, iface);
192 void ctdb_test_stubs_print_ifaces(struct ctdb_context *ctdb)
194 struct ctdb_iface *iface;
196 printf(":Name:LinkStatus:References:\n");
197 for (iface = ctdb->ifaces; iface != NULL; iface = iface->next) {
198 printf(":%s:%u:%u:\n",
199 iface->name,
200 iface->link_up,
201 iface->references);
205 /* Read vnn map.
206 * output:
207 * <GENERATION>
208 * <LMASTER0>
209 * <LMASTER1>
210 * ...
214 struct ctdb_vnn_map {
215 uint32_t generation;
216 uint32_t size;
217 uint32_t *map;
220 void ctdb_test_stubs_read_vnnmap(struct ctdb_context *ctdb)
222 char line[1024];
224 TALLOC_FREE(ctdb->vnn_map);
226 ctdb->vnn_map = talloc_zero(ctdb, struct ctdb_vnn_map);
227 if (ctdb->vnn_map == NULL) {
228 DEBUG(DEBUG_ERR, ("OOM allocating vnnmap\n"));
229 exit (1);
231 ctdb->vnn_map->generation = INVALID_GENERATION;
232 ctdb->vnn_map->size = 0;
233 ctdb->vnn_map->map = NULL;
235 while ((fgets(line, sizeof(line), stdin) != NULL) &&
236 (line[0] != '\n')) {
237 uint32_t n;
238 char *t;
240 /* Get rid of pesky newline */
241 if ((t = strchr(line, '\n')) != NULL) {
242 *t = '\0';
245 n = (uint32_t) strtol(line, NULL, 0);
247 /* generation */
248 if (ctdb->vnn_map->generation == INVALID_GENERATION) {
249 ctdb->vnn_map->generation = n;
250 continue;
253 ctdb->vnn_map->map = talloc_realloc(ctdb, ctdb->vnn_map->map, uint32_t, ctdb->vnn_map->size + 1);
254 if (ctdb->vnn_map->map == NULL) {
255 DEBUG(DEBUG_ERR, ("OOM allocating vnn_map->map\n"));
256 exit (1);
259 ctdb->vnn_map->map[ctdb->vnn_map->size] = n;
260 ctdb->vnn_map->size++;
264 void ctdb_test_stubs_print_vnnmap(struct ctdb_context *ctdb)
266 int i;
268 printf("%d\n", ctdb->vnn_map->generation);
269 for (i = 0; i < ctdb->vnn_map->size; i++) {
270 printf("%d\n", ctdb->vnn_map->map[i]);
274 void ctdb_test_stubs_fake_setup(struct ctdb_context *ctdb)
276 char line[1024];
278 while (fgets(line, sizeof(line), stdin) != NULL) {
279 char *t;
281 /* Get rid of pesky newline */
282 if ((t = strchr(line, '\n')) != NULL) {
283 *t = '\0';
286 if (strcmp(line, "NODEMAP") == 0) {
287 ctdb_test_stubs_read_nodemap(ctdb);
288 } else if (strcmp(line, "IFACES") == 0) {
289 ctdb_test_stubs_read_ifaces(ctdb);
290 } else if (strcmp(line, "VNNMAP") == 0) {
291 ctdb_test_stubs_read_vnnmap(ctdb);
292 } else {
293 printf("Unknown line %s\n", line);
294 exit(1);
299 /* Support... */
300 static bool current_node_is_connected (struct ctdb_context *ctdb)
302 int i;
303 for (i = 0; i < ctdb->num_nodes; i++) {
304 if (ctdb->nodes[i]->pnn == ctdb->pnn) {
305 if (ctdb->nodes[i]->flags &
306 (NODE_FLAGS_DISCONNECTED | NODE_FLAGS_DELETED)) {
307 return false;
308 } else {
309 return true;
314 /* Shouldn't really happen, so fag an error */
315 return false;
318 /* Stubs... */
320 struct ctdb_context *ctdb_cmdline_client_stub(struct tevent_context *ev,
321 struct timeval req_timeout)
323 struct ctdb_context *ctdb;
325 ctdb = talloc_zero(NULL, struct ctdb_context);
327 ctdb_set_socketname(ctdb, "fake");
329 ctdb_test_stubs_fake_setup(ctdb);
331 return ctdb;
334 /* Copied from ctdb_recover.c */
336 ctdb_control_getnodemap(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA indata, TDB_DATA *outdata)
338 uint32_t i, num_nodes;
339 struct ctdb_node_map *node_map;
341 CHECK_CONTROL_DATA_SIZE(0);
343 num_nodes = ctdb->num_nodes;
345 outdata->dsize = offsetof(struct ctdb_node_map, nodes) + num_nodes*sizeof(struct ctdb_node_and_flags);
346 outdata->dptr = (unsigned char *)talloc_zero_size(outdata, outdata->dsize);
347 if (!outdata->dptr) {
348 DEBUG(DEBUG_ALERT, (__location__ " Failed to allocate nodemap array\n"));
349 exit(1);
352 node_map = (struct ctdb_node_map *)outdata->dptr;
353 node_map->num = num_nodes;
354 for (i=0; i<num_nodes; i++) {
355 if (parse_ip(ctdb->nodes[i]->address.address,
356 NULL, /* TODO: pass in the correct interface here*/
358 &node_map->nodes[i].addr) == 0)
360 DEBUG(DEBUG_ERR, (__location__ " Failed to parse %s into a sockaddr\n", ctdb->nodes[i]->address.address));
363 node_map->nodes[i].pnn = ctdb->nodes[i]->pnn;
364 node_map->nodes[i].flags = ctdb->nodes[i]->flags;
367 return 0;
371 ctdb_ctrl_getnodemap_stub(struct ctdb_context *ctdb,
372 struct timeval timeout, uint32_t destnode,
373 TALLOC_CTX *mem_ctx,
374 struct ctdb_node_map **nodemap)
376 int ret;
378 TDB_DATA indata;
379 TDB_DATA *outdata;
381 if (!current_node_is_connected(ctdb)) {
382 return -1;
385 indata.dsize = 0;
386 indata.dptr = NULL;
388 outdata = talloc_zero(ctdb, TDB_DATA);
390 ret = ctdb_control_getnodemap(ctdb, CTDB_CONTROL_GET_NODEMAP,
391 indata, outdata);
393 if (ret == 0) {
394 *nodemap = (struct ctdb_node_map *) outdata->dptr;
397 return ret;
401 ctdb_ctrl_getvnnmap_stub(struct ctdb_context *ctdb,
402 struct timeval timeout, uint32_t destnode,
403 TALLOC_CTX *mem_ctx, struct ctdb_vnn_map **vnnmap)
405 *vnnmap = talloc(ctdb, struct ctdb_vnn_map);
406 if (*vnnmap == NULL) {
407 DEBUG(DEBUG_ERR, (__location__ "OOM\n"));
408 exit (1);
410 (*vnnmap)->map = talloc_array(*vnnmap, uint32_t, ctdb->vnn_map->size);
412 (*vnnmap)->generation = ctdb->vnn_map->generation;
413 (*vnnmap)->size = ctdb->vnn_map->size;
414 memcpy((*vnnmap)->map, ctdb->vnn_map->map, sizeof(uint32_t) * (*vnnmap)->size);
416 return 0;
420 ctdb_ctrl_getrecmode_stub(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx,
421 struct timeval timeout, uint32_t destnode,
422 uint32_t *recmode)
424 *recmode = ctdb->recovery_mode;
426 return 0;
430 ctdb_ctrl_getrecmaster_stub(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx,
431 struct timeval timeout, uint32_t destnode,
432 uint32_t *recmaster)
434 *recmaster = ctdb->recovery_master;
436 return 0;
440 ctdb_ctrl_getpnn_stub(struct ctdb_context *ctdb, struct timeval timeout,
441 uint32_t destnode)
443 if (!current_node_is_connected(ctdb)) {
444 return -1;
447 if (destnode == CTDB_CURRENT_NODE) {
448 return ctdb->pnn;
449 } else {
450 return destnode;
454 /* From ctdb_takeover.c */
455 int32_t ctdb_control_get_ifaces(struct ctdb_context *ctdb,
456 struct ctdb_req_control *c,
457 TDB_DATA *outdata)
459 int i, num, len;
460 struct ctdb_control_get_ifaces *ifaces;
461 struct ctdb_iface *cur;
463 /* count how many public ip structures we have */
464 num = 0;
465 for (cur=ctdb->ifaces;cur;cur=cur->next) {
466 num++;
469 len = offsetof(struct ctdb_control_get_ifaces, ifaces) +
470 num*sizeof(struct ctdb_control_iface_info);
471 ifaces = talloc_zero_size(outdata, len);
472 CTDB_NO_MEMORY(ctdb, ifaces);
474 i = 0;
475 for (cur=ctdb->ifaces;cur;cur=cur->next) {
476 strcpy(ifaces->ifaces[i].name, cur->name);
477 ifaces->ifaces[i].link_state = cur->link_up;
478 ifaces->ifaces[i].references = cur->references;
479 i++;
481 ifaces->num = i;
482 len = offsetof(struct ctdb_control_get_ifaces, ifaces) +
483 i*sizeof(struct ctdb_control_iface_info);
485 outdata->dsize = len;
486 outdata->dptr = (uint8_t *)ifaces;
488 return 0;
492 ctdb_ctrl_get_ifaces_stub(struct ctdb_context *ctdb,
493 struct timeval timeout, uint32_t destnode,
494 TALLOC_CTX *mem_ctx,
495 struct ctdb_control_get_ifaces **ifaces)
497 TDB_DATA *outdata;
498 int ret;
500 if (!current_node_is_connected(ctdb)) {
501 return -1;
504 outdata = talloc(mem_ctx, TDB_DATA);
506 ret = ctdb_control_get_ifaces(ctdb, NULL, outdata);
508 if (ret == 0) {
509 *ifaces = (struct ctdb_control_get_ifaces *)outdata->dptr;
512 return ret;
515 int ctdb_client_check_message_handlers_stub(struct ctdb_context *ctdb,
516 uint64_t *ids, uint32_t num,
517 uint8_t *result)
519 DEBUG(DEBUG_ERR, (__location__ " NOT IMPLEMENTED\n"));
520 return -1;
523 int ctdb_ctrl_getcapabilities_stub(struct ctdb_context *ctdb,
524 struct timeval timeout, uint32_t destnode,
525 uint32_t *capabilities)
527 *capabilities = CTDB_CAP_RECMASTER|CTDB_CAP_LMASTER|CTDB_CAP_NATGW;
528 return 0;