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, c;
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 ctx->c.address = address;
413 ctx->c.max_version = 0;
414 ctx->c.min_version = 0;
417 pull_table.in.assoc_ctx = ctx->pull_assoc;
418 status = wrepl_pull_table(ctx->pull, ctx->pull, &pull_table);
419 if (!NT_STATUS_IS_OK(status)) return NULL;
421 for (i=0; i < pull_table.out.num_partners; i++) {
422 if (strcmp(TEST_OWNER_A_ADDRESS,pull_table.out.partners[i].address)==0) {
423 ctx->a.max_version = pull_table.out.partners[i].max_version;
424 ctx->a.min_version = pull_table.out.partners[i].min_version;
426 if (strcmp(TEST_OWNER_B_ADDRESS,pull_table.out.partners[i].address)==0) {
427 ctx->b.max_version = pull_table.out.partners[i].max_version;
428 ctx->b.min_version = pull_table.out.partners[i].min_version;
430 if (strcmp(address,pull_table.out.partners[i].address)==0) {
431 ctx->c.max_version = pull_table.out.partners[i].max_version;
432 ctx->c.min_version = pull_table.out.partners[i].min_version;
436 talloc_free(pull_table.out.partners);
441 static BOOL test_wrepl_update_one(struct test_wrepl_conflict_conn *ctx,
442 const struct wrepl_wins_owner *owner,
443 const struct wrepl_wins_name *name)
446 struct wrepl_socket *wrepl_socket;
447 struct wrepl_associate associate;
448 struct wrepl_packet update_packet, repl_send;
449 struct wrepl_table *update;
450 struct wrepl_wins_owner wrepl_wins_owners[1];
451 struct wrepl_packet *repl_recv;
452 struct wrepl_wins_owner *send_request;
453 struct wrepl_send_reply *send_reply;
454 struct wrepl_wins_name wrepl_wins_names[1];
458 wrepl_socket = wrepl_socket_init(ctx, NULL);
460 status = wrepl_connect(wrepl_socket, NULL, ctx->address);
461 CHECK_STATUS(status, NT_STATUS_OK);
463 status = wrepl_associate(wrepl_socket, &associate);
464 CHECK_STATUS(status, NT_STATUS_OK);
465 assoc_ctx = associate.out.assoc_ctx;
467 /* now send a WREPL_REPL_UPDATE message */
468 ZERO_STRUCT(update_packet);
469 update_packet.opcode = WREPL_OPCODE_BITS;
470 update_packet.assoc_ctx = assoc_ctx;
471 update_packet.mess_type = WREPL_REPLICATION;
472 update_packet.message.replication.command = WREPL_REPL_UPDATE;
473 update = &update_packet.message.replication.info.table;
475 update->partner_count = ARRAY_SIZE(wrepl_wins_owners);
476 update->partners = wrepl_wins_owners;
477 update->initiator = "0.0.0.0";
479 wrepl_wins_owners[0] = *owner;
481 status = wrepl_request(wrepl_socket, wrepl_socket,
482 &update_packet, &repl_recv);
483 CHECK_STATUS(status, NT_STATUS_OK);
484 CHECK_VALUE(repl_recv->mess_type, WREPL_REPLICATION);
485 CHECK_VALUE(repl_recv->message.replication.command, WREPL_REPL_SEND_REQUEST);
486 send_request = &repl_recv->message.replication.info.owner;
488 ZERO_STRUCT(repl_send);
489 repl_send.opcode = WREPL_OPCODE_BITS;
490 repl_send.assoc_ctx = assoc_ctx;
491 repl_send.mess_type = WREPL_REPLICATION;
492 repl_send.message.replication.command = WREPL_REPL_SEND_REPLY;
493 send_reply = &repl_send.message.replication.info.reply;
495 send_reply->num_names = ARRAY_SIZE(wrepl_wins_names);
496 send_reply->names = wrepl_wins_names;
498 wrepl_wins_names[0] = *name;
500 status = wrepl_request(wrepl_socket, wrepl_socket,
501 &repl_send, &repl_recv);
502 CHECK_STATUS(status, NT_STATUS_OK);
503 CHECK_VALUE(repl_recv->mess_type, WREPL_STOP_ASSOCIATION);
504 CHECK_VALUE(repl_recv->message.stop.reason, 0);
507 talloc_free(wrepl_socket);
511 static BOOL test_wrepl_is_applied(struct test_wrepl_conflict_conn *ctx,
512 const struct wrepl_wins_owner *owner,
513 const struct wrepl_wins_name *name,
518 struct wrepl_pull_names pull_names;
519 struct wrepl_name *names;
521 pull_names.in.assoc_ctx = ctx->pull_assoc;
522 pull_names.in.partner = *owner;
523 pull_names.in.partner.min_version = pull_names.in.partner.max_version;
525 status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
526 CHECK_STATUS(status, NT_STATUS_OK);
527 CHECK_VALUE(pull_names.out.num_names, (expected?1:0));
529 names = pull_names.out.names;
532 uint32_t flags = WREPL_NAME_FLAGS(names[0].type,
536 CHECK_VALUE(names[0].name.type, name->name->type);
537 CHECK_VALUE_STRING(names[0].name.name, name->name->name);
538 CHECK_VALUE_STRING(names[0].name.scope, name->name->scope);
539 CHECK_VALUE(flags, name->flags);
540 CHECK_VALUE_UINT64(names[0].version_id, name->id);
543 CHECK_VALUE(names[0].num_addresses,
544 name->addresses.addresses.num_ips);
546 CHECK_VALUE(names[0].num_addresses, 1);
547 CHECK_VALUE_STRING(names[0].addresses[0].address,
552 talloc_free(pull_names.out.names);
556 static BOOL test_wrepl_is_merged(struct test_wrepl_conflict_conn *ctx,
557 const struct wrepl_wins_name *name1,
558 const struct wrepl_wins_name *name2)
564 struct wrepl_pull_names pull_names;
565 struct wrepl_name *names;
568 pull_names.in.assoc_ctx = ctx->pull_assoc;
569 pull_names.in.partner = ctx->c;
570 pull_names.in.partner.min_version = ctx->c.max_version-1;
572 status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
573 CHECK_STATUS(status, NT_STATUS_OK);
574 CHECK_VALUE(pull_names.out.num_names, 1);
576 names = pull_names.out.names;
578 num_ips = name1->addresses.addresses.num_ips + name2->addresses.addresses.num_ips;
580 CHECK_VALUE(names[0].name.type, name1->name->type);
581 CHECK_VALUE_STRING(names[0].name.name, name1->name->name);
582 CHECK_VALUE_STRING(names[0].name.scope, name1->name->scope);
583 CHECK_VALUE(names[0].type, WREPL_TYPE_SGROUP);
584 CHECK_VALUE(names[0].state, (num_ips>0?WREPL_STATE_ACTIVE:WREPL_STATE_RELEASED));
585 CHECK_VALUE_UINT64(names[0].version_id, ctx->c.max_version);
587 CHECK_VALUE(names[0].num_addresses,
588 name1->addresses.addresses.num_ips+
589 name2->addresses.addresses.num_ips);
591 talloc_free(pull_names.out.names);
596 static BOOL test_conflict_same_owner(struct test_wrepl_conflict_conn *ctx)
599 struct nbt_name name;
600 struct wrepl_wins_name wins_name1;
601 struct wrepl_wins_name wins_name2;
602 struct wrepl_wins_name *wins_name_tmp;
603 struct wrepl_wins_name *wins_name_last;
604 struct wrepl_wins_name *wins_name_cur;
606 uint8_t types[] = { 0x00, 0x1C };
608 enum wrepl_name_type type;
609 enum wrepl_name_state state;
610 enum wrepl_name_node node;
613 const struct wrepl_ip *ips;
616 .type = WREPL_TYPE_GROUP,
617 .state = WREPL_STATE_ACTIVE,
618 .node = WREPL_NODE_B,
620 .num_ips = ARRAY_SIZE(addresses_A_1),
621 .ips = addresses_A_1,
623 .type = WREPL_TYPE_UNIQUE,
624 .state = WREPL_STATE_ACTIVE,
625 .node = WREPL_NODE_B,
627 .num_ips = ARRAY_SIZE(addresses_A_1),
628 .ips = addresses_A_1,
630 .type = WREPL_TYPE_UNIQUE,
631 .state = WREPL_STATE_ACTIVE,
632 .node = WREPL_NODE_B,
634 .num_ips = ARRAY_SIZE(addresses_A_2),
635 .ips = addresses_A_2,
637 .type = WREPL_TYPE_UNIQUE,
638 .state = WREPL_STATE_ACTIVE,
639 .node = WREPL_NODE_B,
641 .num_ips = ARRAY_SIZE(addresses_A_1),
642 .ips = addresses_A_1,
644 .type = WREPL_TYPE_UNIQUE,
645 .state = WREPL_STATE_ACTIVE,
646 .node = WREPL_NODE_B,
648 .num_ips = ARRAY_SIZE(addresses_A_2),
649 .ips = addresses_A_2,
651 .type = WREPL_TYPE_SGROUP,
652 .state = WREPL_STATE_TOMBSTONE,
653 .node = WREPL_NODE_B,
655 .num_ips = ARRAY_SIZE(addresses_A_2),
656 .ips = addresses_A_2,
658 .type = WREPL_TYPE_MHOMED,
659 .state = WREPL_STATE_TOMBSTONE,
660 .node = WREPL_NODE_B,
662 .num_ips = ARRAY_SIZE(addresses_A_1),
663 .ips = addresses_A_1,
665 .type = WREPL_TYPE_MHOMED,
666 .state = WREPL_STATE_RELEASED,
667 .node = WREPL_NODE_B,
669 .num_ips = ARRAY_SIZE(addresses_A_2),
670 .ips = addresses_A_2,
672 .type = WREPL_TYPE_SGROUP,
673 .state = WREPL_STATE_ACTIVE,
674 .node = WREPL_NODE_B,
676 .num_ips = ARRAY_SIZE(addresses_A_1),
677 .ips = addresses_A_1,
679 /* the last one should always be a unique,tomstone record! */
680 .type = WREPL_TYPE_UNIQUE,
681 .state = WREPL_STATE_TOMBSTONE,
682 .node = WREPL_NODE_B,
684 .num_ips = ARRAY_SIZE(addresses_A_1),
685 .ips = addresses_A_1,
689 if (!ctx) return False;
691 name.name = "_SAME_OWNER_A";
695 wins_name_tmp = NULL;
696 wins_name_last = &wins_name2;
697 wins_name_cur = &wins_name1;
699 for (j=0; ret && j < ARRAY_SIZE(types); j++) {
700 name.type = types[j];
701 printf("Test Replica Conflicts with same owner[%s] for %s\n",
702 nbt_name_string(ctx, &name), ctx->a.address);
704 for(i=0; ret && i < ARRAY_SIZE(records); i++) {
705 wins_name_tmp = wins_name_last;
706 wins_name_last = wins_name_cur;
707 wins_name_cur = wins_name_tmp;
710 printf("%s,%s%s vs. %s,%s%s with %s ip(s) => %s\n",
711 wrepl_name_type_string(records[i-1].type),
712 wrepl_name_state_string(records[i-1].state),
713 (records[i-1].is_static?",static":""),
714 wrepl_name_type_string(records[i].type),
715 wrepl_name_state_string(records[i].state),
716 (records[i].is_static?",static":""),
717 (records[i-1].ips==records[i].ips?"same":"different"),
721 wins_name_cur->name = &name;
722 wins_name_cur->flags = WREPL_NAME_FLAGS(records[i].type,
725 records[i].is_static);
726 wins_name_cur->id = ++ctx->a.max_version;
727 if (wins_name_cur->flags & 2) {
728 wins_name_cur->addresses.addresses.num_ips = records[i].num_ips;
729 wins_name_cur->addresses.addresses.ips = discard_const(records[i].ips);
731 wins_name_cur->addresses.ip = records[i].ips[0].ip;
733 wins_name_cur->unknown = "255.255.255.255";
735 ret &= test_wrepl_update_one(ctx, &ctx->a,wins_name_cur);
736 if (records[i].state == WREPL_STATE_RELEASED) {
737 ret &= test_wrepl_is_applied(ctx, &ctx->a, wins_name_last, False);
738 ret &= test_wrepl_is_applied(ctx, &ctx->a, wins_name_cur, False);
740 ret &= test_wrepl_is_applied(ctx, &ctx->a, wins_name_cur, True);
743 /* the first one is a cleanup run */
744 if (!ret && i == 0) ret = True;
747 printf("conflict handled wrong or record[%u]: %s\n", i, __location__);
755 static BOOL test_conflict_different_owner(struct test_wrepl_conflict_conn *ctx)
758 struct wrepl_wins_name wins_name1;
759 struct wrepl_wins_name wins_name2;
760 struct wrepl_wins_name *wins_name_r1;
761 struct wrepl_wins_name *wins_name_r2;
764 const char *line; /* just better debugging */
765 struct nbt_name name;
766 BOOL extra; /* not the worst case, this is an extra test */
769 struct wrepl_wins_owner *owner;
770 enum wrepl_name_type type;
771 enum wrepl_name_state state;
772 enum wrepl_name_node node;
775 const struct wrepl_ip *ips;
781 * NOTE: the first record and the last applied one
782 * needs to be from the same owner,
783 * to not conflict in the next smbtorture run!!!
786 .line = __location__,
787 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
791 .type = WREPL_TYPE_UNIQUE,
792 .state = WREPL_STATE_TOMBSTONE,
793 .node = WREPL_NODE_B,
795 .num_ips = ARRAY_SIZE(addresses_B_1),
796 .ips = addresses_B_1,
797 .apply_expected = True /* ignored */
801 .type = WREPL_TYPE_UNIQUE,
802 .state = WREPL_STATE_TOMBSTONE,
803 .node = WREPL_NODE_B,
805 .num_ips = ARRAY_SIZE(addresses_A_1),
806 .ips = addresses_A_1,
807 .apply_expected = True /* ignored */
812 * unique vs unique section
815 * unique,active vs. unique,active
816 * => should be replaced
819 .line = __location__,
820 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
823 .type = WREPL_TYPE_UNIQUE,
824 .state = WREPL_STATE_ACTIVE,
825 .node = WREPL_NODE_B,
827 .num_ips = ARRAY_SIZE(addresses_A_1),
828 .ips = addresses_A_1,
829 .apply_expected = True
833 .type = WREPL_TYPE_UNIQUE,
834 .state = WREPL_STATE_ACTIVE,
835 .node = WREPL_NODE_B,
837 .num_ips = ARRAY_SIZE(addresses_B_1),
838 .ips = addresses_B_1,
839 .apply_expected = True
844 * unique,active vs. unique,tombstone
845 * => should NOT be replaced
848 .line = __location__,
849 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
853 .type = WREPL_TYPE_UNIQUE,
854 .state = WREPL_STATE_ACTIVE,
855 .node = WREPL_NODE_B,
857 .num_ips = ARRAY_SIZE(addresses_B_1),
858 .ips = addresses_B_1,
859 .apply_expected = True
863 .type = WREPL_TYPE_UNIQUE,
864 .state = WREPL_STATE_TOMBSTONE,
865 .node = WREPL_NODE_B,
867 .num_ips = ARRAY_SIZE(addresses_A_1),
868 .ips = addresses_A_1,
869 .apply_expected = False
874 * unique,released vs. unique,active
875 * => should be replaced
878 .line = __location__,
879 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
882 .type = WREPL_TYPE_UNIQUE,
883 .state = WREPL_STATE_RELEASED,
884 .node = WREPL_NODE_B,
886 .num_ips = ARRAY_SIZE(addresses_B_1),
887 .ips = addresses_B_1,
888 .apply_expected = False
892 .type = WREPL_TYPE_UNIQUE,
893 .state = WREPL_STATE_ACTIVE,
894 .node = WREPL_NODE_B,
896 .num_ips = ARRAY_SIZE(addresses_A_1),
897 .ips = addresses_A_1,
898 .apply_expected = True
903 * unique,released vs. unique,tombstone
904 * => should be replaced
907 .line = __location__,
908 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
911 .type = WREPL_TYPE_UNIQUE,
912 .state = WREPL_STATE_RELEASED,
913 .node = WREPL_NODE_B,
915 .num_ips = ARRAY_SIZE(addresses_A_1),
916 .ips = addresses_A_1,
917 .apply_expected = False
921 .type = WREPL_TYPE_UNIQUE,
922 .state = WREPL_STATE_TOMBSTONE,
923 .node = WREPL_NODE_B,
925 .num_ips = ARRAY_SIZE(addresses_B_1),
926 .ips = addresses_B_1,
927 .apply_expected = True
932 * unique,tombstone vs. unique,active
933 * => should be replaced
936 .line = __location__,
937 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
940 .type = WREPL_TYPE_UNIQUE,
941 .state = WREPL_STATE_TOMBSTONE,
942 .node = WREPL_NODE_B,
944 .num_ips = ARRAY_SIZE(addresses_B_1),
945 .ips = addresses_B_1,
946 .apply_expected = True
950 .type = WREPL_TYPE_UNIQUE,
951 .state = WREPL_STATE_ACTIVE,
952 .node = WREPL_NODE_B,
954 .num_ips = ARRAY_SIZE(addresses_A_1),
955 .ips = addresses_A_1,
956 .apply_expected = True
961 * unique,tombstone vs. unique,tombstone
962 * => should be replaced
965 .line = __location__,
966 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
969 .type = WREPL_TYPE_UNIQUE,
970 .state = WREPL_STATE_TOMBSTONE,
971 .node = WREPL_NODE_B,
973 .num_ips = ARRAY_SIZE(addresses_A_1),
974 .ips = addresses_A_1,
975 .apply_expected = True
979 .type = WREPL_TYPE_UNIQUE,
980 .state = WREPL_STATE_TOMBSTONE,
981 .node = WREPL_NODE_B,
983 .num_ips = ARRAY_SIZE(addresses_B_1),
984 .ips = addresses_B_1,
985 .apply_expected = True
991 * unique vs normal groups section,
994 * unique,active vs. group,active
995 * => should be replaced
998 .line = __location__,
999 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1002 .type = WREPL_TYPE_UNIQUE,
1003 .state = WREPL_STATE_ACTIVE,
1004 .node = WREPL_NODE_B,
1006 .num_ips = ARRAY_SIZE(addresses_B_1),
1007 .ips = addresses_B_1,
1008 .apply_expected = True
1012 .type = WREPL_TYPE_GROUP,
1013 .state = WREPL_STATE_ACTIVE,
1014 .node = WREPL_NODE_B,
1016 .num_ips = ARRAY_SIZE(addresses_A_1),
1017 .ips = addresses_A_1,
1018 .apply_expected = True
1023 * unique,active vs. group,tombstone
1024 * => should NOT be replaced
1027 .line = __location__,
1028 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1031 .type = WREPL_TYPE_UNIQUE,
1032 .state = WREPL_STATE_ACTIVE,
1033 .node = WREPL_NODE_B,
1035 .num_ips = ARRAY_SIZE(addresses_A_1),
1036 .ips = addresses_A_1,
1037 .apply_expected = True
1041 .type = WREPL_TYPE_GROUP,
1042 .state = WREPL_STATE_TOMBSTONE,
1043 .node = WREPL_NODE_B,
1045 .num_ips = ARRAY_SIZE(addresses_A_1),
1046 .ips = addresses_A_1,
1047 .apply_expected = False
1052 * unique,released vs. group,active
1053 * => should be replaced
1056 .line = __location__,
1057 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1060 .type = WREPL_TYPE_UNIQUE,
1061 .state = WREPL_STATE_RELEASED,
1062 .node = WREPL_NODE_B,
1064 .num_ips = ARRAY_SIZE(addresses_A_1),
1065 .ips = addresses_A_1,
1066 .apply_expected = False
1070 .type = WREPL_TYPE_GROUP,
1071 .state = WREPL_STATE_ACTIVE,
1072 .node = WREPL_NODE_B,
1074 .num_ips = ARRAY_SIZE(addresses_B_1),
1075 .ips = addresses_B_1,
1076 .apply_expected = True
1081 * unique,released vs. group,tombstone
1082 * => should be replaced
1085 .line = __location__,
1086 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1089 .type = WREPL_TYPE_UNIQUE,
1090 .state = WREPL_STATE_RELEASED,
1091 .node = WREPL_NODE_B,
1093 .num_ips = ARRAY_SIZE(addresses_B_1),
1094 .ips = addresses_B_1,
1095 .apply_expected = False
1099 .type = WREPL_TYPE_GROUP,
1100 .state = WREPL_STATE_TOMBSTONE,
1101 .node = WREPL_NODE_B,
1103 .num_ips = ARRAY_SIZE(addresses_A_1),
1104 .ips = addresses_A_1,
1105 .apply_expected = True
1110 * unique,tombstone vs. group,active
1111 * => should be replaced
1114 .line = __location__,
1115 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1118 .type = WREPL_TYPE_UNIQUE,
1119 .state = WREPL_STATE_TOMBSTONE,
1120 .node = WREPL_NODE_B,
1122 .num_ips = ARRAY_SIZE(addresses_A_1),
1123 .ips = addresses_A_1,
1124 .apply_expected = True
1128 .type = WREPL_TYPE_GROUP,
1129 .state = WREPL_STATE_ACTIVE,
1130 .node = WREPL_NODE_B,
1132 .num_ips = ARRAY_SIZE(addresses_B_1),
1133 .ips = addresses_B_1,
1134 .apply_expected = True
1139 * unique,tombstone vs. group,tombstone
1140 * => should be replaced
1143 .line = __location__,
1144 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1147 .type = WREPL_TYPE_UNIQUE,
1148 .state = WREPL_STATE_TOMBSTONE,
1149 .node = WREPL_NODE_B,
1151 .num_ips = ARRAY_SIZE(addresses_B_1),
1152 .ips = addresses_B_1,
1153 .apply_expected = True
1157 .type = WREPL_TYPE_GROUP,
1158 .state = WREPL_STATE_TOMBSTONE,
1159 .node = WREPL_NODE_B,
1161 .num_ips = ARRAY_SIZE(addresses_A_1),
1162 .ips = addresses_A_1,
1163 .apply_expected = True
1168 * unique vs special groups section,
1171 * unique,active vs. sgroup,active
1172 * => should NOT be replaced
1175 .line = __location__,
1176 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1179 .type = WREPL_TYPE_UNIQUE,
1180 .state = WREPL_STATE_ACTIVE,
1181 .node = WREPL_NODE_B,
1183 .num_ips = ARRAY_SIZE(addresses_A_1),
1184 .ips = addresses_A_1,
1185 .apply_expected = True
1189 .type = WREPL_TYPE_SGROUP,
1190 .state = WREPL_STATE_ACTIVE,
1191 .node = WREPL_NODE_B,
1193 .num_ips = ARRAY_SIZE(addresses_A_1),
1194 .ips = addresses_A_1,
1195 .apply_expected = False
1200 * unique,active vs. sgroup,tombstone
1201 * => should NOT be replaced
1204 .line = __location__,
1205 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1208 .type = WREPL_TYPE_UNIQUE,
1209 .state = WREPL_STATE_ACTIVE,
1210 .node = WREPL_NODE_B,
1212 .num_ips = ARRAY_SIZE(addresses_A_1),
1213 .ips = addresses_A_1,
1214 .apply_expected = True
1218 .type = WREPL_TYPE_SGROUP,
1219 .state = WREPL_STATE_TOMBSTONE,
1220 .node = WREPL_NODE_B,
1222 .num_ips = ARRAY_SIZE(addresses_A_1),
1223 .ips = addresses_A_1,
1224 .apply_expected = False
1229 * unique,released vs. sgroup,active
1230 * => should be replaced
1233 .line = __location__,
1234 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1237 .type = WREPL_TYPE_UNIQUE,
1238 .state = WREPL_STATE_RELEASED,
1239 .node = WREPL_NODE_B,
1241 .num_ips = ARRAY_SIZE(addresses_A_1),
1242 .ips = addresses_A_1,
1243 .apply_expected = False
1247 .type = WREPL_TYPE_SGROUP,
1248 .state = WREPL_STATE_ACTIVE,
1249 .node = WREPL_NODE_B,
1251 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1252 .ips = addresses_B_3_4,
1253 .apply_expected = True
1258 * unique,released vs. sgroup,tombstone
1259 * => should be replaced
1262 .line = __location__,
1263 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1266 .type = WREPL_TYPE_UNIQUE,
1267 .state = WREPL_STATE_RELEASED,
1268 .node = WREPL_NODE_B,
1270 .num_ips = ARRAY_SIZE(addresses_B_1),
1271 .ips = addresses_B_1,
1272 .apply_expected = False
1276 .type = WREPL_TYPE_SGROUP,
1277 .state = WREPL_STATE_TOMBSTONE,
1278 .node = WREPL_NODE_B,
1280 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1281 .ips = addresses_A_3_4,
1282 .apply_expected = True
1287 * unique,tombstone vs. sgroup,active
1288 * => should be replaced
1291 .line = __location__,
1292 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1295 .type = WREPL_TYPE_UNIQUE,
1296 .state = WREPL_STATE_TOMBSTONE,
1297 .node = WREPL_NODE_B,
1299 .num_ips = ARRAY_SIZE(addresses_A_1),
1300 .ips = addresses_A_1,
1301 .apply_expected = True
1305 .type = WREPL_TYPE_SGROUP,
1306 .state = WREPL_STATE_ACTIVE,
1307 .node = WREPL_NODE_B,
1309 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1310 .ips = addresses_B_3_4,
1311 .apply_expected = True
1316 * unique,tombstone vs. sgroup,tombstone
1317 * => should be replaced
1320 .line = __location__,
1321 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1324 .type = WREPL_TYPE_UNIQUE,
1325 .state = WREPL_STATE_TOMBSTONE,
1326 .node = WREPL_NODE_B,
1328 .num_ips = ARRAY_SIZE(addresses_B_1),
1329 .ips = addresses_B_1,
1330 .apply_expected = True
1334 .type = WREPL_TYPE_SGROUP,
1335 .state = WREPL_STATE_TOMBSTONE,
1336 .node = WREPL_NODE_B,
1338 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1339 .ips = addresses_A_3_4,
1340 .apply_expected = True
1345 * unique vs multi homed section,
1348 * unique,active vs. mhomed,active
1349 * => should be replaced
1352 .line = __location__,
1353 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1356 .type = WREPL_TYPE_UNIQUE,
1357 .state = WREPL_STATE_ACTIVE,
1358 .node = WREPL_NODE_B,
1360 .num_ips = ARRAY_SIZE(addresses_A_1),
1361 .ips = addresses_A_1,
1362 .apply_expected = True
1366 .type = WREPL_TYPE_MHOMED,
1367 .state = WREPL_STATE_ACTIVE,
1368 .node = WREPL_NODE_B,
1370 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1371 .ips = addresses_B_3_4,
1372 .apply_expected = True
1377 * unique,active vs. mhomed,tombstone
1378 * => should NOT be replaced
1381 .line = __location__,
1382 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1385 .type = WREPL_TYPE_UNIQUE,
1386 .state = WREPL_STATE_ACTIVE,
1387 .node = WREPL_NODE_B,
1389 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1390 .ips = addresses_B_3_4,
1391 .apply_expected = True
1395 .type = WREPL_TYPE_MHOMED,
1396 .state = WREPL_STATE_TOMBSTONE,
1397 .node = WREPL_NODE_B,
1399 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1400 .ips = addresses_B_3_4,
1401 .apply_expected = False
1406 * unique,released vs. mhomed,active
1407 * => should be replaced
1410 .line = __location__,
1411 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1414 .type = WREPL_TYPE_UNIQUE,
1415 .state = WREPL_STATE_RELEASED,
1416 .node = WREPL_NODE_B,
1418 .num_ips = ARRAY_SIZE(addresses_B_1),
1419 .ips = addresses_B_1,
1420 .apply_expected = False
1424 .type = WREPL_TYPE_MHOMED,
1425 .state = WREPL_STATE_ACTIVE,
1426 .node = WREPL_NODE_B,
1428 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1429 .ips = addresses_A_3_4,
1430 .apply_expected = True
1435 * unique,released vs. mhomed,tombstone
1436 * => should be replaced
1439 .line = __location__,
1440 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1443 .type = WREPL_TYPE_UNIQUE,
1444 .state = WREPL_STATE_RELEASED,
1445 .node = WREPL_NODE_B,
1447 .num_ips = ARRAY_SIZE(addresses_A_1),
1448 .ips = addresses_A_1,
1449 .apply_expected = False
1453 .type = WREPL_TYPE_MHOMED,
1454 .state = WREPL_STATE_TOMBSTONE,
1455 .node = WREPL_NODE_B,
1457 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1458 .ips = addresses_B_3_4,
1459 .apply_expected = True
1464 * unique,tombstone vs. mhomed,active
1465 * => should be replaced
1468 .line = __location__,
1469 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1472 .type = WREPL_TYPE_UNIQUE,
1473 .state = WREPL_STATE_TOMBSTONE,
1474 .node = WREPL_NODE_B,
1476 .num_ips = ARRAY_SIZE(addresses_B_1),
1477 .ips = addresses_B_1,
1478 .apply_expected = True
1482 .type = WREPL_TYPE_MHOMED,
1483 .state = WREPL_STATE_ACTIVE,
1484 .node = WREPL_NODE_B,
1486 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1487 .ips = addresses_A_3_4,
1488 .apply_expected = True
1493 * unique,tombstone vs. mhomed,tombstone
1494 * => should be replaced
1497 .line = __location__,
1498 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1501 .type = WREPL_TYPE_UNIQUE,
1502 .state = WREPL_STATE_TOMBSTONE,
1503 .node = WREPL_NODE_B,
1505 .num_ips = ARRAY_SIZE(addresses_A_1),
1506 .ips = addresses_A_1,
1507 .apply_expected = True
1511 .type = WREPL_TYPE_MHOMED,
1512 .state = WREPL_STATE_TOMBSTONE,
1513 .node = WREPL_NODE_B,
1515 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1516 .ips = addresses_B_3_4,
1517 .apply_expected = True
1522 * normal groups vs unique section,
1525 * group,active vs. unique,active
1526 * => should NOT be replaced
1529 .line = __location__,
1530 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1533 .type = WREPL_TYPE_GROUP,
1534 .state = WREPL_STATE_ACTIVE,
1535 .node = WREPL_NODE_B,
1537 .num_ips = ARRAY_SIZE(addresses_A_1),
1538 .ips = addresses_A_1,
1539 .apply_expected = True
1543 .type = WREPL_TYPE_UNIQUE,
1544 .state = WREPL_STATE_ACTIVE,
1545 .node = WREPL_NODE_B,
1547 .num_ips = ARRAY_SIZE(addresses_A_1),
1548 .ips = addresses_A_1,
1549 .apply_expected = False
1554 * group,active vs. unique,tombstone
1555 * => should NOT be replaced
1558 .line = __location__,
1559 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1562 .type = WREPL_TYPE_GROUP,
1563 .state = WREPL_STATE_ACTIVE,
1564 .node = WREPL_NODE_B,
1566 .num_ips = ARRAY_SIZE(addresses_A_1),
1567 .ips = addresses_A_1,
1568 .apply_expected = True
1572 .type = WREPL_TYPE_UNIQUE,
1573 .state = WREPL_STATE_TOMBSTONE,
1574 .node = WREPL_NODE_B,
1576 .num_ips = ARRAY_SIZE(addresses_A_1),
1577 .ips = addresses_A_1,
1578 .apply_expected = False
1583 * group,released vs. unique,active
1584 * => should NOT be replaced
1587 .line = __location__,
1588 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1591 .type = WREPL_TYPE_GROUP,
1592 .state = WREPL_STATE_RELEASED,
1593 .node = WREPL_NODE_B,
1595 .num_ips = ARRAY_SIZE(addresses_A_1),
1596 .ips = addresses_A_1,
1597 .apply_expected = False
1601 .type = WREPL_TYPE_UNIQUE,
1602 .state = WREPL_STATE_ACTIVE,
1603 .node = WREPL_NODE_B,
1605 .num_ips = ARRAY_SIZE(addresses_A_1),
1606 .ips = addresses_A_1,
1607 .apply_expected = False
1612 * group,released vs. unique,tombstone
1613 * => should NOT be replaced
1616 .line = __location__,
1617 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1620 .type = WREPL_TYPE_GROUP,
1621 .state = WREPL_STATE_RELEASED,
1622 .node = WREPL_NODE_B,
1624 .num_ips = ARRAY_SIZE(addresses_A_1),
1625 .ips = addresses_A_1,
1626 .apply_expected = False
1630 .type = WREPL_TYPE_UNIQUE,
1631 .state = WREPL_STATE_TOMBSTONE,
1632 .node = WREPL_NODE_B,
1634 .num_ips = ARRAY_SIZE(addresses_A_1),
1635 .ips = addresses_A_1,
1636 .apply_expected = False
1641 * group,tombstone vs. unique,active
1642 * => should NOT be replaced
1645 .line = __location__,
1646 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1649 .type = WREPL_TYPE_GROUP,
1650 .state = WREPL_STATE_TOMBSTONE,
1651 .node = WREPL_NODE_B,
1653 .num_ips = ARRAY_SIZE(addresses_A_1),
1654 .ips = addresses_A_1,
1655 .apply_expected = True
1659 .type = WREPL_TYPE_UNIQUE,
1660 .state = WREPL_STATE_ACTIVE,
1661 .node = WREPL_NODE_B,
1663 .num_ips = ARRAY_SIZE(addresses_A_1),
1664 .ips = addresses_A_1,
1665 .apply_expected = False
1670 * group,tombstone vs. unique,tombstone
1671 * => should NOT be replaced
1674 .line = __location__,
1675 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1678 .type = WREPL_TYPE_GROUP,
1679 .state = WREPL_STATE_TOMBSTONE,
1680 .node = WREPL_NODE_B,
1682 .num_ips = ARRAY_SIZE(addresses_A_1),
1683 .ips = addresses_A_1,
1684 .apply_expected = True
1688 .type = WREPL_TYPE_UNIQUE,
1689 .state = WREPL_STATE_TOMBSTONE,
1690 .node = WREPL_NODE_B,
1692 .num_ips = ARRAY_SIZE(addresses_A_1),
1693 .ips = addresses_A_1,
1694 .apply_expected = False
1699 * normal groups vs normal groups section,
1702 * group,active vs. group,active
1703 * => should NOT be replaced
1706 .line = __location__,
1707 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1710 .type = WREPL_TYPE_GROUP,
1711 .state = WREPL_STATE_ACTIVE,
1712 .node = WREPL_NODE_B,
1714 .num_ips = ARRAY_SIZE(addresses_A_1),
1715 .ips = addresses_A_1,
1716 .apply_expected = True
1720 .type = WREPL_TYPE_GROUP,
1721 .state = WREPL_STATE_ACTIVE,
1722 .node = WREPL_NODE_B,
1724 .num_ips = ARRAY_SIZE(addresses_A_1),
1725 .ips = addresses_A_1,
1726 .apply_expected = False
1731 * group,active vs. group,tombstone
1732 * => should NOT be replaced
1735 .line = __location__,
1736 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1739 .type = WREPL_TYPE_GROUP,
1740 .state = WREPL_STATE_ACTIVE,
1741 .node = WREPL_NODE_B,
1743 .num_ips = ARRAY_SIZE(addresses_A_1),
1744 .ips = addresses_A_1,
1745 .apply_expected = True
1749 .type = WREPL_TYPE_GROUP,
1750 .state = WREPL_STATE_TOMBSTONE,
1751 .node = WREPL_NODE_B,
1753 .num_ips = ARRAY_SIZE(addresses_A_1),
1754 .ips = addresses_A_1,
1755 .apply_expected = False
1760 * group,released vs. group,active
1761 * => should be replaced
1764 .line = __location__,
1765 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1768 .type = WREPL_TYPE_GROUP,
1769 .state = WREPL_STATE_RELEASED,
1770 .node = WREPL_NODE_B,
1772 .num_ips = ARRAY_SIZE(addresses_A_1),
1773 .ips = addresses_A_1,
1774 .apply_expected = False
1778 .type = WREPL_TYPE_GROUP,
1779 .state = WREPL_STATE_ACTIVE,
1780 .node = WREPL_NODE_B,
1782 .num_ips = ARRAY_SIZE(addresses_B_1),
1783 .ips = addresses_B_1,
1784 .apply_expected = True
1789 * group,released vs. group,tombstone
1790 * => should be replaced
1793 .line = __location__,
1794 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1797 .type = WREPL_TYPE_GROUP,
1798 .state = WREPL_STATE_RELEASED,
1799 .node = WREPL_NODE_B,
1801 .num_ips = ARRAY_SIZE(addresses_A_1),
1802 .ips = addresses_A_1,
1803 .apply_expected = False
1807 .type = WREPL_TYPE_GROUP,
1808 .state = WREPL_STATE_TOMBSTONE,
1809 .node = WREPL_NODE_B,
1811 .num_ips = ARRAY_SIZE(addresses_B_1),
1812 .ips = addresses_B_1,
1813 .apply_expected = True
1818 * group,tombstone vs. group,active
1819 * => should be replaced
1822 .line = __location__,
1823 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1826 .type = WREPL_TYPE_GROUP,
1827 .state = WREPL_STATE_TOMBSTONE,
1828 .node = WREPL_NODE_B,
1830 .num_ips = ARRAY_SIZE(addresses_B_1),
1831 .ips = addresses_B_1,
1832 .apply_expected = True
1836 .type = WREPL_TYPE_GROUP,
1837 .state = WREPL_STATE_ACTIVE,
1838 .node = WREPL_NODE_B,
1840 .num_ips = ARRAY_SIZE(addresses_A_1),
1841 .ips = addresses_A_1,
1842 .apply_expected = True
1847 * group,tombstone vs. group,tombstone
1848 * => should be replaced
1851 .line = __location__,
1852 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1855 .type = WREPL_TYPE_GROUP,
1856 .state = WREPL_STATE_TOMBSTONE,
1857 .node = WREPL_NODE_B,
1859 .num_ips = ARRAY_SIZE(addresses_A_1),
1860 .ips = addresses_A_1,
1861 .apply_expected = True
1865 .type = WREPL_TYPE_GROUP,
1866 .state = WREPL_STATE_TOMBSTONE,
1867 .node = WREPL_NODE_B,
1869 .num_ips = ARRAY_SIZE(addresses_B_1),
1870 .ips = addresses_B_1,
1871 .apply_expected = True
1876 * normal groups vs special groups section,
1879 * group,active vs. sgroup,active
1880 * => should NOT be replaced
1883 .line = __location__,
1884 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1887 .type = WREPL_TYPE_GROUP,
1888 .state = WREPL_STATE_ACTIVE,
1889 .node = WREPL_NODE_B,
1891 .num_ips = ARRAY_SIZE(addresses_B_1),
1892 .ips = addresses_B_1,
1893 .apply_expected = True
1897 .type = WREPL_TYPE_SGROUP,
1898 .state = WREPL_STATE_ACTIVE,
1899 .node = WREPL_NODE_B,
1901 .num_ips = ARRAY_SIZE(addresses_B_1),
1902 .ips = addresses_B_1,
1903 .apply_expected = False
1908 * group,active vs. sgroup,tombstone
1909 * => should NOT be replaced
1912 .line = __location__,
1913 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1916 .type = WREPL_TYPE_GROUP,
1917 .state = WREPL_STATE_ACTIVE,
1918 .node = WREPL_NODE_B,
1920 .num_ips = ARRAY_SIZE(addresses_B_1),
1921 .ips = addresses_B_1,
1922 .apply_expected = True
1926 .type = WREPL_TYPE_SGROUP,
1927 .state = WREPL_STATE_TOMBSTONE,
1928 .node = WREPL_NODE_B,
1930 .num_ips = ARRAY_SIZE(addresses_B_1),
1931 .ips = addresses_B_1,
1932 .apply_expected = False
1937 * group,released vs. sgroup,active
1938 * => should be replaced
1941 .line = __location__,
1942 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1945 .type = WREPL_TYPE_GROUP,
1946 .state = WREPL_STATE_RELEASED,
1947 .node = WREPL_NODE_B,
1949 .num_ips = ARRAY_SIZE(addresses_A_1),
1950 .ips = addresses_A_1,
1951 .apply_expected = False
1955 .type = WREPL_TYPE_SGROUP,
1956 .state = WREPL_STATE_ACTIVE,
1957 .node = WREPL_NODE_B,
1959 .num_ips = ARRAY_SIZE(addresses_B_1),
1960 .ips = addresses_B_1,
1961 .apply_expected = True
1966 * group,released vs. sgroup,tombstone
1967 * => should NOT be replaced
1970 .line = __location__,
1971 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1974 .type = WREPL_TYPE_GROUP,
1975 .state = WREPL_STATE_RELEASED,
1976 .node = WREPL_NODE_B,
1978 .num_ips = ARRAY_SIZE(addresses_B_1),
1979 .ips = addresses_B_1,
1980 .apply_expected = False
1984 .type = WREPL_TYPE_SGROUP,
1985 .state = WREPL_STATE_TOMBSTONE,
1986 .node = WREPL_NODE_B,
1988 .num_ips = ARRAY_SIZE(addresses_B_1),
1989 .ips = addresses_B_1,
1990 .apply_expected = False
1995 * group,tombstone vs. sgroup,active
1996 * => should be replaced
1999 .line = __location__,
2000 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2003 .type = WREPL_TYPE_GROUP,
2004 .state = WREPL_STATE_TOMBSTONE,
2005 .node = WREPL_NODE_B,
2007 .num_ips = ARRAY_SIZE(addresses_B_1),
2008 .ips = addresses_B_1,
2009 .apply_expected = True
2013 .type = WREPL_TYPE_SGROUP,
2014 .state = WREPL_STATE_ACTIVE,
2015 .node = WREPL_NODE_B,
2017 .num_ips = ARRAY_SIZE(addresses_A_1),
2018 .ips = addresses_A_1,
2019 .apply_expected = True
2024 * group,tombstone vs. sgroup,tombstone
2025 * => should be replaced
2028 .line = __location__,
2029 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2032 .type = WREPL_TYPE_GROUP,
2033 .state = WREPL_STATE_TOMBSTONE,
2034 .node = WREPL_NODE_B,
2036 .num_ips = ARRAY_SIZE(addresses_A_1),
2037 .ips = addresses_A_1,
2038 .apply_expected = True
2042 .type = WREPL_TYPE_SGROUP,
2043 .state = WREPL_STATE_TOMBSTONE,
2044 .node = WREPL_NODE_B,
2046 .num_ips = ARRAY_SIZE(addresses_B_1),
2047 .ips = addresses_B_1,
2048 .apply_expected = True
2053 * normal groups vs multi homed section,
2056 * group,active vs. mhomed,active
2057 * => should NOT be replaced
2060 .line = __location__,
2061 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2064 .type = WREPL_TYPE_GROUP,
2065 .state = WREPL_STATE_ACTIVE,
2066 .node = WREPL_NODE_B,
2068 .num_ips = ARRAY_SIZE(addresses_B_1),
2069 .ips = addresses_B_1,
2070 .apply_expected = True
2074 .type = WREPL_TYPE_MHOMED,
2075 .state = WREPL_STATE_ACTIVE,
2076 .node = WREPL_NODE_B,
2078 .num_ips = ARRAY_SIZE(addresses_B_1),
2079 .ips = addresses_B_1,
2080 .apply_expected = False
2085 * group,active vs. mhomed,tombstone
2086 * => should NOT be replaced
2089 .line = __location__,
2090 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2093 .type = WREPL_TYPE_GROUP,
2094 .state = WREPL_STATE_ACTIVE,
2095 .node = WREPL_NODE_B,
2097 .num_ips = ARRAY_SIZE(addresses_B_1),
2098 .ips = addresses_B_1,
2099 .apply_expected = True
2103 .type = WREPL_TYPE_MHOMED,
2104 .state = WREPL_STATE_TOMBSTONE,
2105 .node = WREPL_NODE_B,
2107 .num_ips = ARRAY_SIZE(addresses_B_1),
2108 .ips = addresses_B_1,
2109 .apply_expected = False
2114 * group,released vs. mhomed,active
2115 * => should NOT be replaced
2118 .line = __location__,
2119 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2122 .type = WREPL_TYPE_GROUP,
2123 .state = WREPL_STATE_RELEASED,
2124 .node = WREPL_NODE_B,
2126 .num_ips = ARRAY_SIZE(addresses_B_1),
2127 .ips = addresses_B_1,
2128 .apply_expected = False
2132 .type = WREPL_TYPE_MHOMED,
2133 .state = WREPL_STATE_ACTIVE,
2134 .node = WREPL_NODE_B,
2136 .num_ips = ARRAY_SIZE(addresses_B_1),
2137 .ips = addresses_B_1,
2138 .apply_expected = False
2143 * group,released vs. mhomed,tombstone
2144 * => should NOT be replaced
2147 .line = __location__,
2148 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2151 .type = WREPL_TYPE_GROUP,
2152 .state = WREPL_STATE_RELEASED,
2153 .node = WREPL_NODE_B,
2155 .num_ips = ARRAY_SIZE(addresses_B_1),
2156 .ips = addresses_B_1,
2157 .apply_expected = False
2161 .type = WREPL_TYPE_MHOMED,
2162 .state = WREPL_STATE_TOMBSTONE,
2163 .node = WREPL_NODE_B,
2165 .num_ips = ARRAY_SIZE(addresses_B_1),
2166 .ips = addresses_B_1,
2167 .apply_expected = False
2172 * group,tombstone vs. mhomed,active
2173 * => should be replaced
2176 .line = __location__,
2177 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2180 .type = WREPL_TYPE_GROUP,
2181 .state = WREPL_STATE_TOMBSTONE,
2182 .node = WREPL_NODE_B,
2184 .num_ips = ARRAY_SIZE(addresses_B_1),
2185 .ips = addresses_B_1,
2186 .apply_expected = True
2190 .type = WREPL_TYPE_MHOMED,
2191 .state = WREPL_STATE_ACTIVE,
2192 .node = WREPL_NODE_B,
2194 .num_ips = ARRAY_SIZE(addresses_A_1),
2195 .ips = addresses_A_1,
2196 .apply_expected = True
2201 * group,tombstone vs. mhomed,tombstone
2202 * => should be replaced
2205 .line = __location__,
2206 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2209 .type = WREPL_TYPE_GROUP,
2210 .state = WREPL_STATE_TOMBSTONE,
2211 .node = WREPL_NODE_B,
2213 .num_ips = ARRAY_SIZE(addresses_A_1),
2214 .ips = addresses_A_1,
2215 .apply_expected = True
2219 .type = WREPL_TYPE_MHOMED,
2220 .state = WREPL_STATE_TOMBSTONE,
2221 .node = WREPL_NODE_B,
2223 .num_ips = ARRAY_SIZE(addresses_B_1),
2224 .ips = addresses_B_1,
2225 .apply_expected = True
2230 * special groups vs unique section,
2233 * sgroup,active vs. unique,active
2234 * => should NOT be replaced
2237 .line = __location__,
2238 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2241 .type = WREPL_TYPE_SGROUP,
2242 .state = WREPL_STATE_ACTIVE,
2243 .node = WREPL_NODE_B,
2245 .num_ips = ARRAY_SIZE(addresses_B_1),
2246 .ips = addresses_B_1,
2247 .apply_expected = True
2251 .type = WREPL_TYPE_UNIQUE,
2252 .state = WREPL_STATE_ACTIVE,
2253 .node = WREPL_NODE_B,
2255 .num_ips = ARRAY_SIZE(addresses_B_1),
2256 .ips = addresses_B_1,
2257 .apply_expected = False
2262 * sgroup,active vs. unique,tombstone
2263 * => should NOT be replaced
2266 .line = __location__,
2267 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2270 .type = WREPL_TYPE_SGROUP,
2271 .state = WREPL_STATE_ACTIVE,
2272 .node = WREPL_NODE_B,
2274 .num_ips = ARRAY_SIZE(addresses_B_1),
2275 .ips = addresses_B_1,
2276 .apply_expected = True
2280 .type = WREPL_TYPE_UNIQUE,
2281 .state = WREPL_STATE_TOMBSTONE,
2282 .node = WREPL_NODE_B,
2284 .num_ips = ARRAY_SIZE(addresses_B_1),
2285 .ips = addresses_B_1,
2286 .apply_expected = False
2291 * sgroup,released vs. unique,active
2292 * => should be replaced
2295 .line = __location__,
2296 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2299 .type = WREPL_TYPE_SGROUP,
2300 .state = WREPL_STATE_RELEASED,
2301 .node = WREPL_NODE_B,
2303 .num_ips = ARRAY_SIZE(addresses_B_1),
2304 .ips = addresses_B_1,
2305 .apply_expected = False
2309 .type = WREPL_TYPE_UNIQUE,
2310 .state = WREPL_STATE_ACTIVE,
2311 .node = WREPL_NODE_B,
2313 .num_ips = ARRAY_SIZE(addresses_A_1),
2314 .ips = addresses_A_1,
2315 .apply_expected = True
2320 * sgroup,released vs. unique,tombstone
2321 * => should be replaced
2324 .line = __location__,
2325 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2328 .type = WREPL_TYPE_SGROUP,
2329 .state = WREPL_STATE_RELEASED,
2330 .node = WREPL_NODE_B,
2332 .num_ips = ARRAY_SIZE(addresses_A_1),
2333 .ips = addresses_A_1,
2334 .apply_expected = False
2338 .type = WREPL_TYPE_UNIQUE,
2339 .state = WREPL_STATE_TOMBSTONE,
2340 .node = WREPL_NODE_B,
2342 .num_ips = ARRAY_SIZE(addresses_B_1),
2343 .ips = addresses_B_1,
2344 .apply_expected = True
2349 * sgroup,tombstone vs. unique,active
2350 * => should be replaced
2353 .line = __location__,
2354 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2357 .type = WREPL_TYPE_SGROUP,
2358 .state = WREPL_STATE_TOMBSTONE,
2359 .node = WREPL_NODE_B,
2361 .num_ips = ARRAY_SIZE(addresses_A_1),
2362 .ips = addresses_A_1,
2363 .apply_expected = True
2367 .type = WREPL_TYPE_UNIQUE,
2368 .state = WREPL_STATE_ACTIVE,
2369 .node = WREPL_NODE_B,
2371 .num_ips = ARRAY_SIZE(addresses_B_1),
2372 .ips = addresses_B_1,
2373 .apply_expected = True
2378 * sgroup,tombstone vs. unique,tombstone
2379 * => should be replaced
2382 .line = __location__,
2383 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2386 .type = WREPL_TYPE_SGROUP,
2387 .state = WREPL_STATE_TOMBSTONE,
2388 .node = WREPL_NODE_B,
2390 .num_ips = ARRAY_SIZE(addresses_B_1),
2391 .ips = addresses_B_1,
2392 .apply_expected = True
2396 .type = WREPL_TYPE_UNIQUE,
2397 .state = WREPL_STATE_TOMBSTONE,
2398 .node = WREPL_NODE_B,
2400 .num_ips = ARRAY_SIZE(addresses_A_1),
2401 .ips = addresses_A_1,
2402 .apply_expected = True
2407 * special groups vs normal group section,
2410 * sgroup,active vs. group,active
2411 * => should NOT be replaced
2414 .line = __location__,
2415 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2418 .type = WREPL_TYPE_SGROUP,
2419 .state = WREPL_STATE_ACTIVE,
2420 .node = WREPL_NODE_B,
2422 .num_ips = ARRAY_SIZE(addresses_A_1),
2423 .ips = addresses_A_1,
2424 .apply_expected = True
2428 .type = WREPL_TYPE_GROUP,
2429 .state = WREPL_STATE_ACTIVE,
2430 .node = WREPL_NODE_B,
2432 .num_ips = ARRAY_SIZE(addresses_A_1),
2433 .ips = addresses_A_1,
2434 .apply_expected = False
2439 * sgroup,active vs. group,tombstone
2440 * => should NOT be replaced
2443 .line = __location__,
2444 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2447 .type = WREPL_TYPE_SGROUP,
2448 .state = WREPL_STATE_ACTIVE,
2449 .node = WREPL_NODE_B,
2451 .num_ips = ARRAY_SIZE(addresses_A_1),
2452 .ips = addresses_A_1,
2453 .apply_expected = True
2457 .type = WREPL_TYPE_GROUP,
2458 .state = WREPL_STATE_TOMBSTONE,
2459 .node = WREPL_NODE_B,
2461 .num_ips = ARRAY_SIZE(addresses_A_1),
2462 .ips = addresses_A_1,
2463 .apply_expected = False
2468 * sgroup,released vs. group,active
2469 * => should be replaced
2472 .line = __location__,
2473 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2476 .type = WREPL_TYPE_SGROUP,
2477 .state = WREPL_STATE_RELEASED,
2478 .node = WREPL_NODE_B,
2480 .num_ips = ARRAY_SIZE(addresses_A_1),
2481 .ips = addresses_A_1,
2482 .apply_expected = False
2486 .type = WREPL_TYPE_GROUP,
2487 .state = WREPL_STATE_ACTIVE,
2488 .node = WREPL_NODE_B,
2490 .num_ips = ARRAY_SIZE(addresses_B_1),
2491 .ips = addresses_B_1,
2492 .apply_expected = True
2497 * sgroup,released vs. group,tombstone
2498 * => should be replaced
2501 .line = __location__,
2502 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2505 .type = WREPL_TYPE_SGROUP,
2506 .state = WREPL_STATE_RELEASED,
2507 .node = WREPL_NODE_B,
2509 .num_ips = ARRAY_SIZE(addresses_B_1),
2510 .ips = addresses_B_1,
2511 .apply_expected = False
2515 .type = WREPL_TYPE_GROUP,
2516 .state = WREPL_STATE_TOMBSTONE,
2517 .node = WREPL_NODE_B,
2519 .num_ips = ARRAY_SIZE(addresses_A_1),
2520 .ips = addresses_A_1,
2521 .apply_expected = True
2526 * sgroup,tombstone vs. group,active
2527 * => should NOT be replaced
2530 .line = __location__,
2531 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2534 .type = WREPL_TYPE_SGROUP,
2535 .state = WREPL_STATE_TOMBSTONE,
2536 .node = WREPL_NODE_B,
2538 .num_ips = ARRAY_SIZE(addresses_A_1),
2539 .ips = addresses_A_1,
2540 .apply_expected = True
2544 .type = WREPL_TYPE_GROUP,
2545 .state = WREPL_STATE_ACTIVE,
2546 .node = WREPL_NODE_B,
2548 .num_ips = ARRAY_SIZE(addresses_B_1),
2549 .ips = addresses_B_1,
2550 .apply_expected = True
2555 * sgroup,tombstone vs. group,tombstone
2556 * => should NOT be replaced
2559 .line = __location__,
2560 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2563 .type = WREPL_TYPE_SGROUP,
2564 .state = WREPL_STATE_TOMBSTONE,
2565 .node = WREPL_NODE_B,
2567 .num_ips = ARRAY_SIZE(addresses_B_1),
2568 .ips = addresses_B_1,
2569 .apply_expected = True
2573 .type = WREPL_TYPE_GROUP,
2574 .state = WREPL_STATE_TOMBSTONE,
2575 .node = WREPL_NODE_B,
2577 .num_ips = ARRAY_SIZE(addresses_A_1),
2578 .ips = addresses_A_1,
2579 .apply_expected = True
2584 * special groups vs multi homed section,
2587 * sgroup,active vs. mhomed,active
2588 * => should NOT be replaced
2591 .line = __location__,
2592 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2595 .type = WREPL_TYPE_SGROUP,
2596 .state = WREPL_STATE_ACTIVE,
2597 .node = WREPL_NODE_B,
2599 .num_ips = ARRAY_SIZE(addresses_A_1),
2600 .ips = addresses_A_1,
2601 .apply_expected = True
2605 .type = WREPL_TYPE_MHOMED,
2606 .state = WREPL_STATE_ACTIVE,
2607 .node = WREPL_NODE_B,
2609 .num_ips = ARRAY_SIZE(addresses_A_1),
2610 .ips = addresses_A_1,
2611 .apply_expected = False
2616 * sgroup,active vs. mhomed,tombstone
2617 * => should NOT be replaced
2620 .line = __location__,
2621 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2624 .type = WREPL_TYPE_SGROUP,
2625 .state = WREPL_STATE_ACTIVE,
2626 .node = WREPL_NODE_B,
2628 .num_ips = ARRAY_SIZE(addresses_A_1),
2629 .ips = addresses_A_1,
2630 .apply_expected = True
2634 .type = WREPL_TYPE_MHOMED,
2635 .state = WREPL_STATE_TOMBSTONE,
2636 .node = WREPL_NODE_B,
2638 .num_ips = ARRAY_SIZE(addresses_A_1),
2639 .ips = addresses_A_1,
2640 .apply_expected = False
2645 * sgroup,released vs. mhomed,active
2646 * => should be replaced
2649 .line = __location__,
2650 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2653 .type = WREPL_TYPE_SGROUP,
2654 .state = WREPL_STATE_RELEASED,
2655 .node = WREPL_NODE_B,
2657 .num_ips = ARRAY_SIZE(addresses_A_1),
2658 .ips = addresses_A_1,
2659 .apply_expected = False
2663 .type = WREPL_TYPE_MHOMED,
2664 .state = WREPL_STATE_ACTIVE,
2665 .node = WREPL_NODE_B,
2667 .num_ips = ARRAY_SIZE(addresses_B_1),
2668 .ips = addresses_B_1,
2669 .apply_expected = True
2674 * sgroup,released vs. mhomed,tombstone
2675 * => should be replaced
2678 .line = __location__,
2679 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2682 .type = WREPL_TYPE_SGROUP,
2683 .state = WREPL_STATE_RELEASED,
2684 .node = WREPL_NODE_B,
2686 .num_ips = ARRAY_SIZE(addresses_B_1),
2687 .ips = addresses_B_1,
2688 .apply_expected = False
2692 .type = WREPL_TYPE_MHOMED,
2693 .state = WREPL_STATE_TOMBSTONE,
2694 .node = WREPL_NODE_B,
2696 .num_ips = ARRAY_SIZE(addresses_A_1),
2697 .ips = addresses_A_1,
2698 .apply_expected = True
2703 * sgroup,tombstone vs. mhomed,active
2704 * => should be replaced
2707 .line = __location__,
2708 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2711 .type = WREPL_TYPE_SGROUP,
2712 .state = WREPL_STATE_TOMBSTONE,
2713 .node = WREPL_NODE_B,
2715 .num_ips = ARRAY_SIZE(addresses_A_1),
2716 .ips = addresses_A_1,
2717 .apply_expected = True
2721 .type = WREPL_TYPE_MHOMED,
2722 .state = WREPL_STATE_ACTIVE,
2723 .node = WREPL_NODE_B,
2725 .num_ips = ARRAY_SIZE(addresses_B_1),
2726 .ips = addresses_B_1,
2727 .apply_expected = True
2732 * sgroup,tombstone vs. mhomed,tombstone
2733 * => should be replaced
2736 .line = __location__,
2737 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2740 .type = WREPL_TYPE_SGROUP,
2741 .state = WREPL_STATE_TOMBSTONE,
2742 .node = WREPL_NODE_B,
2744 .num_ips = ARRAY_SIZE(addresses_B_1),
2745 .ips = addresses_B_1,
2746 .apply_expected = True
2750 .type = WREPL_TYPE_MHOMED,
2751 .state = WREPL_STATE_TOMBSTONE,
2752 .node = WREPL_NODE_B,
2754 .num_ips = ARRAY_SIZE(addresses_A_1),
2755 .ips = addresses_A_1,
2756 .apply_expected = True
2761 * multi homed vs. normal group section,
2764 * mhomed,active vs. group,active
2765 * => should be replaced
2768 .line = __location__,
2769 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2772 .type = WREPL_TYPE_MHOMED,
2773 .state = WREPL_STATE_ACTIVE,
2774 .node = WREPL_NODE_B,
2776 .num_ips = ARRAY_SIZE(addresses_A_1),
2777 .ips = addresses_A_1,
2778 .apply_expected = True
2782 .type = WREPL_TYPE_GROUP,
2783 .state = WREPL_STATE_ACTIVE,
2784 .node = WREPL_NODE_B,
2786 .num_ips = ARRAY_SIZE(addresses_B_1),
2787 .ips = addresses_B_1,
2788 .apply_expected = True
2793 * mhomed,active vs. group,tombstone
2794 * => should NOT be replaced
2797 .line = __location__,
2798 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2801 .type = WREPL_TYPE_MHOMED,
2802 .state = WREPL_STATE_ACTIVE,
2803 .node = WREPL_NODE_B,
2805 .num_ips = ARRAY_SIZE(addresses_B_1),
2806 .ips = addresses_B_1,
2807 .apply_expected = True
2811 .type = WREPL_TYPE_GROUP,
2812 .state = WREPL_STATE_TOMBSTONE,
2813 .node = WREPL_NODE_B,
2815 .num_ips = ARRAY_SIZE(addresses_B_1),
2816 .ips = addresses_B_1,
2817 .apply_expected = False
2822 * mhomed,released vs. group,active
2823 * => should be replaced
2826 .line = __location__,
2827 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2830 .type = WREPL_TYPE_MHOMED,
2831 .state = WREPL_STATE_RELEASED,
2832 .node = WREPL_NODE_B,
2834 .num_ips = ARRAY_SIZE(addresses_B_1),
2835 .ips = addresses_B_1,
2836 .apply_expected = False
2840 .type = WREPL_TYPE_GROUP,
2841 .state = WREPL_STATE_ACTIVE,
2842 .node = WREPL_NODE_B,
2844 .num_ips = ARRAY_SIZE(addresses_A_1),
2845 .ips = addresses_A_1,
2846 .apply_expected = True
2851 * mhomed,released vs. group,tombstone
2852 * => should be replaced
2855 .line = __location__,
2856 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2859 .type = WREPL_TYPE_MHOMED,
2860 .state = WREPL_STATE_RELEASED,
2861 .node = WREPL_NODE_B,
2863 .num_ips = ARRAY_SIZE(addresses_A_1),
2864 .ips = addresses_A_1,
2865 .apply_expected = False
2869 .type = WREPL_TYPE_GROUP,
2870 .state = WREPL_STATE_TOMBSTONE,
2871 .node = WREPL_NODE_B,
2873 .num_ips = ARRAY_SIZE(addresses_B_1),
2874 .ips = addresses_B_1,
2875 .apply_expected = True
2880 * mhomed,tombstone vs. group,active
2881 * => should be replaced
2884 .line = __location__,
2885 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2888 .type = WREPL_TYPE_MHOMED,
2889 .state = WREPL_STATE_TOMBSTONE,
2890 .node = WREPL_NODE_B,
2892 .num_ips = ARRAY_SIZE(addresses_B_1),
2893 .ips = addresses_B_1,
2894 .apply_expected = True
2898 .type = WREPL_TYPE_GROUP,
2899 .state = WREPL_STATE_ACTIVE,
2900 .node = WREPL_NODE_B,
2902 .num_ips = ARRAY_SIZE(addresses_A_1),
2903 .ips = addresses_A_1,
2904 .apply_expected = True
2909 * mhomed,tombstone vs. group,tombstone
2910 * => should be replaced
2913 .line = __location__,
2914 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2917 .type = WREPL_TYPE_MHOMED,
2918 .state = WREPL_STATE_TOMBSTONE,
2919 .node = WREPL_NODE_B,
2921 .num_ips = ARRAY_SIZE(addresses_A_1),
2922 .ips = addresses_A_1,
2923 .apply_expected = True
2927 .type = WREPL_TYPE_GROUP,
2928 .state = WREPL_STATE_TOMBSTONE,
2929 .node = WREPL_NODE_B,
2931 .num_ips = ARRAY_SIZE(addresses_B_1),
2932 .ips = addresses_B_1,
2933 .apply_expected = True
2938 * multi homed vs. special group section,
2941 * mhomed,active vs. sgroup,active
2942 * => should NOT be replaced
2945 .line = __location__,
2946 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2949 .type = WREPL_TYPE_MHOMED,
2950 .state = WREPL_STATE_ACTIVE,
2951 .node = WREPL_NODE_B,
2953 .num_ips = ARRAY_SIZE(addresses_A_1),
2954 .ips = addresses_A_1,
2955 .apply_expected = True
2959 .type = WREPL_TYPE_SGROUP,
2960 .state = WREPL_STATE_ACTIVE,
2961 .node = WREPL_NODE_B,
2963 .num_ips = ARRAY_SIZE(addresses_A_1),
2964 .ips = addresses_A_1,
2965 .apply_expected = False
2970 * mhomed,active vs. group,tombstone
2971 * => should NOT be replaced
2974 .line = __location__,
2975 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2978 .type = WREPL_TYPE_MHOMED,
2979 .state = WREPL_STATE_ACTIVE,
2980 .node = WREPL_NODE_B,
2982 .num_ips = ARRAY_SIZE(addresses_A_1),
2983 .ips = addresses_A_1,
2984 .apply_expected = True
2988 .type = WREPL_TYPE_SGROUP,
2989 .state = WREPL_STATE_TOMBSTONE,
2990 .node = WREPL_NODE_B,
2992 .num_ips = ARRAY_SIZE(addresses_A_1),
2993 .ips = addresses_A_1,
2994 .apply_expected = False
2999 * mhomed,released vs. sgroup,active
3000 * => should be replaced
3003 .line = __location__,
3004 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3007 .type = WREPL_TYPE_MHOMED,
3008 .state = WREPL_STATE_RELEASED,
3009 .node = WREPL_NODE_B,
3011 .num_ips = ARRAY_SIZE(addresses_A_1),
3012 .ips = addresses_A_1,
3013 .apply_expected = False
3017 .type = WREPL_TYPE_SGROUP,
3018 .state = WREPL_STATE_ACTIVE,
3019 .node = WREPL_NODE_B,
3021 .num_ips = ARRAY_SIZE(addresses_B_1),
3022 .ips = addresses_B_1,
3023 .apply_expected = True
3028 * mhomed,released vs. group,tombstone
3029 * => should be replaced
3032 .line = __location__,
3033 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3036 .type = WREPL_TYPE_MHOMED,
3037 .state = WREPL_STATE_RELEASED,
3038 .node = WREPL_NODE_B,
3040 .num_ips = ARRAY_SIZE(addresses_B_1),
3041 .ips = addresses_B_1,
3042 .apply_expected = False
3046 .type = WREPL_TYPE_SGROUP,
3047 .state = WREPL_STATE_TOMBSTONE,
3048 .node = WREPL_NODE_B,
3050 .num_ips = ARRAY_SIZE(addresses_A_1),
3051 .ips = addresses_A_1,
3052 .apply_expected = True
3057 * mhomed,tombstone vs. sgroup,active
3058 * => should be replaced
3061 .line = __location__,
3062 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3065 .type = WREPL_TYPE_MHOMED,
3066 .state = WREPL_STATE_TOMBSTONE,
3067 .node = WREPL_NODE_B,
3069 .num_ips = ARRAY_SIZE(addresses_A_1),
3070 .ips = addresses_A_1,
3071 .apply_expected = True
3075 .type = WREPL_TYPE_SGROUP,
3076 .state = WREPL_STATE_ACTIVE,
3077 .node = WREPL_NODE_B,
3079 .num_ips = ARRAY_SIZE(addresses_B_1),
3080 .ips = addresses_B_1,
3081 .apply_expected = True
3086 * mhomed,tombstone vs. group,tombstone
3087 * => should be replaced
3090 .line = __location__,
3091 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3094 .type = WREPL_TYPE_MHOMED,
3095 .state = WREPL_STATE_TOMBSTONE,
3096 .node = WREPL_NODE_B,
3098 .num_ips = ARRAY_SIZE(addresses_B_1),
3099 .ips = addresses_B_1,
3100 .apply_expected = True
3104 .type = WREPL_TYPE_SGROUP,
3105 .state = WREPL_STATE_TOMBSTONE,
3106 .node = WREPL_NODE_B,
3108 .num_ips = ARRAY_SIZE(addresses_A_1),
3109 .ips = addresses_A_1,
3110 .apply_expected = True
3117 * special group vs special group section,
3120 * sgroup,active vs. sgroup,active
3121 * => should be merged
3124 .line = __location__,
3125 .name = _NBT_NAME("_DIFF_OWNER_SG", 0x00, NULL),
3129 .type = WREPL_TYPE_SGROUP,
3130 .state = WREPL_STATE_ACTIVE,
3131 .node = WREPL_NODE_B,
3133 .num_ips = ARRAY_SIZE(addresses_A_3_4),
3134 .ips = addresses_A_3_4,
3135 .apply_expected = True,
3139 .type = WREPL_TYPE_SGROUP,
3140 .state = WREPL_STATE_ACTIVE,
3141 .node = WREPL_NODE_B,
3143 .num_ips = ARRAY_SIZE(addresses_B_3_4),
3144 .ips = addresses_B_3_4,
3145 .apply_expected = False,
3146 .merge_expected = True
3150 .line = __location__,
3151 .name = _NBT_NAME("_DIFF_OWNER_SG", 0x00, NULL),
3155 .type = WREPL_TYPE_SGROUP,
3156 .state = WREPL_STATE_ACTIVE,
3157 .node = WREPL_NODE_B,
3161 .apply_expected = False
3165 .type = WREPL_TYPE_SGROUP,
3166 .state = WREPL_STATE_ACTIVE,
3167 .node = WREPL_NODE_B,
3171 .apply_expected = False,
3172 .merge_expected = False
3176 .line = __location__,
3177 .name = _NBT_NAME("_DIFF_OWNER_SG", 0x00, NULL),
3181 .type = WREPL_TYPE_SGROUP,
3182 .state = WREPL_STATE_ACTIVE,
3183 .node = WREPL_NODE_B,
3185 .num_ips = ARRAY_SIZE(addresses_A_1),
3186 .ips = addresses_A_1,
3187 .apply_expected = True
3191 .type = WREPL_TYPE_UNIQUE,
3192 .state = WREPL_STATE_TOMBSTONE,
3193 .node = WREPL_NODE_B,
3195 .num_ips = ARRAY_SIZE(addresses_A_1),
3196 .ips = addresses_A_1,
3197 .apply_expected = True
3202 * This should be the last record in this array,
3203 * we need to make sure the we leave a tombstoned unique entry
3207 .line = __location__,
3208 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3212 .type = WREPL_TYPE_UNIQUE,
3213 .state = WREPL_STATE_TOMBSTONE,
3214 .node = WREPL_NODE_B,
3216 .num_ips = ARRAY_SIZE(addresses_A_1),
3217 .ips = addresses_A_1,
3218 .apply_expected = True
3222 .type = WREPL_TYPE_UNIQUE,
3223 .state = WREPL_STATE_TOMBSTONE,
3224 .node = WREPL_NODE_B,
3226 .num_ips = ARRAY_SIZE(addresses_A_1),
3227 .ips = addresses_A_1,
3228 .apply_expected = True
3230 }}; /* do not add entries here, this should be the last record! */
3232 if (!ctx) return False;
3234 wins_name_r1 = &wins_name1;
3235 wins_name_r2 = &wins_name2;
3237 printf("Test Replica Conflicts with different owners\n");
3239 for(i=0; ret && i < ARRAY_SIZE(records); i++) {
3241 if (!records[i].extra && !records[i].cleanup) {
3242 /* we should test the worst cases */
3243 if (records[i].r2.apply_expected && records[i].r1.ips==records[i].r2.ips) {
3244 printf("(%s) Programmer error, invalid record[%u]: %s\n",
3245 __location__, i, records[i].line);
3247 } else if (!records[i].r2.apply_expected && records[i].r1.ips!=records[i].r2.ips) {
3248 printf("(%s) Programmer error, invalid record[%u]: %s\n",
3249 __location__, i, records[i].line);
3254 if (!records[i].cleanup) {
3255 const char *expected;
3258 if (records[i].r2.merge_expected) {
3260 } else if (records[i].r2.apply_expected) {
3261 expected = "REPLACE";
3263 expected = "NOT REPLACE";
3266 if (!records[i].r1.ips && !records[i].r2.ips) {
3268 } else if (records[i].r1.ips==records[i].r2.ips) {
3274 printf("%s,%s%s vs. %s,%s%s with %s ip(s) => %s\n",
3275 wrepl_name_type_string(records[i].r1.type),
3276 wrepl_name_state_string(records[i].r1.state),
3277 (records[i].r1.is_static?",static":""),
3278 wrepl_name_type_string(records[i].r2.type),
3279 wrepl_name_state_string(records[i].r2.state),
3280 (records[i].r2.is_static?",static":""),
3287 wins_name_r1->name = &records[i].name;
3288 wins_name_r1->flags = WREPL_NAME_FLAGS(records[i].r1.type,
3289 records[i].r1.state,
3291 records[i].r1.is_static);
3292 wins_name_r1->id = ++records[i].r1.owner->max_version;
3293 if (wins_name_r1->flags & 2) {
3294 wins_name_r1->addresses.addresses.num_ips = records[i].r1.num_ips;
3295 wins_name_r1->addresses.addresses.ips = discard_const(records[i].r1.ips);
3297 wins_name_r1->addresses.ip = records[i].r1.ips[0].ip;
3299 wins_name_r1->unknown = "255.255.255.255";
3302 ret &= test_wrepl_update_one(ctx, records[i].r1.owner, wins_name_r1);
3303 ret &= test_wrepl_is_applied(ctx, records[i].r1.owner,
3304 wins_name_r1, records[i].r1.apply_expected);
3309 wins_name_r2->name = &records[i].name;
3310 wins_name_r2->flags = WREPL_NAME_FLAGS(records[i].r2.type,
3311 records[i].r2.state,
3313 records[i].r2.is_static);
3314 wins_name_r2->id = ++records[i].r2.owner->max_version;
3315 if (wins_name_r2->flags & 2) {
3316 wins_name_r2->addresses.addresses.num_ips = records[i].r2.num_ips;
3317 wins_name_r2->addresses.addresses.ips = discard_const(records[i].r2.ips);
3319 wins_name_r2->addresses.ip = records[i].r2.ips[0].ip;
3321 wins_name_r2->unknown = "255.255.255.255";
3324 ret &= test_wrepl_update_one(ctx, records[i].r2.owner, wins_name_r2);
3325 if (records[i].r1.state == WREPL_STATE_RELEASED) {
3326 ret &= test_wrepl_is_applied(ctx, records[i].r1.owner,
3327 wins_name_r1, False);
3328 } else if (records[i].r2.merge_expected) {
3329 ret &= test_wrepl_is_merged(ctx, wins_name_r1, wins_name_r2);
3330 } else if (records[i].r1.owner != records[i].r2.owner) {
3332 _expected = (records[i].r1.apply_expected && !records[i].r2.apply_expected);
3333 ret &= test_wrepl_is_applied(ctx, records[i].r1.owner,
3334 wins_name_r1, _expected);
3336 if (records[i].r2.state == WREPL_STATE_RELEASED) {
3337 ret &= test_wrepl_is_applied(ctx, records[i].r2.owner,
3338 wins_name_r2, False);
3339 } else if (!records[i].r2.merge_expected) {
3340 ret &= test_wrepl_is_applied(ctx, records[i].r2.owner,
3341 wins_name_r2, records[i].r2.apply_expected);
3344 /* the first one is a cleanup run */
3345 if (!ret && i == 0) ret = True;
3348 printf("conflict handled wrong or record[%u]: %s\n", i, records[i].line);
3357 test WINS replication operations
3359 BOOL torture_nbt_winsreplication_quick(void)
3361 const char *address;
3362 struct nbt_name name;
3363 TALLOC_CTX *mem_ctx = talloc_new(NULL);
3367 make_nbt_name_server(&name, lp_parm_string(-1, "torture", "host"));
3369 /* do an initial name resolution to find its IP */
3370 status = resolve_name(&name, mem_ctx, &address, NULL);
3371 if (!NT_STATUS_IS_OK(status)) {
3372 printf("Failed to resolve %s - %s\n",
3373 name.name, nt_errstr(status));
3374 talloc_free(mem_ctx);
3378 ret &= test_assoc_ctx1(mem_ctx, address);
3379 ret &= test_assoc_ctx2(mem_ctx, address);
3381 talloc_free(mem_ctx);
3387 test WINS replication operations
3389 BOOL torture_nbt_winsreplication(void)
3391 const char *address;
3392 struct nbt_name name;
3393 TALLOC_CTX *mem_ctx = talloc_new(NULL);
3396 struct test_wrepl_conflict_conn *ctx;
3398 make_nbt_name_server(&name, lp_parm_string(-1, "torture", "host"));
3400 /* do an initial name resolution to find its IP */
3401 status = resolve_name(&name, mem_ctx, &address, NULL);
3402 if (!NT_STATUS_IS_OK(status)) {
3403 printf("Failed to resolve %s - %s\n",
3404 name.name, nt_errstr(status));
3405 talloc_free(mem_ctx);
3409 ret &= test_assoc_ctx1(mem_ctx, address);
3410 ret &= test_assoc_ctx2(mem_ctx, address);
3412 ret &= test_wins_replication(mem_ctx, address);
3414 ctx = test_create_conflict_ctx(mem_ctx, address);
3416 ret &= test_conflict_same_owner(ctx);
3417 ret &= test_conflict_different_owner(ctx);
3419 talloc_free(mem_ctx);