2 Unix SMB/CIFS implementation.
4 WINS replication testing
6 Copyright (C) Andrew Tridgell 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "libcli/nbt/libnbt.h"
25 #include "libcli/wrepl/winsrepl.h"
27 #define CHECK_STATUS(status, correct) do { \
28 if (!NT_STATUS_EQUAL(status, correct)) { \
29 printf("(%s) Incorrect status %s - should be %s\n", \
30 __location__, nt_errstr(status), nt_errstr(correct)); \
35 #define CHECK_VALUE(v, correct) do { \
36 if ((v) != (correct)) { \
37 printf("(%s) Incorrect value %s=%d - should be %d\n", \
38 __location__, #v, v, correct); \
43 #define CHECK_VALUE_UINT64(v, correct) do { \
44 if ((v) != (correct)) { \
45 printf("(%s) Incorrect value %s=%llu - should be %llu\n", \
46 __location__, #v, v, correct); \
51 #define CHECK_VALUE_STRING(v, correct) do { \
52 if ( ((!v) && (correct)) || \
53 ((v) && (!correct)) || \
54 ((v) && (correct) && strcmp(v,correct) != 0)) { \
55 printf("(%s) Incorrect value %s='%s' - should be '%s'\n", \
56 __location__, #v, v, correct); \
61 #define _NBT_NAME(n,t,s) {\
67 static const char *wrepl_name_type_string(enum wrepl_name_type type)
70 case WREPL_TYPE_UNIQUE: return "UNIQUE";
71 case WREPL_TYPE_GROUP: return "GROUP";
72 case WREPL_TYPE_SGROUP: return "SGROUP";
73 case WREPL_TYPE_MHOMED: return "MHOMED";
75 return "UNKNOWN_TYPE";
78 static const char *wrepl_name_state_string(enum wrepl_name_state state)
81 case WREPL_STATE_ACTIVE: return "ACTIVE";
82 case WREPL_STATE_RELEASED: return "RELEASED";
83 case WREPL_STATE_TOMBSTONE: return "TOMBSTONE";
84 case WREPL_STATE_RESERVED: return "RESERVED";
86 return "UNKNOWN_STATE";
90 test how assoc_ctx's are only usable on the connection
93 static BOOL test_assoc_ctx1(TALLOC_CTX *mem_ctx, const char *address)
96 struct wrepl_request *req;
97 struct wrepl_socket *wrepl_socket1;
98 struct wrepl_associate associate1;
99 struct wrepl_socket *wrepl_socket2;
100 struct wrepl_associate associate2;
101 struct wrepl_pull_table pull_table;
102 struct wrepl_packet *rep_packet;
103 struct wrepl_associate_stop assoc_stop;
106 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
107 printf("winsrepl: cross connection assoc_ctx usage disabled - enable dangerous tests to use\n");
111 printf("Test if assoc_ctx is only valid on the conection it was created on\n");
113 wrepl_socket1 = wrepl_socket_init(mem_ctx, NULL);
114 wrepl_socket2 = wrepl_socket_init(mem_ctx, NULL);
116 printf("Setup 2 wrepl connections\n");
117 status = wrepl_connect(wrepl_socket1, NULL, address);
118 CHECK_STATUS(status, NT_STATUS_OK);
120 status = wrepl_connect(wrepl_socket2, NULL, address);
121 CHECK_STATUS(status, NT_STATUS_OK);
123 printf("Send a start association request (conn1)\n");
124 status = wrepl_associate(wrepl_socket1, &associate1);
125 CHECK_STATUS(status, NT_STATUS_OK);
127 printf("association context (conn1): 0x%x\n", associate1.out.assoc_ctx);
129 printf("Send a start association request (conn2)\n");
130 status = wrepl_associate(wrepl_socket2, &associate2);
131 CHECK_STATUS(status, NT_STATUS_OK);
133 printf("association context (conn2): 0x%x\n", associate2.out.assoc_ctx);
135 printf("Send a replication table query, with assoc 1 (conn2), the anwser should be on conn1\n");
136 pull_table.in.assoc_ctx = associate1.out.assoc_ctx;
137 req = wrepl_pull_table_send(wrepl_socket2, &pull_table);
138 req->send_only = True;
139 status = wrepl_request_recv(req, mem_ctx, &rep_packet);
140 CHECK_STATUS(status, NT_STATUS_OK);
142 printf("Send a association request (conn2), to make sure the last request was ignored\n");
143 status = wrepl_associate(wrepl_socket2, &associate2);
144 CHECK_STATUS(status, NT_STATUS_OK);
146 printf("Send a replication table query, with invalid assoc (conn1), receive answer from conn2\n");
147 pull_table.in.assoc_ctx = 0;
148 req = wrepl_pull_table_send(wrepl_socket1, &pull_table);
149 status = wrepl_request_recv(req, mem_ctx, &rep_packet);
150 CHECK_STATUS(status, NT_STATUS_OK);
152 printf("Send a association request (conn1), to make sure the last request was handled correct\n");
153 status = wrepl_associate(wrepl_socket1, &associate2);
154 CHECK_STATUS(status, NT_STATUS_OK);
156 assoc_stop.in.assoc_ctx = associate1.out.assoc_ctx;
157 assoc_stop.in.reason = 4;
158 printf("Send a association stop request (conn1), reson: %u\n", assoc_stop.in.reason);
159 status = wrepl_associate_stop(wrepl_socket1, &assoc_stop);
160 CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
162 assoc_stop.in.assoc_ctx = associate2.out.assoc_ctx;
163 assoc_stop.in.reason = 0;
164 printf("Send a association stop request (conn2), reson: %u\n", assoc_stop.in.reason);
165 status = wrepl_associate_stop(wrepl_socket2, &assoc_stop);
166 CHECK_STATUS(status, NT_STATUS_OK);
169 printf("Close 2 wrepl connections\n");
170 talloc_free(wrepl_socket1);
171 talloc_free(wrepl_socket2);
176 test if we always get back the same assoc_ctx
178 static BOOL test_assoc_ctx2(TALLOC_CTX *mem_ctx, const char *address)
181 struct wrepl_socket *wrepl_socket;
182 struct wrepl_associate associate;
186 printf("Test if we always get back the same assoc_ctx\n");
188 wrepl_socket = wrepl_socket_init(mem_ctx, NULL);
190 printf("Setup wrepl connections\n");
191 status = wrepl_connect(wrepl_socket, NULL, address);
192 CHECK_STATUS(status, NT_STATUS_OK);
195 printf("Send 1st start association request\n");
196 status = wrepl_associate(wrepl_socket, &associate);
197 CHECK_STATUS(status, NT_STATUS_OK);
198 assoc_ctx1 = associate.out.assoc_ctx;
199 printf("1st association context: 0x%x\n", associate.out.assoc_ctx);
201 printf("Send 2nd start association request\n");
202 status = wrepl_associate(wrepl_socket, &associate);
203 CHECK_VALUE(associate.out.assoc_ctx, assoc_ctx1);
204 CHECK_STATUS(status, NT_STATUS_OK);
205 printf("2nd association context: 0x%x\n", associate.out.assoc_ctx);
207 printf("Send 3rd start association request\n");
208 status = wrepl_associate(wrepl_socket, &associate);
209 CHECK_VALUE(associate.out.assoc_ctx, assoc_ctx1);
210 CHECK_STATUS(status, NT_STATUS_OK);
211 printf("3rd association context: 0x%x\n", associate.out.assoc_ctx);
214 printf("Close wrepl connections\n");
215 talloc_free(wrepl_socket);
221 display a replication entry
223 static void display_entry(TALLOC_CTX *mem_ctx, struct wrepl_name *name)
227 printf("%s\n", nbt_name_string(mem_ctx, &name->name));
228 printf("\tTYPE:%u STATE:%u NODE:%u STATIC:%u VERSION_ID: %llu\n",
229 name->type, name->state, name->node, name->is_static, name->version_id);
230 printf("\tRAW_FLAGS: 0x%08X OWNER: %-15s\n",
231 name->raw_flags, name->owner);
232 for (i=0;i<name->num_addresses;i++) {
233 printf("\tADDR: %-15s OWNER: %-15s\n",
234 name->addresses[i].address, name->addresses[i].owner);
239 test a full replication dump from a WINS server
241 static BOOL test_wins_replication(TALLOC_CTX *mem_ctx, const char *address)
244 struct wrepl_socket *wrepl_socket;
247 struct wrepl_associate associate;
248 struct wrepl_pull_table pull_table;
249 struct wrepl_pull_names pull_names;
251 printf("Test one pull replication cycle\n");
253 wrepl_socket = wrepl_socket_init(mem_ctx, NULL);
255 printf("Setup wrepl connections\n");
256 status = wrepl_connect(wrepl_socket, NULL, address);
257 CHECK_STATUS(status, NT_STATUS_OK);
259 printf("Send a start association request\n");
261 status = wrepl_associate(wrepl_socket, &associate);
262 CHECK_STATUS(status, NT_STATUS_OK);
264 printf("association context: 0x%x\n", associate.out.assoc_ctx);
266 printf("Send a replication table query\n");
267 pull_table.in.assoc_ctx = associate.out.assoc_ctx;
269 status = wrepl_pull_table(wrepl_socket, mem_ctx, &pull_table);
270 if (NT_STATUS_EQUAL(NT_STATUS_NETWORK_ACCESS_DENIED,status)) {
271 struct wrepl_packet packet;
272 struct wrepl_request *req;
275 packet.opcode = WREPL_OPCODE_BITS;
276 packet.assoc_ctx = associate.out.assoc_ctx;
277 packet.mess_type = WREPL_STOP_ASSOCIATION;
278 packet.message.stop.reason = 0;
280 req = wrepl_request_send(wrepl_socket, &packet);
283 printf("failed - We are not a valid pull partner for the server\n");
287 CHECK_STATUS(status, NT_STATUS_OK);
289 printf("Found %d replication partners\n", pull_table.out.num_partners);
291 for (i=0;i<pull_table.out.num_partners;i++) {
292 struct wrepl_wins_owner *partner = &pull_table.out.partners[i];
293 printf("%s max_version=%6llu min_version=%6llu type=%d\n",
295 partner->max_version,
296 partner->min_version,
299 pull_names.in.assoc_ctx = associate.out.assoc_ctx;
300 pull_names.in.partner = *partner;
302 status = wrepl_pull_names(wrepl_socket, mem_ctx, &pull_names);
303 CHECK_STATUS(status, NT_STATUS_OK);
305 printf("Received %d names\n", pull_names.out.num_names);
307 for (j=0;j<pull_names.out.num_names;j++) {
308 display_entry(mem_ctx, &pull_names.out.names[j]);
313 printf("Close wrepl connections\n");
314 talloc_free(wrepl_socket);
318 struct test_wrepl_conflict_conn {
320 struct wrepl_socket *pull;
323 #define TEST_OWNER_A_ADDRESS "127.65.65.1"
324 #define TEST_ADDRESS_A_PREFIX "127.0.65"
325 #define TEST_OWNER_B_ADDRESS "127.66.66.1"
326 #define TEST_ADDRESS_B_PREFIX "127.0.66"
328 struct wrepl_wins_owner a, b;
331 static const struct wrepl_ip addresses_A_1[] = {
333 .owner = TEST_OWNER_A_ADDRESS,
334 .ip = TEST_ADDRESS_A_PREFIX".1"
337 static const struct wrepl_ip addresses_A_2[] = {
339 .owner = TEST_OWNER_A_ADDRESS,
340 .ip = TEST_ADDRESS_A_PREFIX".2"
343 static const struct wrepl_ip addresses_A_3_4[] = {
345 .owner = TEST_OWNER_A_ADDRESS,
346 .ip = TEST_ADDRESS_A_PREFIX".3"
349 .owner = TEST_OWNER_A_ADDRESS,
350 .ip = TEST_ADDRESS_A_PREFIX".4"
354 static const struct wrepl_ip addresses_B_1[] = {
356 .owner = TEST_OWNER_B_ADDRESS,
357 .ip = TEST_ADDRESS_B_PREFIX".1"
360 static const struct wrepl_ip addresses_B_2[] = {
362 .owner = TEST_OWNER_B_ADDRESS,
363 .ip = TEST_ADDRESS_B_PREFIX".2"
366 static const struct wrepl_ip addresses_B_3_4[] = {
368 .owner = TEST_OWNER_B_ADDRESS,
369 .ip = TEST_ADDRESS_B_PREFIX".3"
372 .owner = TEST_OWNER_B_ADDRESS,
373 .ip = TEST_ADDRESS_B_PREFIX".4"
377 static struct test_wrepl_conflict_conn *test_create_conflict_ctx(TALLOC_CTX *mem_ctx,
380 struct test_wrepl_conflict_conn *ctx;
381 struct wrepl_associate associate;
382 struct wrepl_pull_table pull_table;
386 ctx = talloc_zero(mem_ctx, struct test_wrepl_conflict_conn);
387 if (!ctx) return NULL;
389 ctx->address = address;
390 ctx->pull = wrepl_socket_init(ctx, NULL);
391 if (!ctx->pull) return NULL;
393 printf("Setup wrepl conflict pull connection\n");
394 status = wrepl_connect(ctx->pull, NULL, ctx->address);
395 if (!NT_STATUS_IS_OK(status)) return NULL;
397 status = wrepl_associate(ctx->pull, &associate);
398 if (!NT_STATUS_IS_OK(status)) return NULL;
400 ctx->pull_assoc = associate.out.assoc_ctx;
402 ctx->a.address = TEST_OWNER_A_ADDRESS;
403 ctx->a.max_version = 0;
404 ctx->a.min_version = 0;
407 ctx->b.address = TEST_OWNER_B_ADDRESS;
408 ctx->b.max_version = 0;
409 ctx->b.min_version = 0;
412 pull_table.in.assoc_ctx = ctx->pull_assoc;
413 status = wrepl_pull_table(ctx->pull, ctx->pull, &pull_table);
414 if (!NT_STATUS_IS_OK(status)) return NULL;
416 for (i=0; i < pull_table.out.num_partners; i++) {
417 if (strcmp(TEST_OWNER_A_ADDRESS,pull_table.out.partners[i].address)==0) {
418 ctx->a.max_version = pull_table.out.partners[i].max_version;
419 ctx->a.min_version = pull_table.out.partners[i].min_version;
421 if (strcmp(TEST_OWNER_B_ADDRESS,pull_table.out.partners[i].address)==0) {
422 ctx->b.max_version = pull_table.out.partners[i].max_version;
423 ctx->b.min_version = pull_table.out.partners[i].min_version;
427 talloc_free(pull_table.out.partners);
432 static BOOL test_wrepl_update_one(struct test_wrepl_conflict_conn *ctx,
433 const struct wrepl_wins_owner *owner,
434 const struct wrepl_wins_name *name)
437 struct wrepl_socket *wrepl_socket;
438 struct wrepl_associate associate;
439 struct wrepl_packet update_packet, repl_send;
440 struct wrepl_table *update;
441 struct wrepl_wins_owner wrepl_wins_owners[1];
442 struct wrepl_packet *repl_recv;
443 struct wrepl_wins_owner *send_request;
444 struct wrepl_send_reply *send_reply;
445 struct wrepl_wins_name wrepl_wins_names[1];
449 wrepl_socket = wrepl_socket_init(ctx, NULL);
451 status = wrepl_connect(wrepl_socket, NULL, ctx->address);
452 CHECK_STATUS(status, NT_STATUS_OK);
454 status = wrepl_associate(wrepl_socket, &associate);
455 CHECK_STATUS(status, NT_STATUS_OK);
456 assoc_ctx = associate.out.assoc_ctx;
458 /* now send a WREPL_REPL_UPDATE message */
459 ZERO_STRUCT(update_packet);
460 update_packet.opcode = WREPL_OPCODE_BITS;
461 update_packet.assoc_ctx = assoc_ctx;
462 update_packet.mess_type = WREPL_REPLICATION;
463 update_packet.message.replication.command = WREPL_REPL_UPDATE;
464 update = &update_packet.message.replication.info.table;
466 update->partner_count = ARRAY_SIZE(wrepl_wins_owners);
467 update->partners = wrepl_wins_owners;
468 update->initiator = "0.0.0.0";
470 wrepl_wins_owners[0] = *owner;
472 status = wrepl_request(wrepl_socket, wrepl_socket,
473 &update_packet, &repl_recv);
474 CHECK_STATUS(status, NT_STATUS_OK);
475 CHECK_VALUE(repl_recv->mess_type, WREPL_REPLICATION);
476 CHECK_VALUE(repl_recv->message.replication.command, WREPL_REPL_SEND_REQUEST);
477 send_request = &repl_recv->message.replication.info.owner;
479 ZERO_STRUCT(repl_send);
480 repl_send.opcode = WREPL_OPCODE_BITS;
481 repl_send.assoc_ctx = assoc_ctx;
482 repl_send.mess_type = WREPL_REPLICATION;
483 repl_send.message.replication.command = WREPL_REPL_SEND_REPLY;
484 send_reply = &repl_send.message.replication.info.reply;
486 send_reply->num_names = ARRAY_SIZE(wrepl_wins_names);
487 send_reply->names = wrepl_wins_names;
489 wrepl_wins_names[0] = *name;
491 status = wrepl_request(wrepl_socket, wrepl_socket,
492 &repl_send, &repl_recv);
493 CHECK_STATUS(status, NT_STATUS_OK);
494 CHECK_VALUE(repl_recv->mess_type, WREPL_STOP_ASSOCIATION);
495 CHECK_VALUE(repl_recv->message.stop.reason, 0);
498 talloc_free(wrepl_socket);
502 static BOOL test_wrepl_is_applied(struct test_wrepl_conflict_conn *ctx,
503 const struct wrepl_wins_owner *owner,
504 const struct wrepl_wins_name *name,
509 struct wrepl_pull_names pull_names;
510 struct wrepl_name *names;
512 pull_names.in.assoc_ctx = ctx->pull_assoc;
513 pull_names.in.partner = *owner;
514 pull_names.in.partner.min_version = pull_names.in.partner.max_version;
516 status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
517 CHECK_STATUS(status, NT_STATUS_OK);
518 CHECK_VALUE(pull_names.out.num_names, (expected?1:0));
520 names = pull_names.out.names;
523 uint32_t flags = WREPL_NAME_FLAGS(names[0].type,
527 CHECK_VALUE(names[0].name.type, name->name->type);
528 CHECK_VALUE_STRING(names[0].name.name, name->name->name);
529 CHECK_VALUE_STRING(names[0].name.scope, name->name->scope);
530 CHECK_VALUE(flags, name->flags);
531 CHECK_VALUE_UINT64(names[0].version_id, name->id);
534 talloc_free(pull_names.out.names);
538 static BOOL test_conflict_same_owner(struct test_wrepl_conflict_conn *ctx)
541 struct nbt_name name;
542 struct wrepl_wins_name wins_name1;
543 struct wrepl_wins_name wins_name2;
544 struct wrepl_wins_name *wins_name_tmp;
545 struct wrepl_wins_name *wins_name_last;
546 struct wrepl_wins_name *wins_name_cur;
548 uint8_t types[] = { 0x00, 0x1C };
550 enum wrepl_name_type type;
551 enum wrepl_name_state state;
552 enum wrepl_name_node node;
555 const struct wrepl_ip *ips;
558 .type = WREPL_TYPE_GROUP,
559 .state = WREPL_STATE_ACTIVE,
560 .node = WREPL_NODE_B,
562 .num_ips = ARRAY_SIZE(addresses_A_1),
563 .ips = addresses_A_1,
565 .type = WREPL_TYPE_UNIQUE,
566 .state = WREPL_STATE_ACTIVE,
567 .node = WREPL_NODE_B,
569 .num_ips = ARRAY_SIZE(addresses_A_1),
570 .ips = addresses_A_1,
572 .type = WREPL_TYPE_UNIQUE,
573 .state = WREPL_STATE_ACTIVE,
574 .node = WREPL_NODE_B,
576 .num_ips = ARRAY_SIZE(addresses_A_2),
577 .ips = addresses_A_2,
579 .type = WREPL_TYPE_UNIQUE,
580 .state = WREPL_STATE_ACTIVE,
581 .node = WREPL_NODE_B,
583 .num_ips = ARRAY_SIZE(addresses_A_1),
584 .ips = addresses_A_1,
586 .type = WREPL_TYPE_UNIQUE,
587 .state = WREPL_STATE_ACTIVE,
588 .node = WREPL_NODE_B,
590 .num_ips = ARRAY_SIZE(addresses_A_2),
591 .ips = addresses_A_2,
593 .type = WREPL_TYPE_SGROUP,
594 .state = WREPL_STATE_TOMBSTONE,
595 .node = WREPL_NODE_B,
597 .num_ips = ARRAY_SIZE(addresses_A_2),
598 .ips = addresses_A_2,
600 .type = WREPL_TYPE_MHOMED,
601 .state = WREPL_STATE_TOMBSTONE,
602 .node = WREPL_NODE_B,
604 .num_ips = ARRAY_SIZE(addresses_A_1),
605 .ips = addresses_A_1,
607 .type = WREPL_TYPE_MHOMED,
608 .state = WREPL_STATE_RELEASED,
609 .node = WREPL_NODE_B,
611 .num_ips = ARRAY_SIZE(addresses_A_2),
612 .ips = addresses_A_2,
614 .type = WREPL_TYPE_SGROUP,
615 .state = WREPL_STATE_ACTIVE,
616 .node = WREPL_NODE_B,
618 .num_ips = ARRAY_SIZE(addresses_A_1),
619 .ips = addresses_A_1,
621 /* the last one should always be a unique,tomstone record! */
622 .type = WREPL_TYPE_UNIQUE,
623 .state = WREPL_STATE_TOMBSTONE,
624 .node = WREPL_NODE_B,
626 .num_ips = ARRAY_SIZE(addresses_A_1),
627 .ips = addresses_A_1,
631 if (!ctx) return False;
633 name.name = "_SAME_OWNER_A";
637 wins_name_tmp = NULL;
638 wins_name_last = &wins_name2;
639 wins_name_cur = &wins_name1;
641 for (j=0; ret && j < ARRAY_SIZE(types); j++) {
642 name.type = types[j];
643 printf("Test Replica Conflicts with same owner[%s] for %s\n",
644 nbt_name_string(ctx, &name), ctx->a.address);
646 for(i=0; ret && i < ARRAY_SIZE(records); i++) {
647 wins_name_tmp = wins_name_last;
648 wins_name_last = wins_name_cur;
649 wins_name_cur = wins_name_tmp;
652 printf("%s,%s%s vs, %s,%s%s with %s ip(s) => %s\n",
653 wrepl_name_type_string(records[i-1].type),
654 wrepl_name_state_string(records[i-1].state),
655 (records[i-1].is_static?",static":""),
656 wrepl_name_type_string(records[i].type),
657 wrepl_name_state_string(records[i].state),
658 (records[i].is_static?",static":""),
659 (records[i-1].ips==records[i].ips?"same":"different"),
663 wins_name_cur->name = &name;
664 wins_name_cur->flags = WREPL_NAME_FLAGS(records[i].type,
667 records[i].is_static);
668 wins_name_cur->id = ++ctx->a.max_version;
669 if (wins_name_cur->flags & 2) {
670 wins_name_cur->addresses.addresses.num_ips = records[i].num_ips;
671 wins_name_cur->addresses.addresses.ips = discard_const(records[i].ips);
673 wins_name_cur->addresses.ip = records[i].ips[0].ip;
675 wins_name_cur->unknown = "255.255.255.255";
677 ret &= test_wrepl_update_one(ctx, &ctx->a,wins_name_cur);
678 if (records[i].state == WREPL_STATE_RELEASED) {
679 ret &= test_wrepl_is_applied(ctx, &ctx->a, wins_name_last, False);
680 ret &= test_wrepl_is_applied(ctx, &ctx->a, wins_name_cur, False);
682 ret &= test_wrepl_is_applied(ctx, &ctx->a, wins_name_cur, True);
685 /* the first one is a cleanup run */
686 if (!ret && i == 0) ret = True;
689 printf("conflict handled wrong or record[%u]: %s\n", i, __location__);
697 static BOOL test_conflict_different_owner(struct test_wrepl_conflict_conn *ctx)
700 struct wrepl_wins_name wins_name1;
701 struct wrepl_wins_name wins_name2;
702 struct wrepl_wins_name *wins_name_r1;
703 struct wrepl_wins_name *wins_name_r2;
706 const char *line; /* just better debugging */
707 struct nbt_name name;
709 struct wrepl_wins_owner *owner;
710 enum wrepl_name_type type;
711 enum wrepl_name_state state;
712 enum wrepl_name_node node;
715 const struct wrepl_ip *ips;
720 * NOTE: the first record and the last applied one
721 * needs to be from the same owner,
722 * to not conflict in the next smbtorture run!!!
725 .line = __location__,
726 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
729 .type = WREPL_TYPE_UNIQUE,
730 .state = WREPL_STATE_TOMBSTONE,
731 .node = WREPL_NODE_B,
733 .num_ips = ARRAY_SIZE(addresses_B_1),
734 .ips = addresses_B_1,
735 .apply_expected = True /* ignored */
739 .type = WREPL_TYPE_UNIQUE,
740 .state = WREPL_STATE_TOMBSTONE,
741 .node = WREPL_NODE_B,
743 .num_ips = ARRAY_SIZE(addresses_A_1),
744 .ips = addresses_A_1,
745 .apply_expected = True /* ignored */
750 * unique vs unique section
753 * unique,active vs. unique,active the same ip
754 * => should be replaced
757 .line = __location__,
758 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
761 .type = WREPL_TYPE_UNIQUE,
762 .state = WREPL_STATE_ACTIVE,
763 .node = WREPL_NODE_B,
765 .num_ips = ARRAY_SIZE(addresses_A_1),
766 .ips = addresses_A_1,
767 .apply_expected = True
771 .type = WREPL_TYPE_UNIQUE,
772 .state = WREPL_STATE_ACTIVE,
773 .node = WREPL_NODE_B,
775 .num_ips = ARRAY_SIZE(addresses_A_1),
776 .ips = addresses_A_1,
777 .apply_expected = True
782 * unique,active vs. unique,tombstone the same ips
783 * => should NOT be replaced
786 .line = __location__,
787 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
790 .type = WREPL_TYPE_UNIQUE,
791 .state = WREPL_STATE_ACTIVE,
792 .node = WREPL_NODE_B,
794 .num_ips = ARRAY_SIZE(addresses_B_1),
795 .ips = addresses_B_1,
796 .apply_expected = True
800 .type = WREPL_TYPE_UNIQUE,
801 .state = WREPL_STATE_TOMBSTONE,
802 .node = WREPL_NODE_B,
804 .num_ips = ARRAY_SIZE(addresses_B_1),
805 .ips = addresses_B_1,
806 .apply_expected = False
811 * unique,tombstone vs. unique,active the same ips
812 * => should NOT be replaced
815 .line = __location__,
816 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
819 .type = WREPL_TYPE_UNIQUE,
820 .state = WREPL_STATE_TOMBSTONE,
821 .node = WREPL_NODE_B,
823 .num_ips = ARRAY_SIZE(addresses_B_1),
824 .ips = addresses_B_1,
825 .apply_expected = True
829 .type = WREPL_TYPE_UNIQUE,
830 .state = WREPL_STATE_ACTIVE,
831 .node = WREPL_NODE_B,
833 .num_ips = ARRAY_SIZE(addresses_B_1),
834 .ips = addresses_B_1,
835 .apply_expected = True
840 * unique,tombstone vs. unique,tombstone the same ips
841 * => should be replaced
844 .line = __location__,
845 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
848 .type = WREPL_TYPE_UNIQUE,
849 .state = WREPL_STATE_TOMBSTONE,
850 .node = WREPL_NODE_B,
852 .num_ips = ARRAY_SIZE(addresses_A_1),
853 .ips = addresses_A_1,
854 .apply_expected = True
858 .type = WREPL_TYPE_UNIQUE,
859 .state = WREPL_STATE_TOMBSTONE,
860 .node = WREPL_NODE_B,
862 .num_ips = ARRAY_SIZE(addresses_A_1),
863 .ips = addresses_A_1,
864 .apply_expected = True
869 * unique,active vs. unique,active the different ips
870 * => should be replaced
873 .line = __location__,
874 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
877 .type = WREPL_TYPE_UNIQUE,
878 .state = WREPL_STATE_ACTIVE,
879 .node = WREPL_NODE_B,
881 .num_ips = ARRAY_SIZE(addresses_A_1),
882 .ips = addresses_A_1,
883 .apply_expected = True
887 .type = WREPL_TYPE_UNIQUE,
888 .state = WREPL_STATE_ACTIVE,
889 .node = WREPL_NODE_B,
891 .num_ips = ARRAY_SIZE(addresses_B_1),
892 .ips = addresses_B_1,
893 .apply_expected = True
898 * unique,active vs. unique,tombstone the different ips
899 * => should NOT be replaced
902 .line = __location__,
903 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
906 .type = WREPL_TYPE_UNIQUE,
907 .state = WREPL_STATE_ACTIVE,
908 .node = WREPL_NODE_B,
910 .num_ips = ARRAY_SIZE(addresses_B_1),
911 .ips = addresses_B_1,
912 .apply_expected = True
916 .type = WREPL_TYPE_UNIQUE,
917 .state = WREPL_STATE_TOMBSTONE,
918 .node = WREPL_NODE_B,
920 .num_ips = ARRAY_SIZE(addresses_A_1),
921 .ips = addresses_A_1,
922 .apply_expected = False
927 * unique,tombstone vs. unique,active the different ips
928 * => should be replaced
931 .line = __location__,
932 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
935 .type = WREPL_TYPE_UNIQUE,
936 .state = WREPL_STATE_TOMBSTONE,
937 .node = WREPL_NODE_B,
939 .num_ips = ARRAY_SIZE(addresses_B_1),
940 .ips = addresses_B_1,
941 .apply_expected = True
945 .type = WREPL_TYPE_UNIQUE,
946 .state = WREPL_STATE_ACTIVE,
947 .node = WREPL_NODE_B,
949 .num_ips = ARRAY_SIZE(addresses_A_1),
950 .ips = addresses_A_1,
951 .apply_expected = True
956 * unique,tombstone vs. unique,tombstone the different ips
957 * => should be replaced
960 .line = __location__,
961 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
964 .type = WREPL_TYPE_UNIQUE,
965 .state = WREPL_STATE_TOMBSTONE,
966 .node = WREPL_NODE_B,
968 .num_ips = ARRAY_SIZE(addresses_A_1),
969 .ips = addresses_A_1,
970 .apply_expected = True
974 .type = WREPL_TYPE_UNIQUE,
975 .state = WREPL_STATE_TOMBSTONE,
976 .node = WREPL_NODE_B,
978 .num_ips = ARRAY_SIZE(addresses_B_1),
979 .ips = addresses_B_1,
980 .apply_expected = True
985 * unique vs normal groups section,
988 * unique,active vs. group,active
989 * => should be replaced
992 .line = __location__,
993 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
996 .type = WREPL_TYPE_UNIQUE,
997 .state = WREPL_STATE_ACTIVE,
998 .node = WREPL_NODE_B,
1000 .num_ips = ARRAY_SIZE(addresses_B_1),
1001 .ips = addresses_B_1,
1002 .apply_expected = True
1006 .type = WREPL_TYPE_GROUP,
1007 .state = WREPL_STATE_ACTIVE,
1008 .node = WREPL_NODE_B,
1010 .num_ips = ARRAY_SIZE(addresses_A_1),
1011 .ips = addresses_A_1,
1012 .apply_expected = True
1017 * unique,active vs. group,tombstone same ip
1018 * => should NOT be replaced
1021 .line = __location__,
1022 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1025 .type = WREPL_TYPE_UNIQUE,
1026 .state = WREPL_STATE_ACTIVE,
1027 .node = WREPL_NODE_B,
1029 .num_ips = ARRAY_SIZE(addresses_A_1),
1030 .ips = addresses_A_1,
1031 .apply_expected = True
1035 .type = WREPL_TYPE_GROUP,
1036 .state = WREPL_STATE_TOMBSTONE,
1037 .node = WREPL_NODE_B,
1039 .num_ips = ARRAY_SIZE(addresses_A_1),
1040 .ips = addresses_A_1,
1041 .apply_expected = False
1046 * unique,active vs. group,tombstone different ip
1047 * => should NOT be replaced
1050 .line = __location__,
1051 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1054 .type = WREPL_TYPE_UNIQUE,
1055 .state = WREPL_STATE_ACTIVE,
1056 .node = WREPL_NODE_B,
1058 .num_ips = ARRAY_SIZE(addresses_A_1),
1059 .ips = addresses_A_1,
1060 .apply_expected = True
1064 .type = WREPL_TYPE_GROUP,
1065 .state = WREPL_STATE_TOMBSTONE,
1066 .node = WREPL_NODE_B,
1068 .num_ips = ARRAY_SIZE(addresses_B_1),
1069 .ips = addresses_B_1,
1070 .apply_expected = False
1075 * unique,active vs. group,released
1076 * => should NOT be replaced
1079 .line = __location__,
1080 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1083 .type = WREPL_TYPE_UNIQUE,
1084 .state = WREPL_STATE_ACTIVE,
1085 .node = WREPL_NODE_B,
1087 .num_ips = ARRAY_SIZE(addresses_A_1),
1088 .ips = addresses_A_1,
1089 .apply_expected = True
1093 .type = WREPL_TYPE_GROUP,
1094 .state = WREPL_STATE_RELEASED,
1095 .node = WREPL_NODE_B,
1097 .num_ips = ARRAY_SIZE(addresses_B_1),
1098 .ips = addresses_B_1,
1099 .apply_expected = False
1104 * unique,tombstone vs. group,active
1105 * => should be replaced
1108 .line = __location__,
1109 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1112 .type = WREPL_TYPE_UNIQUE,
1113 .state = WREPL_STATE_TOMBSTONE,
1114 .node = WREPL_NODE_B,
1116 .num_ips = ARRAY_SIZE(addresses_A_1),
1117 .ips = addresses_A_1,
1118 .apply_expected = True
1122 .type = WREPL_TYPE_GROUP,
1123 .state = WREPL_STATE_ACTIVE,
1124 .node = WREPL_NODE_B,
1126 .num_ips = ARRAY_SIZE(addresses_B_1),
1127 .ips = addresses_B_1,
1128 .apply_expected = True
1133 * unique,tombstone vs. group,tombstone
1134 * => should be replaced
1137 .line = __location__,
1138 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1141 .type = WREPL_TYPE_UNIQUE,
1142 .state = WREPL_STATE_TOMBSTONE,
1143 .node = WREPL_NODE_B,
1145 .num_ips = ARRAY_SIZE(addresses_B_1),
1146 .ips = addresses_B_1,
1147 .apply_expected = True
1151 .type = WREPL_TYPE_GROUP,
1152 .state = WREPL_STATE_TOMBSTONE,
1153 .node = WREPL_NODE_B,
1155 .num_ips = ARRAY_SIZE(addresses_A_1),
1156 .ips = addresses_A_1,
1157 .apply_expected = True
1162 * unique,tombstone vs. group,released
1163 * => should be replaced
1166 .line = __location__,
1167 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1170 .type = WREPL_TYPE_UNIQUE,
1171 .state = WREPL_STATE_TOMBSTONE,
1172 .node = WREPL_NODE_B,
1174 .num_ips = ARRAY_SIZE(addresses_A_1),
1175 .ips = addresses_A_1,
1176 .apply_expected = True
1180 .type = WREPL_TYPE_GROUP,
1181 .state = WREPL_STATE_RELEASED,
1182 .node = WREPL_NODE_B,
1184 .num_ips = ARRAY_SIZE(addresses_B_1),
1185 .ips = addresses_B_1,
1186 .apply_expected = True
1191 * unique,released vs. group,released
1192 * => should be replaced
1194 * here we need a 2nd round to make sure
1195 * released vs. released is handled correct
1198 .line = __location__,
1199 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1202 .type = WREPL_TYPE_UNIQUE,
1203 .state = WREPL_STATE_RELEASED,
1204 .node = WREPL_NODE_B,
1206 .num_ips = ARRAY_SIZE(addresses_B_1),
1207 .ips = addresses_B_1,
1208 .apply_expected = False
1212 .type = WREPL_TYPE_GROUP,
1213 .state = WREPL_STATE_RELEASED,
1214 .node = WREPL_NODE_B,
1216 .num_ips = ARRAY_SIZE(addresses_A_1),
1217 .ips = addresses_A_1,
1218 .apply_expected = True
1222 .line = __location__,
1223 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1226 .type = WREPL_TYPE_UNIQUE,
1227 .state = WREPL_STATE_TOMBSTONE,
1228 .node = WREPL_NODE_B,
1230 .num_ips = ARRAY_SIZE(addresses_A_1),
1231 .ips = addresses_A_1,
1232 .apply_expected = False /* this should conflict with the group.released above */
1236 .type = WREPL_TYPE_GROUP,
1237 .state = WREPL_STATE_TOMBSTONE,
1238 .node = WREPL_NODE_B,
1240 .num_ips = ARRAY_SIZE(addresses_A_1),
1241 .ips = addresses_A_1,
1242 .apply_expected = True
1247 * unique vs special groups section,
1250 * unique,active vs. sgroup,active
1251 * => should NOT be replaced
1254 .line = __location__,
1255 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1258 .type = WREPL_TYPE_UNIQUE,
1259 .state = WREPL_STATE_ACTIVE,
1260 .node = WREPL_NODE_B,
1262 .num_ips = ARRAY_SIZE(addresses_A_1),
1263 .ips = addresses_A_1,
1264 .apply_expected = True
1268 .type = WREPL_TYPE_SGROUP,
1269 .state = WREPL_STATE_ACTIVE,
1270 .node = WREPL_NODE_B,
1272 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1273 .ips = addresses_B_3_4,
1274 .apply_expected = False
1279 * unique,active vs. sgroup,tombstone
1280 * => should NOT be replaced
1283 .line = __location__,
1284 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1287 .type = WREPL_TYPE_UNIQUE,
1288 .state = WREPL_STATE_ACTIVE,
1289 .node = WREPL_NODE_B,
1291 .num_ips = ARRAY_SIZE(addresses_A_1),
1292 .ips = addresses_A_1,
1293 .apply_expected = True
1297 .type = WREPL_TYPE_SGROUP,
1298 .state = WREPL_STATE_TOMBSTONE,
1299 .node = WREPL_NODE_B,
1301 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1302 .ips = addresses_B_3_4,
1303 .apply_expected = False
1308 * unique,tombstone vs. sgroup,active
1309 * => should be replaced
1312 .line = __location__,
1313 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1316 .type = WREPL_TYPE_UNIQUE,
1317 .state = WREPL_STATE_TOMBSTONE,
1318 .node = WREPL_NODE_B,
1320 .num_ips = ARRAY_SIZE(addresses_A_1),
1321 .ips = addresses_A_1,
1322 .apply_expected = True
1326 .type = WREPL_TYPE_SGROUP,
1327 .state = WREPL_STATE_ACTIVE,
1328 .node = WREPL_NODE_B,
1330 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1331 .ips = addresses_B_3_4,
1332 .apply_expected = True
1337 * unique,tombstone vs. sgroup,tombstone
1338 * => should be replaced
1341 .line = __location__,
1342 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1345 .type = WREPL_TYPE_UNIQUE,
1346 .state = WREPL_STATE_TOMBSTONE,
1347 .node = WREPL_NODE_B,
1349 .num_ips = ARRAY_SIZE(addresses_B_1),
1350 .ips = addresses_B_1,
1351 .apply_expected = True
1355 .type = WREPL_TYPE_SGROUP,
1356 .state = WREPL_STATE_TOMBSTONE,
1357 .node = WREPL_NODE_B,
1359 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1360 .ips = addresses_A_3_4,
1361 .apply_expected = True
1366 * normal groups vs unique section,
1369 * group,active vs. unique,active
1370 * => should NOT be replaced
1373 .line = __location__,
1374 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1377 .type = WREPL_TYPE_GROUP,
1378 .state = WREPL_STATE_ACTIVE,
1379 .node = WREPL_NODE_B,
1381 .num_ips = ARRAY_SIZE(addresses_A_1),
1382 .ips = addresses_A_1,
1383 .apply_expected = True
1387 .type = WREPL_TYPE_UNIQUE,
1388 .state = WREPL_STATE_ACTIVE,
1389 .node = WREPL_NODE_B,
1391 .num_ips = ARRAY_SIZE(addresses_B_1),
1392 .ips = addresses_B_1,
1393 .apply_expected = False
1398 * group,active vs. unique,tombstone
1399 * => should NOT be replaced
1402 .line = __location__,
1403 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1406 .type = WREPL_TYPE_GROUP,
1407 .state = WREPL_STATE_ACTIVE,
1408 .node = WREPL_NODE_B,
1410 .num_ips = ARRAY_SIZE(addresses_A_1),
1411 .ips = addresses_A_1,
1412 .apply_expected = True
1416 .type = WREPL_TYPE_UNIQUE,
1417 .state = WREPL_STATE_TOMBSTONE,
1418 .node = WREPL_NODE_B,
1420 .num_ips = ARRAY_SIZE(addresses_B_1),
1421 .ips = addresses_B_1,
1422 .apply_expected = False
1427 * group,released vs. unique,active
1428 * => should NOT be replaced
1431 .line = __location__,
1432 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1435 .type = WREPL_TYPE_GROUP,
1436 .state = WREPL_STATE_RELEASED,
1437 .node = WREPL_NODE_B,
1439 .num_ips = ARRAY_SIZE(addresses_A_1),
1440 .ips = addresses_A_1,
1441 .apply_expected = False
1445 .type = WREPL_TYPE_UNIQUE,
1446 .state = WREPL_STATE_ACTIVE,
1447 .node = WREPL_NODE_B,
1449 .num_ips = ARRAY_SIZE(addresses_B_1),
1450 .ips = addresses_B_1,
1451 .apply_expected = False
1456 * group,released vs. unique,tombstone
1457 * => should NOT be replaced
1460 .line = __location__,
1461 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1464 .type = WREPL_TYPE_GROUP,
1465 .state = WREPL_STATE_RELEASED,
1466 .node = WREPL_NODE_B,
1468 .num_ips = ARRAY_SIZE(addresses_A_1),
1469 .ips = addresses_A_1,
1470 .apply_expected = False
1474 .type = WREPL_TYPE_UNIQUE,
1475 .state = WREPL_STATE_TOMBSTONE,
1476 .node = WREPL_NODE_B,
1478 .num_ips = ARRAY_SIZE(addresses_B_1),
1479 .ips = addresses_B_1,
1480 .apply_expected = False
1485 * group,tombstone vs. unique,active
1486 * => should NOT be replaced
1489 .line = __location__,
1490 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1493 .type = WREPL_TYPE_GROUP,
1494 .state = WREPL_STATE_TOMBSTONE,
1495 .node = WREPL_NODE_B,
1497 .num_ips = ARRAY_SIZE(addresses_A_1),
1498 .ips = addresses_A_1,
1499 .apply_expected = True
1503 .type = WREPL_TYPE_UNIQUE,
1504 .state = WREPL_STATE_ACTIVE,
1505 .node = WREPL_NODE_B,
1507 .num_ips = ARRAY_SIZE(addresses_B_1),
1508 .ips = addresses_B_1,
1509 .apply_expected = False
1514 * group,tombstone vs. unique,tombstone
1515 * => should NOT be replaced
1518 .line = __location__,
1519 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1522 .type = WREPL_TYPE_GROUP,
1523 .state = WREPL_STATE_TOMBSTONE,
1524 .node = WREPL_NODE_B,
1526 .num_ips = ARRAY_SIZE(addresses_A_1),
1527 .ips = addresses_A_1,
1528 .apply_expected = True
1532 .type = WREPL_TYPE_UNIQUE,
1533 .state = WREPL_STATE_TOMBSTONE,
1534 .node = WREPL_NODE_B,
1536 .num_ips = ARRAY_SIZE(addresses_B_1),
1537 .ips = addresses_B_1,
1538 .apply_expected = False
1543 * This should be the last record in this array,
1544 * we need to make sure the we leave a tombstoned unique entry
1548 .line = __location__,
1549 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1552 .type = WREPL_TYPE_UNIQUE,
1553 .state = WREPL_STATE_TOMBSTONE,
1554 .node = WREPL_NODE_B,
1556 .num_ips = ARRAY_SIZE(addresses_A_1),
1557 .ips = addresses_A_1,
1558 .apply_expected = True
1562 .type = WREPL_TYPE_UNIQUE,
1563 .state = WREPL_STATE_TOMBSTONE,
1564 .node = WREPL_NODE_B,
1566 .num_ips = ARRAY_SIZE(addresses_A_1),
1567 .ips = addresses_A_1,
1568 .apply_expected = True
1570 }}; /* do not add entries here, this should be the last record! */
1572 if (!ctx) return False;
1574 wins_name_r1 = &wins_name1;
1575 wins_name_r2 = &wins_name2;
1577 printf("Test Replica Conflicts with different owners\n");
1579 for(i=0; ret && i < ARRAY_SIZE(records); i++) {
1582 printf("%s,%s%s vs, %s,%s%s with %s ip(s) => %s\n",
1583 wrepl_name_type_string(records[i].r1.type),
1584 wrepl_name_state_string(records[i].r1.state),
1585 (records[i].r1.is_static?",static":""),
1586 wrepl_name_type_string(records[i].r2.type),
1587 wrepl_name_state_string(records[i].r2.state),
1588 (records[i].r2.is_static?",static":""),
1589 (records[i].r1.ips==records[i].r2.ips?"same":"different"),
1590 (records[i].r2.apply_expected?"REPLACE":"NOT REPLACE"));
1596 wins_name_r1->name = &records[i].name;
1597 wins_name_r1->flags = WREPL_NAME_FLAGS(records[i].r1.type,
1598 records[i].r1.state,
1600 records[i].r1.is_static);
1601 wins_name_r1->id = ++records[i].r1.owner->max_version;
1602 if (wins_name_r1->flags & 2) {
1603 wins_name_r1->addresses.addresses.num_ips = records[i].r1.num_ips;
1604 wins_name_r1->addresses.addresses.ips = discard_const(records[i].r1.ips);
1606 wins_name_r1->addresses.ip = records[i].r1.ips[0].ip;
1608 wins_name_r1->unknown = "255.255.255.255";
1611 ret &= test_wrepl_update_one(ctx, records[i].r1.owner, wins_name_r1);
1612 ret &= test_wrepl_is_applied(ctx, records[i].r1.owner,
1613 wins_name_r1, records[i].r1.apply_expected);
1618 wins_name_r2->name = &records[i].name;
1619 wins_name_r2->flags = WREPL_NAME_FLAGS(records[i].r2.type,
1620 records[i].r2.state,
1622 records[i].r2.is_static);
1623 wins_name_r2->id = ++records[i].r2.owner->max_version;
1624 if (wins_name_r2->flags & 2) {
1625 wins_name_r2->addresses.addresses.num_ips = records[i].r2.num_ips;
1626 wins_name_r2->addresses.addresses.ips = discard_const(records[i].r2.ips);
1628 wins_name_r2->addresses.ip = records[i].r2.ips[0].ip;
1630 wins_name_r2->unknown = "255.255.255.255";
1633 ret &= test_wrepl_update_one(ctx, records[i].r2.owner, wins_name_r2);
1634 if (records[i].r1.state == WREPL_STATE_RELEASED) {
1635 ret &= test_wrepl_is_applied(ctx, records[i].r1.owner,
1636 wins_name_r1, False);
1637 } else if (records[i].r1.owner != records[i].r2.owner) {
1638 ret &= test_wrepl_is_applied(ctx, records[i].r1.owner,
1639 wins_name_r1, !records[i].r2.apply_expected);
1641 if (records[i].r2.state == WREPL_STATE_RELEASED) {
1642 ret &= test_wrepl_is_applied(ctx, records[i].r2.owner,
1643 wins_name_r2, False);
1645 ret &= test_wrepl_is_applied(ctx, records[i].r2.owner,
1646 wins_name_r2, records[i].r2.apply_expected);
1649 /* the first one is a cleanup run */
1650 if (!ret && i == 0) ret = True;
1653 printf("conflict handled wrong or record[%u]: %s\n", i, records[i].line);
1662 test WINS replication operations
1664 BOOL torture_nbt_winsreplication_quick(void)
1666 const char *address;
1667 struct nbt_name name;
1668 TALLOC_CTX *mem_ctx = talloc_new(NULL);
1672 make_nbt_name_server(&name, lp_parm_string(-1, "torture", "host"));
1674 /* do an initial name resolution to find its IP */
1675 status = resolve_name(&name, mem_ctx, &address, NULL);
1676 if (!NT_STATUS_IS_OK(status)) {
1677 printf("Failed to resolve %s - %s\n",
1678 name.name, nt_errstr(status));
1679 talloc_free(mem_ctx);
1683 ret &= test_assoc_ctx1(mem_ctx, address);
1684 ret &= test_assoc_ctx2(mem_ctx, address);
1686 talloc_free(mem_ctx);
1692 test WINS replication operations
1694 BOOL torture_nbt_winsreplication(void)
1696 const char *address;
1697 struct nbt_name name;
1698 TALLOC_CTX *mem_ctx = talloc_new(NULL);
1701 struct test_wrepl_conflict_conn *ctx;
1703 make_nbt_name_server(&name, lp_parm_string(-1, "torture", "host"));
1705 /* do an initial name resolution to find its IP */
1706 status = resolve_name(&name, mem_ctx, &address, NULL);
1707 if (!NT_STATUS_IS_OK(status)) {
1708 printf("Failed to resolve %s - %s\n",
1709 name.name, nt_errstr(status));
1710 talloc_free(mem_ctx);
1714 ret &= test_assoc_ctx1(mem_ctx, address);
1715 ret &= test_assoc_ctx2(mem_ctx, address);
1717 ret &= test_wins_replication(mem_ctx, address);
1719 ctx = test_create_conflict_ctx(mem_ctx, address);
1721 ret &= test_conflict_same_owner(ctx);
1722 ret &= test_conflict_different_owner(ctx);
1724 talloc_free(mem_ctx);