dsdb: don't allow a missing nTSecurityDescriptor in dsdb_get_sd_from_ldb_message()
[Samba/gebeck_regimport.git] / source4 / torture / nbt / winsreplication.c
blobfef539c42697045630a3fc9123e1996866b241b1
1 /*
2 Unix SMB/CIFS implementation.
4 WINS replication testing
6 Copyright (C) Andrew Tridgell 2005
7 Copyright (C) Stefan Metzmacher 2005
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
24 #include "libcli/wrepl/winsrepl.h"
25 #include "lib/events/events.h"
26 #include "lib/socket/socket.h"
27 #include "system/network.h"
28 #include "lib/socket/netif.h"
29 #include "librpc/gen_ndr/ndr_nbt.h"
30 #include "libcli/nbt/libnbt.h"
31 #include "torture/torture.h"
32 #include "torture/nbt/proto.h"
33 #include "param/param.h"
35 #define CHECK_STATUS(tctx, status, correct) \
36 torture_assert_ntstatus_equal(tctx, status, correct, \
37 "Incorrect status")
39 #define CHECK_VALUE(tctx, v, correct) \
40 torture_assert(tctx, (v) == (correct), \
41 talloc_asprintf(tctx, "Incorrect value %s=%d - should be %d\n", \
42 #v, v, correct))
44 #define CHECK_VALUE_UINT64(tctx, v, correct) \
45 torture_assert(tctx, (v) == (correct), \
46 talloc_asprintf(tctx, "Incorrect value %s=%llu - should be %llu\n", \
47 #v, (long long)v, (long long)correct))
49 #define CHECK_VALUE_STRING(tctx, v, correct) \
50 torture_assert_str_equal(tctx, v, correct, "Invalid value")
52 #define _NBT_NAME(n,t,s) {\
53 .name = n,\
54 .type = t,\
55 .scope = s\
58 static const char *wrepl_name_type_string(enum wrepl_name_type type)
60 switch (type) {
61 case WREPL_TYPE_UNIQUE: return "UNIQUE";
62 case WREPL_TYPE_GROUP: return "GROUP";
63 case WREPL_TYPE_SGROUP: return "SGROUP";
64 case WREPL_TYPE_MHOMED: return "MHOMED";
66 return "UNKNOWN_TYPE";
69 static const char *wrepl_name_state_string(enum wrepl_name_state state)
71 switch (state) {
72 case WREPL_STATE_ACTIVE: return "ACTIVE";
73 case WREPL_STATE_RELEASED: return "RELEASED";
74 case WREPL_STATE_TOMBSTONE: return "TOMBSTONE";
75 case WREPL_STATE_RESERVED: return "RESERVED";
77 return "UNKNOWN_STATE";
81 test how assoc_ctx's are only usable on the connection
82 they are created on.
84 static bool test_assoc_ctx1(struct torture_context *tctx)
86 bool ret = true;
87 struct tevent_req *subreq;
88 struct wrepl_socket *wrepl_socket1;
89 struct wrepl_associate associate1;
90 struct wrepl_socket *wrepl_socket2;
91 struct wrepl_associate associate2;
92 struct wrepl_packet packet;
93 struct wrepl_send_ctrl ctrl;
94 struct wrepl_packet *rep_packet;
95 struct wrepl_associate_stop assoc_stop;
96 NTSTATUS status;
97 struct nbt_name name;
98 const char *address;
99 bool ok;
101 if (!torture_nbt_get_name(tctx, &name, &address))
102 return false;
104 torture_comment(tctx, "Test if assoc_ctx is only valid on the conection it was created on\n");
106 wrepl_socket1 = wrepl_socket_init(tctx, tctx->ev);
107 wrepl_socket2 = wrepl_socket_init(tctx, tctx->ev);
109 torture_comment(tctx, "Setup 2 wrepl connections\n");
110 status = wrepl_connect(wrepl_socket1, wrepl_best_ip(tctx->lp_ctx, address), address);
111 CHECK_STATUS(tctx, status, NT_STATUS_OK);
113 status = wrepl_connect(wrepl_socket2, wrepl_best_ip(tctx->lp_ctx, address), address);
114 CHECK_STATUS(tctx, status, NT_STATUS_OK);
116 torture_comment(tctx, "Send a start association request (conn1)\n");
117 status = wrepl_associate(wrepl_socket1, &associate1);
118 CHECK_STATUS(tctx, status, NT_STATUS_OK);
120 torture_comment(tctx, "association context (conn1): 0x%x\n", associate1.out.assoc_ctx);
122 torture_comment(tctx, "Send a start association request (conn2)\n");
123 status = wrepl_associate(wrepl_socket2, &associate2);
124 CHECK_STATUS(tctx, status, NT_STATUS_OK);
126 torture_comment(tctx, "association context (conn2): 0x%x\n", associate2.out.assoc_ctx);
128 torture_comment(tctx, "Send a replication table query, with assoc 1 (conn2), the anwser should be on conn1\n");
129 ZERO_STRUCT(packet);
130 packet.opcode = WREPL_OPCODE_BITS;
131 packet.assoc_ctx = associate1.out.assoc_ctx;
132 packet.mess_type = WREPL_REPLICATION;
133 packet.message.replication.command = WREPL_REPL_TABLE_QUERY;
134 ZERO_STRUCT(ctrl);
135 ctrl.send_only = true;
136 subreq = wrepl_request_send(tctx, tctx->ev, wrepl_socket2, &packet, &ctrl);
137 ok = tevent_req_poll(subreq, tctx->ev);
138 if (!ok) {
139 CHECK_STATUS(tctx, NT_STATUS_INTERNAL_ERROR, NT_STATUS_OK);
141 status = wrepl_request_recv(subreq, tctx, &rep_packet);
142 TALLOC_FREE(subreq);
143 CHECK_STATUS(tctx, status, NT_STATUS_OK);
145 torture_comment(tctx, "Send a association request (conn2), to make sure the last request was ignored\n");
146 status = wrepl_associate(wrepl_socket2, &associate2);
147 CHECK_STATUS(tctx, status, NT_STATUS_OK);
149 torture_comment(tctx, "Send a replication table query, with invalid assoc (conn1), receive answer from conn2\n");
150 ZERO_STRUCT(packet);
151 packet.opcode = WREPL_OPCODE_BITS;
152 packet.assoc_ctx = 0;
153 packet.mess_type = WREPL_REPLICATION;
154 packet.message.replication.command = WREPL_REPL_TABLE_QUERY;
155 status = wrepl_request(wrepl_socket1, tctx, &packet, &rep_packet);
156 CHECK_STATUS(tctx, status, NT_STATUS_OK);
158 torture_comment(tctx, "Send a association request (conn1), to make sure the last request was handled correct\n");
159 status = wrepl_associate(wrepl_socket1, &associate2);
160 CHECK_STATUS(tctx, status, NT_STATUS_OK);
162 assoc_stop.in.assoc_ctx = associate1.out.assoc_ctx;
163 assoc_stop.in.reason = 4;
164 torture_comment(tctx, "Send a association stop request (conn1), reson: %u\n", assoc_stop.in.reason);
165 status = wrepl_associate_stop(wrepl_socket1, &assoc_stop);
166 CHECK_STATUS(tctx, status, NT_STATUS_END_OF_FILE);
168 assoc_stop.in.assoc_ctx = associate2.out.assoc_ctx;
169 assoc_stop.in.reason = 0;
170 torture_comment(tctx, "Send a association stop request (conn2), reson: %u\n", assoc_stop.in.reason);
171 status = wrepl_associate_stop(wrepl_socket2, &assoc_stop);
172 CHECK_STATUS(tctx, status, NT_STATUS_OK);
174 torture_comment(tctx, "Close 2 wrepl connections\n");
175 talloc_free(wrepl_socket1);
176 talloc_free(wrepl_socket2);
177 return ret;
181 test if we always get back the same assoc_ctx
183 static bool test_assoc_ctx2(struct torture_context *tctx)
185 struct wrepl_socket *wrepl_socket;
186 struct wrepl_associate associate;
187 uint32_t assoc_ctx1;
188 struct nbt_name name;
189 NTSTATUS status;
190 const char *address;
192 if (!torture_nbt_get_name(tctx, &name, &address))
193 return false;
195 torture_comment(tctx, "Test if we always get back the same assoc_ctx\n");
197 wrepl_socket = wrepl_socket_init(tctx, tctx->ev);
199 torture_comment(tctx, "Setup wrepl connections\n");
200 status = wrepl_connect(wrepl_socket, wrepl_best_ip(tctx->lp_ctx, address), address);
201 CHECK_STATUS(tctx, status, NT_STATUS_OK);
203 torture_comment(tctx, "Send 1st start association request\n");
204 status = wrepl_associate(wrepl_socket, &associate);
205 CHECK_STATUS(tctx, status, NT_STATUS_OK);
206 assoc_ctx1 = associate.out.assoc_ctx;
207 torture_comment(tctx, "1st association context: 0x%x\n", associate.out.assoc_ctx);
209 torture_comment(tctx, "Send 2nd start association request\n");
210 status = wrepl_associate(wrepl_socket, &associate);
211 torture_assert_ntstatus_ok(tctx, status, "2nd start association failed");
212 torture_assert(tctx, associate.out.assoc_ctx == assoc_ctx1,
213 "Different context returned");
214 torture_comment(tctx, "2nd association context: 0x%x\n", associate.out.assoc_ctx);
216 torture_comment(tctx, "Send 3rd start association request\n");
217 status = wrepl_associate(wrepl_socket, &associate);
218 torture_assert(tctx, associate.out.assoc_ctx == assoc_ctx1,
219 "Different context returned");
220 CHECK_STATUS(tctx, status, NT_STATUS_OK);
221 torture_comment(tctx, "3rd association context: 0x%x\n", associate.out.assoc_ctx);
223 torture_comment(tctx, "Close wrepl connections\n");
224 talloc_free(wrepl_socket);
225 return true;
230 display a replication entry
232 static void display_entry(struct torture_context *tctx, struct wrepl_name *name)
234 int i;
236 torture_comment(tctx, "%s\n", nbt_name_string(tctx, &name->name));
237 torture_comment(tctx, "\tTYPE:%u STATE:%u NODE:%u STATIC:%u VERSION_ID: %llu\n",
238 name->type, name->state, name->node, name->is_static, (long long)name->version_id);
239 torture_comment(tctx, "\tRAW_FLAGS: 0x%08X OWNER: %-15s\n",
240 name->raw_flags, name->owner);
241 for (i=0;i<name->num_addresses;i++) {
242 torture_comment(tctx, "\tADDR: %-15s OWNER: %-15s\n",
243 name->addresses[i].address, name->addresses[i].owner);
248 test a full replication dump from a WINS server
250 static bool test_wins_replication(struct torture_context *tctx)
252 struct wrepl_socket *wrepl_socket;
253 NTSTATUS status;
254 int i, j;
255 struct wrepl_associate associate;
256 struct wrepl_pull_table pull_table;
257 struct wrepl_pull_names pull_names;
258 struct nbt_name name;
259 const char *address;
261 if (!torture_nbt_get_name(tctx, &name, &address))
262 return false;
264 torture_comment(tctx, "Test one pull replication cycle\n");
266 wrepl_socket = wrepl_socket_init(tctx, tctx->ev);
268 torture_comment(tctx, "Setup wrepl connections\n");
269 status = wrepl_connect(wrepl_socket, wrepl_best_ip(tctx->lp_ctx, address), address);
270 CHECK_STATUS(tctx, status, NT_STATUS_OK);
272 torture_comment(tctx, "Send a start association request\n");
274 status = wrepl_associate(wrepl_socket, &associate);
275 CHECK_STATUS(tctx, status, NT_STATUS_OK);
277 torture_comment(tctx, "association context: 0x%x\n", associate.out.assoc_ctx);
279 torture_comment(tctx, "Send a replication table query\n");
280 pull_table.in.assoc_ctx = associate.out.assoc_ctx;
282 status = wrepl_pull_table(wrepl_socket, tctx, &pull_table);
283 if (NT_STATUS_EQUAL(NT_STATUS_NETWORK_ACCESS_DENIED,status)) {
284 struct wrepl_associate_stop assoc_stop;
286 assoc_stop.in.assoc_ctx = associate.out.assoc_ctx;
287 assoc_stop.in.reason = 0;
289 wrepl_associate_stop(wrepl_socket, &assoc_stop);
291 torture_fail(tctx, "We are not a valid pull partner for the server");
293 CHECK_STATUS(tctx, status, NT_STATUS_OK);
295 torture_comment(tctx, "Found %d replication partners\n", pull_table.out.num_partners);
297 for (i=0;i<pull_table.out.num_partners;i++) {
298 struct wrepl_wins_owner *partner = &pull_table.out.partners[i];
299 torture_comment(tctx, "%s max_version=%6llu min_version=%6llu type=%d\n",
300 partner->address,
301 (long long)partner->max_version,
302 (long long)partner->min_version,
303 partner->type);
305 pull_names.in.assoc_ctx = associate.out.assoc_ctx;
306 pull_names.in.partner = *partner;
308 status = wrepl_pull_names(wrepl_socket, tctx, &pull_names);
309 CHECK_STATUS(tctx, status, NT_STATUS_OK);
311 torture_comment(tctx, "Received %d names\n", pull_names.out.num_names);
313 for (j=0;j<pull_names.out.num_names;j++) {
314 display_entry(tctx, &pull_names.out.names[j]);
318 torture_comment(tctx, "Close wrepl connections\n");
319 talloc_free(wrepl_socket);
320 return true;
323 struct test_wrepl_conflict_conn {
324 const char *address;
325 struct wrepl_socket *pull;
326 uint32_t pull_assoc;
328 #define TEST_OWNER_A_ADDRESS "127.65.65.1"
329 #define TEST_ADDRESS_A_PREFIX "127.0.65"
330 #define TEST_OWNER_B_ADDRESS "127.66.66.1"
331 #define TEST_ADDRESS_B_PREFIX "127.0.66"
332 #define TEST_OWNER_X_ADDRESS "127.88.88.1"
333 #define TEST_ADDRESS_X_PREFIX "127.0.88"
335 struct wrepl_wins_owner a, b, c, x;
337 struct socket_address *myaddr;
338 struct socket_address *myaddr2;
339 struct nbt_name_socket *nbtsock;
340 struct nbt_name_socket *nbtsock2;
342 struct nbt_name_socket *nbtsock_srv;
343 struct nbt_name_socket *nbtsock_srv2;
345 uint32_t addresses_best_num;
346 struct wrepl_ip *addresses_best;
348 uint32_t addresses_best2_num;
349 struct wrepl_ip *addresses_best2;
351 uint32_t addresses_all_num;
352 struct wrepl_ip *addresses_all;
354 uint32_t addresses_mhomed_num;
355 struct wrepl_ip *addresses_mhomed;
358 static const struct wrepl_ip addresses_A_1[] = {
360 .owner = TEST_OWNER_A_ADDRESS,
361 .ip = TEST_ADDRESS_A_PREFIX".1"
364 static const struct wrepl_ip addresses_A_2[] = {
366 .owner = TEST_OWNER_A_ADDRESS,
367 .ip = TEST_ADDRESS_A_PREFIX".2"
370 static const struct wrepl_ip addresses_A_3_4[] = {
372 .owner = TEST_OWNER_A_ADDRESS,
373 .ip = TEST_ADDRESS_A_PREFIX".3"
376 .owner = TEST_OWNER_A_ADDRESS,
377 .ip = TEST_ADDRESS_A_PREFIX".4"
380 static const struct wrepl_ip addresses_A_3_4_X_3_4[] = {
382 .owner = TEST_OWNER_A_ADDRESS,
383 .ip = TEST_ADDRESS_A_PREFIX".3"
386 .owner = TEST_OWNER_A_ADDRESS,
387 .ip = TEST_ADDRESS_A_PREFIX".4"
390 .owner = TEST_OWNER_X_ADDRESS,
391 .ip = TEST_ADDRESS_X_PREFIX".3"
394 .owner = TEST_OWNER_X_ADDRESS,
395 .ip = TEST_ADDRESS_X_PREFIX".4"
398 static const struct wrepl_ip addresses_A_3_4_B_3_4[] = {
400 .owner = TEST_OWNER_A_ADDRESS,
401 .ip = TEST_ADDRESS_A_PREFIX".3"
404 .owner = TEST_OWNER_A_ADDRESS,
405 .ip = TEST_ADDRESS_A_PREFIX".4"
408 .owner = TEST_OWNER_B_ADDRESS,
409 .ip = TEST_ADDRESS_B_PREFIX".3"
412 .owner = TEST_OWNER_B_ADDRESS,
413 .ip = TEST_ADDRESS_B_PREFIX".4"
416 static const struct wrepl_ip addresses_A_3_4_OWNER_B[] = {
418 .owner = TEST_OWNER_B_ADDRESS,
419 .ip = TEST_ADDRESS_A_PREFIX".3"
422 .owner = TEST_OWNER_B_ADDRESS,
423 .ip = TEST_ADDRESS_A_PREFIX".4"
426 static const struct wrepl_ip addresses_A_3_4_X_3_4_OWNER_B[] = {
428 .owner = TEST_OWNER_B_ADDRESS,
429 .ip = TEST_ADDRESS_A_PREFIX".3"
432 .owner = TEST_OWNER_B_ADDRESS,
433 .ip = TEST_ADDRESS_A_PREFIX".4"
436 .owner = TEST_OWNER_B_ADDRESS,
437 .ip = TEST_ADDRESS_X_PREFIX".3"
440 .owner = TEST_OWNER_B_ADDRESS,
441 .ip = TEST_ADDRESS_X_PREFIX".4"
445 static const struct wrepl_ip addresses_A_3_4_X_1_2[] = {
447 .owner = TEST_OWNER_A_ADDRESS,
448 .ip = TEST_ADDRESS_A_PREFIX".3"
451 .owner = TEST_OWNER_A_ADDRESS,
452 .ip = TEST_ADDRESS_A_PREFIX".4"
455 .owner = TEST_OWNER_X_ADDRESS,
456 .ip = TEST_ADDRESS_X_PREFIX".1"
459 .owner = TEST_OWNER_X_ADDRESS,
460 .ip = TEST_ADDRESS_X_PREFIX".2"
464 static const struct wrepl_ip addresses_B_1[] = {
466 .owner = TEST_OWNER_B_ADDRESS,
467 .ip = TEST_ADDRESS_B_PREFIX".1"
470 static const struct wrepl_ip addresses_B_2[] = {
472 .owner = TEST_OWNER_B_ADDRESS,
473 .ip = TEST_ADDRESS_B_PREFIX".2"
476 static const struct wrepl_ip addresses_B_3_4[] = {
478 .owner = TEST_OWNER_B_ADDRESS,
479 .ip = TEST_ADDRESS_B_PREFIX".3"
482 .owner = TEST_OWNER_B_ADDRESS,
483 .ip = TEST_ADDRESS_B_PREFIX".4"
486 static const struct wrepl_ip addresses_B_3_4_X_3_4[] = {
488 .owner = TEST_OWNER_B_ADDRESS,
489 .ip = TEST_ADDRESS_B_PREFIX".3"
492 .owner = TEST_OWNER_B_ADDRESS,
493 .ip = TEST_ADDRESS_B_PREFIX".4"
496 .owner = TEST_OWNER_X_ADDRESS,
497 .ip = TEST_ADDRESS_X_PREFIX".3"
500 .owner = TEST_OWNER_X_ADDRESS,
501 .ip = TEST_ADDRESS_X_PREFIX".4"
504 static const struct wrepl_ip addresses_B_3_4_X_1_2[] = {
506 .owner = TEST_OWNER_B_ADDRESS,
507 .ip = TEST_ADDRESS_B_PREFIX".3"
510 .owner = TEST_OWNER_B_ADDRESS,
511 .ip = TEST_ADDRESS_B_PREFIX".4"
514 .owner = TEST_OWNER_X_ADDRESS,
515 .ip = TEST_ADDRESS_X_PREFIX".1"
518 .owner = TEST_OWNER_X_ADDRESS,
519 .ip = TEST_ADDRESS_X_PREFIX".2"
523 static const struct wrepl_ip addresses_X_1_2[] = {
525 .owner = TEST_OWNER_X_ADDRESS,
526 .ip = TEST_ADDRESS_X_PREFIX".1"
529 .owner = TEST_OWNER_X_ADDRESS,
530 .ip = TEST_ADDRESS_X_PREFIX".2"
533 static const struct wrepl_ip addresses_X_3_4[] = {
535 .owner = TEST_OWNER_X_ADDRESS,
536 .ip = TEST_ADDRESS_X_PREFIX".3"
539 .owner = TEST_OWNER_X_ADDRESS,
540 .ip = TEST_ADDRESS_X_PREFIX".4"
544 static struct test_wrepl_conflict_conn *test_create_conflict_ctx(
545 struct torture_context *tctx, const char *address)
547 struct test_wrepl_conflict_conn *ctx;
548 struct wrepl_associate associate;
549 struct wrepl_pull_table pull_table;
550 struct socket_address *nbt_srv_addr;
551 NTSTATUS status;
552 uint32_t i;
553 struct interface *ifaces;
555 ctx = talloc_zero(tctx, struct test_wrepl_conflict_conn);
556 if (!ctx) return NULL;
558 ctx->address = address;
559 ctx->pull = wrepl_socket_init(ctx, tctx->ev);
560 if (!ctx->pull) return NULL;
562 torture_comment(tctx, "Setup wrepl conflict pull connection\n");
563 status = wrepl_connect(ctx->pull, wrepl_best_ip(tctx->lp_ctx, ctx->address), ctx->address);
564 if (!NT_STATUS_IS_OK(status)) return NULL;
566 status = wrepl_associate(ctx->pull, &associate);
567 if (!NT_STATUS_IS_OK(status)) return NULL;
569 ctx->pull_assoc = associate.out.assoc_ctx;
571 ctx->a.address = TEST_OWNER_A_ADDRESS;
572 ctx->a.max_version = 0;
573 ctx->a.min_version = 0;
574 ctx->a.type = 1;
576 ctx->b.address = TEST_OWNER_B_ADDRESS;
577 ctx->b.max_version = 0;
578 ctx->b.min_version = 0;
579 ctx->b.type = 1;
581 ctx->x.address = TEST_OWNER_X_ADDRESS;
582 ctx->x.max_version = 0;
583 ctx->x.min_version = 0;
584 ctx->x.type = 1;
586 ctx->c.address = address;
587 ctx->c.max_version = 0;
588 ctx->c.min_version = 0;
589 ctx->c.type = 1;
591 pull_table.in.assoc_ctx = ctx->pull_assoc;
592 status = wrepl_pull_table(ctx->pull, ctx->pull, &pull_table);
593 if (!NT_STATUS_IS_OK(status)) return NULL;
595 for (i=0; i < pull_table.out.num_partners; i++) {
596 if (strcmp(TEST_OWNER_A_ADDRESS,pull_table.out.partners[i].address)==0) {
597 ctx->a.max_version = pull_table.out.partners[i].max_version;
598 ctx->a.min_version = pull_table.out.partners[i].min_version;
600 if (strcmp(TEST_OWNER_B_ADDRESS,pull_table.out.partners[i].address)==0) {
601 ctx->b.max_version = pull_table.out.partners[i].max_version;
602 ctx->b.min_version = pull_table.out.partners[i].min_version;
604 if (strcmp(TEST_OWNER_X_ADDRESS,pull_table.out.partners[i].address)==0) {
605 ctx->x.max_version = pull_table.out.partners[i].max_version;
606 ctx->x.min_version = pull_table.out.partners[i].min_version;
608 if (strcmp(address,pull_table.out.partners[i].address)==0) {
609 ctx->c.max_version = pull_table.out.partners[i].max_version;
610 ctx->c.min_version = pull_table.out.partners[i].min_version;
614 talloc_free(pull_table.out.partners);
616 ctx->nbtsock = nbt_name_socket_init(ctx, tctx->ev);
617 if (!ctx->nbtsock) return NULL;
619 load_interface_list(tctx, tctx->lp_ctx, &ifaces);
621 ctx->myaddr = socket_address_from_strings(tctx, ctx->nbtsock->sock->backend_name, iface_list_best_ip(ifaces, address), 0);
622 if (!ctx->myaddr) return NULL;
624 for (i = 0; i < iface_list_count(ifaces); i++) {
625 if (strcmp(ctx->myaddr->addr, iface_list_n_ip(ifaces, i)) == 0) continue;
626 ctx->myaddr2 = socket_address_from_strings(tctx, ctx->nbtsock->sock->backend_name, iface_list_n_ip(ifaces, i), 0);
627 if (!ctx->myaddr2) return NULL;
628 break;
631 status = socket_listen(ctx->nbtsock->sock, ctx->myaddr, 0, 0);
632 if (!NT_STATUS_IS_OK(status)) return NULL;
634 ctx->nbtsock_srv = nbt_name_socket_init(ctx, tctx->ev);
635 if (!ctx->nbtsock_srv) return NULL;
637 /* Make a port 137 version of ctx->myaddr */
638 nbt_srv_addr = socket_address_from_strings(tctx, ctx->nbtsock_srv->sock->backend_name, ctx->myaddr->addr, lpcfg_nbt_port(tctx->lp_ctx));
639 if (!nbt_srv_addr) return NULL;
641 /* And if possible, bind to it. This won't work unless we are root or in sockewrapper */
642 status = socket_listen(ctx->nbtsock_srv->sock, nbt_srv_addr, 0, 0);
643 talloc_free(nbt_srv_addr);
644 if (!NT_STATUS_IS_OK(status)) {
645 /* this isn't fatal */
646 talloc_free(ctx->nbtsock_srv);
647 ctx->nbtsock_srv = NULL;
650 if (ctx->myaddr2 && ctx->nbtsock_srv) {
651 ctx->nbtsock2 = nbt_name_socket_init(ctx, tctx->ev);
652 if (!ctx->nbtsock2) return NULL;
654 status = socket_listen(ctx->nbtsock2->sock, ctx->myaddr2, 0, 0);
655 if (!NT_STATUS_IS_OK(status)) return NULL;
657 ctx->nbtsock_srv2 = nbt_name_socket_init(ctx, ctx->nbtsock_srv->event_ctx);
658 if (!ctx->nbtsock_srv2) return NULL;
660 /* Make a port 137 version of ctx->myaddr2 */
661 nbt_srv_addr = socket_address_from_strings(tctx,
662 ctx->nbtsock_srv->sock->backend_name,
663 ctx->myaddr2->addr,
664 lpcfg_nbt_port(tctx->lp_ctx));
665 if (!nbt_srv_addr) return NULL;
667 /* And if possible, bind to it. This won't work unless we are root or in sockewrapper */
668 status = socket_listen(ctx->nbtsock_srv2->sock, ctx->myaddr2, 0, 0);
669 talloc_free(nbt_srv_addr);
670 if (!NT_STATUS_IS_OK(status)) {
671 /* this isn't fatal */
672 talloc_free(ctx->nbtsock_srv2);
673 ctx->nbtsock_srv2 = NULL;
677 ctx->addresses_best_num = 1;
678 ctx->addresses_best = talloc_array(ctx, struct wrepl_ip, ctx->addresses_best_num);
679 if (!ctx->addresses_best) return NULL;
680 ctx->addresses_best[0].owner = ctx->b.address;
681 ctx->addresses_best[0].ip = ctx->myaddr->addr;
683 ctx->addresses_all_num = iface_list_count(ifaces);
684 ctx->addresses_all = talloc_array(ctx, struct wrepl_ip, ctx->addresses_all_num);
685 if (!ctx->addresses_all) return NULL;
686 for (i=0; i < ctx->addresses_all_num; i++) {
687 ctx->addresses_all[i].owner = ctx->b.address;
688 ctx->addresses_all[i].ip = talloc_strdup(ctx->addresses_all, iface_list_n_ip(ifaces, i));
689 if (!ctx->addresses_all[i].ip) return NULL;
692 if (ctx->nbtsock_srv2) {
693 ctx->addresses_best2_num = 1;
694 ctx->addresses_best2 = talloc_array(ctx, struct wrepl_ip, ctx->addresses_best2_num);
695 if (!ctx->addresses_best2) return NULL;
696 ctx->addresses_best2[0].owner = ctx->b.address;
697 ctx->addresses_best2[0].ip = ctx->myaddr2->addr;
699 ctx->addresses_mhomed_num = 2;
700 ctx->addresses_mhomed = talloc_array(ctx, struct wrepl_ip, ctx->addresses_mhomed_num);
701 if (!ctx->addresses_mhomed) return NULL;
702 ctx->addresses_mhomed[0].owner = ctx->b.address;
703 ctx->addresses_mhomed[0].ip = ctx->myaddr->addr;
704 ctx->addresses_mhomed[1].owner = ctx->b.address;
705 ctx->addresses_mhomed[1].ip = ctx->myaddr2->addr;
708 return ctx;
711 static bool test_wrepl_update_one(struct torture_context *tctx,
712 struct test_wrepl_conflict_conn *ctx,
713 const struct wrepl_wins_owner *owner,
714 const struct wrepl_wins_name *name)
716 struct wrepl_socket *wrepl_socket;
717 struct wrepl_associate associate;
718 struct wrepl_packet update_packet, repl_send;
719 struct wrepl_table *update;
720 struct wrepl_wins_owner wrepl_wins_owners[1];
721 struct wrepl_packet *repl_recv;
722 struct wrepl_wins_owner *send_request;
723 struct wrepl_send_reply *send_reply;
724 struct wrepl_wins_name wrepl_wins_names[1];
725 uint32_t assoc_ctx;
726 NTSTATUS status;
728 wrepl_socket = wrepl_socket_init(ctx, tctx->ev);
730 status = wrepl_connect(wrepl_socket, wrepl_best_ip(tctx->lp_ctx, ctx->address), ctx->address);
731 CHECK_STATUS(tctx, status, NT_STATUS_OK);
733 status = wrepl_associate(wrepl_socket, &associate);
734 CHECK_STATUS(tctx, status, NT_STATUS_OK);
735 assoc_ctx = associate.out.assoc_ctx;
737 /* now send a WREPL_REPL_UPDATE message */
738 ZERO_STRUCT(update_packet);
739 update_packet.opcode = WREPL_OPCODE_BITS;
740 update_packet.assoc_ctx = assoc_ctx;
741 update_packet.mess_type = WREPL_REPLICATION;
742 update_packet.message.replication.command = WREPL_REPL_UPDATE;
743 update = &update_packet.message.replication.info.table;
745 update->partner_count = ARRAY_SIZE(wrepl_wins_owners);
746 update->partners = wrepl_wins_owners;
747 update->initiator = "0.0.0.0";
749 wrepl_wins_owners[0] = *owner;
751 status = wrepl_request(wrepl_socket, wrepl_socket,
752 &update_packet, &repl_recv);
753 CHECK_STATUS(tctx, status, NT_STATUS_OK);
754 CHECK_VALUE(tctx, repl_recv->mess_type, WREPL_REPLICATION);
755 CHECK_VALUE(tctx, repl_recv->message.replication.command, WREPL_REPL_SEND_REQUEST);
756 send_request = &repl_recv->message.replication.info.owner;
758 ZERO_STRUCT(repl_send);
759 repl_send.opcode = WREPL_OPCODE_BITS;
760 repl_send.assoc_ctx = assoc_ctx;
761 repl_send.mess_type = WREPL_REPLICATION;
762 repl_send.message.replication.command = WREPL_REPL_SEND_REPLY;
763 send_reply = &repl_send.message.replication.info.reply;
765 send_reply->num_names = ARRAY_SIZE(wrepl_wins_names);
766 send_reply->names = wrepl_wins_names;
768 wrepl_wins_names[0] = *name;
770 status = wrepl_request(wrepl_socket, wrepl_socket,
771 &repl_send, &repl_recv);
772 CHECK_STATUS(tctx, status, NT_STATUS_OK);
773 CHECK_VALUE(tctx, repl_recv->mess_type, WREPL_STOP_ASSOCIATION);
774 CHECK_VALUE(tctx, repl_recv->message.stop.reason, 0);
776 talloc_free(wrepl_socket);
777 return true;
780 static bool test_wrepl_is_applied(struct torture_context *tctx,
781 struct test_wrepl_conflict_conn *ctx,
782 const struct wrepl_wins_owner *owner,
783 const struct wrepl_wins_name *name,
784 bool expected)
786 NTSTATUS status;
787 struct wrepl_pull_names pull_names;
788 struct wrepl_name *names;
790 pull_names.in.assoc_ctx = ctx->pull_assoc;
791 pull_names.in.partner = *owner;
792 pull_names.in.partner.min_version = pull_names.in.partner.max_version;
794 status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
795 CHECK_STATUS(tctx, status, NT_STATUS_OK);
796 torture_assert(tctx, pull_names.out.num_names == (expected?1:0),
797 talloc_asprintf(tctx, "Invalid number of records returned - expected %d got %d", expected, pull_names.out.num_names));
799 names = pull_names.out.names;
801 if (expected) {
802 uint32_t flags = WREPL_NAME_FLAGS(names[0].type,
803 names[0].state,
804 names[0].node,
805 names[0].is_static);
806 char *expected_scope = NULL;
807 CHECK_VALUE(tctx, names[0].name.type, name->name->type);
808 CHECK_VALUE_STRING(tctx, names[0].name.name, name->name->name);
810 if (names[0].name.scope) {
811 expected_scope = talloc_strndup(tctx,
812 name->name->scope,
813 237);
815 CHECK_VALUE_STRING(tctx, names[0].name.scope, expected_scope);
816 CHECK_VALUE(tctx, flags, name->flags);
817 CHECK_VALUE_UINT64(tctx, names[0].version_id, name->id);
819 if (flags & 2) {
820 CHECK_VALUE(tctx, names[0].num_addresses,
821 name->addresses.addresses.num_ips);
822 } else {
823 CHECK_VALUE(tctx, names[0].num_addresses, 1);
824 CHECK_VALUE_STRING(tctx, names[0].addresses[0].address,
825 name->addresses.ip);
828 talloc_free(pull_names.out.names);
829 return true;
832 static bool test_wrepl_mhomed_merged(struct torture_context *tctx,
833 struct test_wrepl_conflict_conn *ctx,
834 const struct wrepl_wins_owner *owner1,
835 uint32_t num_ips1, const struct wrepl_ip *ips1,
836 const struct wrepl_wins_owner *owner2,
837 uint32_t num_ips2, const struct wrepl_ip *ips2,
838 const struct wrepl_wins_name *name2)
840 NTSTATUS status;
841 struct wrepl_pull_names pull_names;
842 struct wrepl_name *names;
843 uint32_t flags;
844 uint32_t i, j;
845 uint32_t num_ips = num_ips1 + num_ips2;
847 for (i = 0; i < num_ips2; i++) {
848 for (j = 0; j < num_ips1; j++) {
849 if (strcmp(ips2[i].ip,ips1[j].ip) == 0) {
850 num_ips--;
851 break;
856 pull_names.in.assoc_ctx = ctx->pull_assoc;
857 pull_names.in.partner = *owner2;
858 pull_names.in.partner.min_version = pull_names.in.partner.max_version;
860 status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
861 CHECK_STATUS(tctx, status, NT_STATUS_OK);
862 CHECK_VALUE(tctx, pull_names.out.num_names, 1);
864 names = pull_names.out.names;
866 flags = WREPL_NAME_FLAGS(names[0].type,
867 names[0].state,
868 names[0].node,
869 names[0].is_static);
870 CHECK_VALUE(tctx, names[0].name.type, name2->name->type);
871 CHECK_VALUE_STRING(tctx, names[0].name.name, name2->name->name);
872 CHECK_VALUE_STRING(tctx, names[0].name.scope, name2->name->scope);
873 CHECK_VALUE(tctx, flags, name2->flags | WREPL_TYPE_MHOMED);
874 CHECK_VALUE_UINT64(tctx, names[0].version_id, name2->id);
876 CHECK_VALUE(tctx, names[0].num_addresses, num_ips);
878 for (i = 0; i < names[0].num_addresses; i++) {
879 const char *addr = names[0].addresses[i].address;
880 const char *owner = names[0].addresses[i].owner;
881 bool found = false;
883 for (j = 0; j < num_ips2; j++) {
884 if (strcmp(addr, ips2[j].ip) == 0) {
885 found = true;
886 CHECK_VALUE_STRING(tctx, owner, owner2->address);
887 break;
891 if (found) continue;
893 for (j = 0; j < num_ips1; j++) {
894 if (strcmp(addr, ips1[j].ip) == 0) {
895 found = true;
896 CHECK_VALUE_STRING(tctx, owner, owner1->address);
897 break;
901 if (found) continue;
903 CHECK_VALUE_STRING(tctx, addr, "not found in address list");
905 talloc_free(pull_names.out.names);
906 return true;
909 static bool test_wrepl_sgroup_merged(struct torture_context *tctx,
910 struct test_wrepl_conflict_conn *ctx,
911 struct wrepl_wins_owner *merge_owner,
912 struct wrepl_wins_owner *owner1,
913 uint32_t num_ips1, const struct wrepl_ip *ips1,
914 struct wrepl_wins_owner *owner2,
915 uint32_t num_ips2, const struct wrepl_ip *ips2,
916 const struct wrepl_wins_name *name2)
918 NTSTATUS status;
919 struct wrepl_pull_names pull_names;
920 struct wrepl_name *names;
921 struct wrepl_name *name = NULL;
922 uint32_t flags;
923 uint32_t i, j;
924 uint32_t num_ips = num_ips1 + num_ips2;
926 if (!merge_owner) {
927 merge_owner = &ctx->c;
930 for (i = 0; i < num_ips1; i++) {
931 if (owner1 != &ctx->c && strcmp(ips1[i].owner,owner2->address) == 0) {
932 num_ips--;
933 continue;
935 for (j = 0; j < num_ips2; j++) {
936 if (strcmp(ips1[i].ip,ips2[j].ip) == 0) {
937 num_ips--;
938 break;
944 pull_names.in.assoc_ctx = ctx->pull_assoc;
945 pull_names.in.partner = *merge_owner;
946 pull_names.in.partner.min_version = pull_names.in.partner.max_version;
947 pull_names.in.partner.max_version = 0;
949 status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
950 CHECK_STATUS(tctx, status, NT_STATUS_OK);
952 names = pull_names.out.names;
954 for (i = 0; i < pull_names.out.num_names; i++) {
955 if (names[i].name.type != name2->name->type) continue;
956 if (!names[i].name.name) continue;
957 if (strcmp(names[i].name.name, name2->name->name) != 0) continue;
958 if (names[i].name.scope) continue;
960 name = &names[i];
963 if (pull_names.out.num_names > 0) {
964 merge_owner->max_version = names[pull_names.out.num_names-1].version_id;
967 if (!name) {
968 torture_comment(tctx, "%s: Name '%s' not found\n", __location__, nbt_name_string(ctx, name2->name));
969 return false;
972 flags = WREPL_NAME_FLAGS(name->type,
973 name->state,
974 name->node,
975 name->is_static);
976 CHECK_VALUE(tctx, name->name.type, name2->name->type);
977 CHECK_VALUE_STRING(tctx, name->name.name, name2->name->name);
978 CHECK_VALUE_STRING(tctx, name->name.scope, name2->name->scope);
979 CHECK_VALUE(tctx, flags, name2->flags);
981 CHECK_VALUE(tctx, name->num_addresses, num_ips);
983 for (i = 0; i < name->num_addresses; i++) {
984 const char *addr = name->addresses[i].address;
985 const char *owner = name->addresses[i].owner;
986 bool found = false;
988 for (j = 0; j < num_ips2; j++) {
989 if (strcmp(addr, ips2[j].ip) == 0) {
990 found = true;
991 CHECK_VALUE_STRING(tctx, owner, ips2[j].owner);
992 break;
996 if (found) continue;
998 for (j = 0; j < num_ips1; j++) {
999 if (strcmp(addr, ips1[j].ip) == 0) {
1000 found = true;
1001 if (owner1 == &ctx->c) {
1002 CHECK_VALUE_STRING(tctx, owner, owner1->address);
1003 } else {
1004 CHECK_VALUE_STRING(tctx, owner, ips1[j].owner);
1006 break;
1010 if (found) continue;
1012 CHECK_VALUE_STRING(tctx, addr, "not found in address list");
1014 talloc_free(pull_names.out.names);
1015 return true;
1018 static char *test_nbt_winsrepl_scope_string(TALLOC_CTX *mem_ctx, uint8_t count)
1020 char *res;
1021 uint8_t i;
1023 res = talloc_array(mem_ctx, char, count+1);
1024 if (res == NULL) {
1025 return NULL;
1028 for (i=0; i < count; i++) {
1029 res[i] = '0' + (i%10);
1032 res[count] = '\0';
1034 talloc_set_name_const(res, res);
1036 return res;
1039 static bool test_conflict_same_owner(struct torture_context *tctx,
1040 struct test_wrepl_conflict_conn *ctx)
1042 bool ret = true;
1043 struct wrepl_wins_name wins_name1;
1044 struct wrepl_wins_name wins_name2;
1045 struct wrepl_wins_name *wins_name_tmp;
1046 struct wrepl_wins_name *wins_name_last;
1047 struct wrepl_wins_name *wins_name_cur;
1048 uint32_t i,j;
1049 struct nbt_name names[] = {
1050 _NBT_NAME("_SAME_OWNER_A", 0x00, NULL),
1051 _NBT_NAME("_SAME_OWNER_A", 0x00,
1052 test_nbt_winsrepl_scope_string(tctx, 1)),
1053 _NBT_NAME("_SAME_OWNER_A", 0x00,
1054 test_nbt_winsrepl_scope_string(tctx, 2)),
1055 _NBT_NAME("_SAME_OWNER_A", 0x00,
1056 test_nbt_winsrepl_scope_string(tctx, 3)),
1057 _NBT_NAME("_SAME_OWNER_A", 0x00,
1058 test_nbt_winsrepl_scope_string(tctx, 4)),
1059 _NBT_NAME("_SAME_OWNER_A", 0x00,
1060 test_nbt_winsrepl_scope_string(tctx, 5)),
1061 _NBT_NAME("_SAME_OWNER_A", 0x00,
1062 test_nbt_winsrepl_scope_string(tctx, 6)),
1063 _NBT_NAME("_SAME_OWNER_A", 0x00,
1064 test_nbt_winsrepl_scope_string(tctx, 7)),
1065 _NBT_NAME("_SAME_OWNER_A", 0x00,
1066 test_nbt_winsrepl_scope_string(tctx, 8)),
1067 _NBT_NAME("_SAME_OWNER_A", 0x00,
1068 test_nbt_winsrepl_scope_string(tctx, 9)),
1069 _NBT_NAME("_SAME_OWNER_A", 0x00,
1070 test_nbt_winsrepl_scope_string(tctx, 237)),
1071 _NBT_NAME("_SAME_OWNER_A", 0x00,
1072 test_nbt_winsrepl_scope_string(tctx, 238)),
1073 _NBT_NAME("_SAME_OWNER_A", 0x1C, NULL),
1075 struct {
1076 enum wrepl_name_type type;
1077 enum wrepl_name_state state;
1078 enum wrepl_name_node node;
1079 bool is_static;
1080 uint32_t num_ips;
1081 const struct wrepl_ip *ips;
1082 } records[] = {
1084 .type = WREPL_TYPE_GROUP,
1085 .state = WREPL_STATE_ACTIVE,
1086 .node = WREPL_NODE_B,
1087 .is_static = false,
1088 .num_ips = ARRAY_SIZE(addresses_A_1),
1089 .ips = addresses_A_1,
1091 .type = WREPL_TYPE_UNIQUE,
1092 .state = WREPL_STATE_ACTIVE,
1093 .node = WREPL_NODE_B,
1094 .is_static = false,
1095 .num_ips = ARRAY_SIZE(addresses_A_1),
1096 .ips = addresses_A_1,
1098 .type = WREPL_TYPE_UNIQUE,
1099 .state = WREPL_STATE_ACTIVE,
1100 .node = WREPL_NODE_B,
1101 .is_static = false,
1102 .num_ips = ARRAY_SIZE(addresses_A_2),
1103 .ips = addresses_A_2,
1105 .type = WREPL_TYPE_UNIQUE,
1106 .state = WREPL_STATE_ACTIVE,
1107 .node = WREPL_NODE_B,
1108 .is_static = true,
1109 .num_ips = ARRAY_SIZE(addresses_A_1),
1110 .ips = addresses_A_1,
1112 .type = WREPL_TYPE_UNIQUE,
1113 .state = WREPL_STATE_ACTIVE,
1114 .node = WREPL_NODE_B,
1115 .is_static = false,
1116 .num_ips = ARRAY_SIZE(addresses_A_2),
1117 .ips = addresses_A_2,
1119 .type = WREPL_TYPE_SGROUP,
1120 .state = WREPL_STATE_TOMBSTONE,
1121 .node = WREPL_NODE_B,
1122 .is_static = false,
1123 .num_ips = ARRAY_SIZE(addresses_A_2),
1124 .ips = addresses_A_2,
1126 .type = WREPL_TYPE_MHOMED,
1127 .state = WREPL_STATE_TOMBSTONE,
1128 .node = WREPL_NODE_B,
1129 .is_static = false,
1130 .num_ips = ARRAY_SIZE(addresses_A_1),
1131 .ips = addresses_A_1,
1133 .type = WREPL_TYPE_MHOMED,
1134 .state = WREPL_STATE_RELEASED,
1135 .node = WREPL_NODE_B,
1136 .is_static = false,
1137 .num_ips = ARRAY_SIZE(addresses_A_2),
1138 .ips = addresses_A_2,
1140 .type = WREPL_TYPE_SGROUP,
1141 .state = WREPL_STATE_ACTIVE,
1142 .node = WREPL_NODE_B,
1143 .is_static = false,
1144 .num_ips = ARRAY_SIZE(addresses_A_1),
1145 .ips = addresses_A_1,
1147 .type = WREPL_TYPE_SGROUP,
1148 .state = WREPL_STATE_ACTIVE,
1149 .node = WREPL_NODE_B,
1150 .is_static = false,
1151 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1152 .ips = addresses_A_3_4,
1154 .type = WREPL_TYPE_SGROUP,
1155 .state = WREPL_STATE_TOMBSTONE,
1156 .node = WREPL_NODE_B,
1157 .is_static = false,
1158 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1159 .ips = addresses_B_3_4,
1161 /* the last one should always be a unique,tomstone record! */
1162 .type = WREPL_TYPE_UNIQUE,
1163 .state = WREPL_STATE_TOMBSTONE,
1164 .node = WREPL_NODE_B,
1165 .is_static = false,
1166 .num_ips = ARRAY_SIZE(addresses_A_1),
1167 .ips = addresses_A_1,
1171 wins_name_tmp = NULL;
1172 wins_name_last = &wins_name2;
1173 wins_name_cur = &wins_name1;
1175 for (j=0; ret && j < ARRAY_SIZE(names); j++) {
1176 torture_comment(tctx, "Test Replica Conflicts with same owner[%s] for %s\n",
1177 nbt_name_string(ctx, &names[j]), ctx->a.address);
1179 for(i=0; ret && i < ARRAY_SIZE(records); i++) {
1180 wins_name_tmp = wins_name_last;
1181 wins_name_last = wins_name_cur;
1182 wins_name_cur = wins_name_tmp;
1184 if (i > 0) {
1185 torture_comment(tctx, "%s,%s%s vs. %s,%s%s with %s ip(s) => %s\n",
1186 wrepl_name_type_string(records[i-1].type),
1187 wrepl_name_state_string(records[i-1].state),
1188 (records[i-1].is_static?",static":""),
1189 wrepl_name_type_string(records[i].type),
1190 wrepl_name_state_string(records[i].state),
1191 (records[i].is_static?",static":""),
1192 (records[i-1].ips==records[i].ips?"same":"different"),
1193 "REPLACE");
1196 wins_name_cur->name = &names[j];
1197 wins_name_cur->flags = WREPL_NAME_FLAGS(records[i].type,
1198 records[i].state,
1199 records[i].node,
1200 records[i].is_static);
1201 wins_name_cur->id = ++ctx->a.max_version;
1202 if (wins_name_cur->flags & 2) {
1203 wins_name_cur->addresses.addresses.num_ips = records[i].num_ips;
1204 wins_name_cur->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
1205 records[i].ips);
1206 } else {
1207 wins_name_cur->addresses.ip = records[i].ips[0].ip;
1209 wins_name_cur->unknown = "255.255.255.255";
1211 ret &= test_wrepl_update_one(tctx, ctx, &ctx->a,wins_name_cur);
1212 if (records[i].state == WREPL_STATE_RELEASED) {
1213 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->a, wins_name_last, false);
1214 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->a, wins_name_cur, false);
1215 } else {
1216 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->a, wins_name_cur, true);
1219 /* the first one is a cleanup run */
1220 if (!ret && i == 0) ret = true;
1222 if (!ret) {
1223 torture_comment(tctx, "conflict handled wrong or record[%u]: %s\n", i, __location__);
1224 return ret;
1228 return ret;
1231 static bool test_conflict_different_owner(struct torture_context *tctx,
1232 struct test_wrepl_conflict_conn *ctx)
1234 bool ret = true;
1235 struct wrepl_wins_name wins_name1;
1236 struct wrepl_wins_name wins_name2;
1237 struct wrepl_wins_name *wins_name_r1;
1238 struct wrepl_wins_name *wins_name_r2;
1239 uint32_t i;
1240 struct {
1241 const char *line; /* just better debugging */
1242 struct nbt_name name;
1243 const char *comment;
1244 bool extra; /* not the worst case, this is an extra test */
1245 bool cleanup;
1246 struct {
1247 struct wrepl_wins_owner *owner;
1248 enum wrepl_name_type type;
1249 enum wrepl_name_state state;
1250 enum wrepl_name_node node;
1251 bool is_static;
1252 uint32_t num_ips;
1253 const struct wrepl_ip *ips;
1254 bool apply_expected;
1255 bool sgroup_merge;
1256 struct wrepl_wins_owner *merge_owner;
1257 bool sgroup_cleanup;
1258 } r1, r2;
1259 } records[] = {
1261 * NOTE: the first record and the last applied one
1262 * needs to be from the same owner,
1263 * to not conflict in the next smbtorture run!!!
1266 .line = __location__,
1267 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1268 .cleanup= true,
1269 .r1 = {
1270 .owner = &ctx->b,
1271 .type = WREPL_TYPE_UNIQUE,
1272 .state = WREPL_STATE_TOMBSTONE,
1273 .node = WREPL_NODE_B,
1274 .is_static = false,
1275 .num_ips = ARRAY_SIZE(addresses_B_1),
1276 .ips = addresses_B_1,
1277 .apply_expected = true /* ignored */
1279 .r2 = {
1280 .owner = &ctx->a,
1281 .type = WREPL_TYPE_UNIQUE,
1282 .state = WREPL_STATE_TOMBSTONE,
1283 .node = WREPL_NODE_B,
1284 .is_static = false,
1285 .num_ips = ARRAY_SIZE(addresses_A_1),
1286 .ips = addresses_A_1,
1287 .apply_expected = true /* ignored */
1292 * unique vs unique section
1295 * unique,active vs. unique,active
1296 * => should be replaced
1299 .line = __location__,
1300 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1301 .r1 = {
1302 .owner = &ctx->a,
1303 .type = WREPL_TYPE_UNIQUE,
1304 .state = WREPL_STATE_ACTIVE,
1305 .node = WREPL_NODE_B,
1306 .is_static = false,
1307 .num_ips = ARRAY_SIZE(addresses_A_1),
1308 .ips = addresses_A_1,
1309 .apply_expected = true
1311 .r2 = {
1312 .owner = &ctx->b,
1313 .type = WREPL_TYPE_UNIQUE,
1314 .state = WREPL_STATE_ACTIVE,
1315 .node = WREPL_NODE_B,
1316 .is_static = false,
1317 .num_ips = ARRAY_SIZE(addresses_B_1),
1318 .ips = addresses_B_1,
1319 .apply_expected = true
1324 * unique,active vs. unique,tombstone
1325 * => should NOT be replaced
1328 .line = __location__,
1329 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1330 .r1 = {
1331 .owner = &ctx->b,
1332 .type = WREPL_TYPE_UNIQUE,
1333 .state = WREPL_STATE_ACTIVE,
1334 .node = WREPL_NODE_B,
1335 .is_static = false,
1336 .num_ips = ARRAY_SIZE(addresses_B_1),
1337 .ips = addresses_B_1,
1338 .apply_expected = true
1340 .r2 = {
1341 .owner = &ctx->a,
1342 .type = WREPL_TYPE_UNIQUE,
1343 .state = WREPL_STATE_TOMBSTONE,
1344 .node = WREPL_NODE_B,
1345 .is_static = false,
1346 .num_ips = ARRAY_SIZE(addresses_B_1),
1347 .ips = addresses_B_1,
1348 .apply_expected = false
1353 * unique,released vs. unique,active
1354 * => should be replaced
1357 .line = __location__,
1358 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1359 .r1 = {
1360 .owner = &ctx->b,
1361 .type = WREPL_TYPE_UNIQUE,
1362 .state = WREPL_STATE_RELEASED,
1363 .node = WREPL_NODE_B,
1364 .is_static = false,
1365 .num_ips = ARRAY_SIZE(addresses_B_1),
1366 .ips = addresses_B_1,
1367 .apply_expected = false
1369 .r2 = {
1370 .owner = &ctx->a,
1371 .type = WREPL_TYPE_UNIQUE,
1372 .state = WREPL_STATE_ACTIVE,
1373 .node = WREPL_NODE_B,
1374 .is_static = false,
1375 .num_ips = ARRAY_SIZE(addresses_A_1),
1376 .ips = addresses_A_1,
1377 .apply_expected = true
1382 * unique,released vs. unique,tombstone
1383 * => should be replaced
1386 .line = __location__,
1387 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1388 .r1 = {
1389 .owner = &ctx->a,
1390 .type = WREPL_TYPE_UNIQUE,
1391 .state = WREPL_STATE_RELEASED,
1392 .node = WREPL_NODE_B,
1393 .is_static = false,
1394 .num_ips = ARRAY_SIZE(addresses_A_1),
1395 .ips = addresses_A_1,
1396 .apply_expected = false
1398 .r2 = {
1399 .owner = &ctx->b,
1400 .type = WREPL_TYPE_UNIQUE,
1401 .state = WREPL_STATE_TOMBSTONE,
1402 .node = WREPL_NODE_B,
1403 .is_static = false,
1404 .num_ips = ARRAY_SIZE(addresses_B_1),
1405 .ips = addresses_B_1,
1406 .apply_expected = true
1411 * unique,tombstone vs. unique,active
1412 * => should be replaced
1415 .line = __location__,
1416 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1417 .r1 = {
1418 .owner = &ctx->b,
1419 .type = WREPL_TYPE_UNIQUE,
1420 .state = WREPL_STATE_TOMBSTONE,
1421 .node = WREPL_NODE_B,
1422 .is_static = false,
1423 .num_ips = ARRAY_SIZE(addresses_B_1),
1424 .ips = addresses_B_1,
1425 .apply_expected = true
1427 .r2 = {
1428 .owner = &ctx->a,
1429 .type = WREPL_TYPE_UNIQUE,
1430 .state = WREPL_STATE_ACTIVE,
1431 .node = WREPL_NODE_B,
1432 .is_static = false,
1433 .num_ips = ARRAY_SIZE(addresses_A_1),
1434 .ips = addresses_A_1,
1435 .apply_expected = true
1440 * unique,tombstone vs. unique,tombstone
1441 * => should be replaced
1444 .line = __location__,
1445 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1446 .r1 = {
1447 .owner = &ctx->a,
1448 .type = WREPL_TYPE_UNIQUE,
1449 .state = WREPL_STATE_TOMBSTONE,
1450 .node = WREPL_NODE_B,
1451 .is_static = false,
1452 .num_ips = ARRAY_SIZE(addresses_A_1),
1453 .ips = addresses_A_1,
1454 .apply_expected = true
1456 .r2 = {
1457 .owner = &ctx->b,
1458 .type = WREPL_TYPE_UNIQUE,
1459 .state = WREPL_STATE_TOMBSTONE,
1460 .node = WREPL_NODE_B,
1461 .is_static = false,
1462 .num_ips = ARRAY_SIZE(addresses_B_1),
1463 .ips = addresses_B_1,
1464 .apply_expected = true
1470 * unique vs normal groups section,
1473 * unique,active vs. group,active
1474 * => should be replaced
1477 .line = __location__,
1478 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1479 .r1 = {
1480 .owner = &ctx->b,
1481 .type = WREPL_TYPE_UNIQUE,
1482 .state = WREPL_STATE_ACTIVE,
1483 .node = WREPL_NODE_B,
1484 .is_static = false,
1485 .num_ips = ARRAY_SIZE(addresses_B_1),
1486 .ips = addresses_B_1,
1487 .apply_expected = true
1489 .r2 = {
1490 .owner = &ctx->a,
1491 .type = WREPL_TYPE_GROUP,
1492 .state = WREPL_STATE_ACTIVE,
1493 .node = WREPL_NODE_B,
1494 .is_static = false,
1495 .num_ips = ARRAY_SIZE(addresses_A_1),
1496 .ips = addresses_A_1,
1497 .apply_expected = true
1502 * unique,active vs. group,tombstone
1503 * => should NOT be replaced
1506 .line = __location__,
1507 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1508 .r1 = {
1509 .owner = &ctx->a,
1510 .type = WREPL_TYPE_UNIQUE,
1511 .state = WREPL_STATE_ACTIVE,
1512 .node = WREPL_NODE_B,
1513 .is_static = false,
1514 .num_ips = ARRAY_SIZE(addresses_A_1),
1515 .ips = addresses_A_1,
1516 .apply_expected = true
1518 .r2 = {
1519 .owner = &ctx->b,
1520 .type = WREPL_TYPE_GROUP,
1521 .state = WREPL_STATE_TOMBSTONE,
1522 .node = WREPL_NODE_B,
1523 .is_static = false,
1524 .num_ips = ARRAY_SIZE(addresses_A_1),
1525 .ips = addresses_A_1,
1526 .apply_expected = false
1531 * unique,released vs. group,active
1532 * => should be replaced
1535 .line = __location__,
1536 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1537 .r1 = {
1538 .owner = &ctx->a,
1539 .type = WREPL_TYPE_UNIQUE,
1540 .state = WREPL_STATE_RELEASED,
1541 .node = WREPL_NODE_B,
1542 .is_static = false,
1543 .num_ips = ARRAY_SIZE(addresses_A_1),
1544 .ips = addresses_A_1,
1545 .apply_expected = false
1547 .r2 = {
1548 .owner = &ctx->b,
1549 .type = WREPL_TYPE_GROUP,
1550 .state = WREPL_STATE_ACTIVE,
1551 .node = WREPL_NODE_B,
1552 .is_static = false,
1553 .num_ips = ARRAY_SIZE(addresses_B_1),
1554 .ips = addresses_B_1,
1555 .apply_expected = true
1560 * unique,released vs. group,tombstone
1561 * => should be replaced
1564 .line = __location__,
1565 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1566 .r1 = {
1567 .owner = &ctx->b,
1568 .type = WREPL_TYPE_UNIQUE,
1569 .state = WREPL_STATE_RELEASED,
1570 .node = WREPL_NODE_B,
1571 .is_static = false,
1572 .num_ips = ARRAY_SIZE(addresses_B_1),
1573 .ips = addresses_B_1,
1574 .apply_expected = false
1576 .r2 = {
1577 .owner = &ctx->a,
1578 .type = WREPL_TYPE_GROUP,
1579 .state = WREPL_STATE_TOMBSTONE,
1580 .node = WREPL_NODE_B,
1581 .is_static = false,
1582 .num_ips = ARRAY_SIZE(addresses_A_1),
1583 .ips = addresses_A_1,
1584 .apply_expected = true
1589 * unique,tombstone vs. group,active
1590 * => should be replaced
1593 .line = __location__,
1594 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1595 .r1 = {
1596 .owner = &ctx->a,
1597 .type = WREPL_TYPE_UNIQUE,
1598 .state = WREPL_STATE_TOMBSTONE,
1599 .node = WREPL_NODE_B,
1600 .is_static = false,
1601 .num_ips = ARRAY_SIZE(addresses_A_1),
1602 .ips = addresses_A_1,
1603 .apply_expected = true
1605 .r2 = {
1606 .owner = &ctx->b,
1607 .type = WREPL_TYPE_GROUP,
1608 .state = WREPL_STATE_ACTIVE,
1609 .node = WREPL_NODE_B,
1610 .is_static = false,
1611 .num_ips = ARRAY_SIZE(addresses_B_1),
1612 .ips = addresses_B_1,
1613 .apply_expected = true
1618 * unique,tombstone vs. group,tombstone
1619 * => should be replaced
1622 .line = __location__,
1623 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1624 .r1 = {
1625 .owner = &ctx->b,
1626 .type = WREPL_TYPE_UNIQUE,
1627 .state = WREPL_STATE_TOMBSTONE,
1628 .node = WREPL_NODE_B,
1629 .is_static = false,
1630 .num_ips = ARRAY_SIZE(addresses_B_1),
1631 .ips = addresses_B_1,
1632 .apply_expected = true
1634 .r2 = {
1635 .owner = &ctx->a,
1636 .type = WREPL_TYPE_GROUP,
1637 .state = WREPL_STATE_TOMBSTONE,
1638 .node = WREPL_NODE_B,
1639 .is_static = false,
1640 .num_ips = ARRAY_SIZE(addresses_A_1),
1641 .ips = addresses_A_1,
1642 .apply_expected = true
1647 * unique vs special groups section,
1650 * unique,active vs. sgroup,active
1651 * => should NOT be replaced
1654 .line = __location__,
1655 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1656 .r1 = {
1657 .owner = &ctx->a,
1658 .type = WREPL_TYPE_UNIQUE,
1659 .state = WREPL_STATE_ACTIVE,
1660 .node = WREPL_NODE_B,
1661 .is_static = false,
1662 .num_ips = ARRAY_SIZE(addresses_A_1),
1663 .ips = addresses_A_1,
1664 .apply_expected = true
1666 .r2 = {
1667 .owner = &ctx->b,
1668 .type = WREPL_TYPE_SGROUP,
1669 .state = WREPL_STATE_ACTIVE,
1670 .node = WREPL_NODE_B,
1671 .is_static = false,
1672 .num_ips = ARRAY_SIZE(addresses_A_1),
1673 .ips = addresses_A_1,
1674 .apply_expected = false
1679 * unique,active vs. sgroup,tombstone
1680 * => should NOT be replaced
1683 .line = __location__,
1684 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1685 .r1 = {
1686 .owner = &ctx->a,
1687 .type = WREPL_TYPE_UNIQUE,
1688 .state = WREPL_STATE_ACTIVE,
1689 .node = WREPL_NODE_B,
1690 .is_static = false,
1691 .num_ips = ARRAY_SIZE(addresses_A_1),
1692 .ips = addresses_A_1,
1693 .apply_expected = true
1695 .r2 = {
1696 .owner = &ctx->b,
1697 .type = WREPL_TYPE_SGROUP,
1698 .state = WREPL_STATE_TOMBSTONE,
1699 .node = WREPL_NODE_B,
1700 .is_static = false,
1701 .num_ips = ARRAY_SIZE(addresses_A_1),
1702 .ips = addresses_A_1,
1703 .apply_expected = false
1708 * unique,released vs. sgroup,active
1709 * => should be replaced
1712 .line = __location__,
1713 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1714 .r1 = {
1715 .owner = &ctx->a,
1716 .type = WREPL_TYPE_UNIQUE,
1717 .state = WREPL_STATE_RELEASED,
1718 .node = WREPL_NODE_B,
1719 .is_static = false,
1720 .num_ips = ARRAY_SIZE(addresses_A_1),
1721 .ips = addresses_A_1,
1722 .apply_expected = false
1724 .r2 = {
1725 .owner = &ctx->b,
1726 .type = WREPL_TYPE_SGROUP,
1727 .state = WREPL_STATE_ACTIVE,
1728 .node = WREPL_NODE_B,
1729 .is_static = false,
1730 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1731 .ips = addresses_B_3_4,
1732 .apply_expected = true
1737 * unique,released vs. sgroup,tombstone
1738 * => should be replaced
1741 .line = __location__,
1742 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1743 .r1 = {
1744 .owner = &ctx->b,
1745 .type = WREPL_TYPE_UNIQUE,
1746 .state = WREPL_STATE_RELEASED,
1747 .node = WREPL_NODE_B,
1748 .is_static = false,
1749 .num_ips = ARRAY_SIZE(addresses_B_1),
1750 .ips = addresses_B_1,
1751 .apply_expected = false
1753 .r2 = {
1754 .owner = &ctx->a,
1755 .type = WREPL_TYPE_SGROUP,
1756 .state = WREPL_STATE_TOMBSTONE,
1757 .node = WREPL_NODE_B,
1758 .is_static = false,
1759 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1760 .ips = addresses_A_3_4,
1761 .apply_expected = true
1766 * unique,tombstone vs. sgroup,active
1767 * => should be replaced
1770 .line = __location__,
1771 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1772 .r1 = {
1773 .owner = &ctx->a,
1774 .type = WREPL_TYPE_UNIQUE,
1775 .state = WREPL_STATE_TOMBSTONE,
1776 .node = WREPL_NODE_B,
1777 .is_static = false,
1778 .num_ips = ARRAY_SIZE(addresses_A_1),
1779 .ips = addresses_A_1,
1780 .apply_expected = true
1782 .r2 = {
1783 .owner = &ctx->b,
1784 .type = WREPL_TYPE_SGROUP,
1785 .state = WREPL_STATE_ACTIVE,
1786 .node = WREPL_NODE_B,
1787 .is_static = false,
1788 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1789 .ips = addresses_B_3_4,
1790 .apply_expected = true
1795 * unique,tombstone vs. sgroup,tombstone
1796 * => should be replaced
1799 .line = __location__,
1800 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1801 .r1 = {
1802 .owner = &ctx->b,
1803 .type = WREPL_TYPE_UNIQUE,
1804 .state = WREPL_STATE_TOMBSTONE,
1805 .node = WREPL_NODE_B,
1806 .is_static = false,
1807 .num_ips = ARRAY_SIZE(addresses_B_1),
1808 .ips = addresses_B_1,
1809 .apply_expected = true
1811 .r2 = {
1812 .owner = &ctx->a,
1813 .type = WREPL_TYPE_SGROUP,
1814 .state = WREPL_STATE_TOMBSTONE,
1815 .node = WREPL_NODE_B,
1816 .is_static = false,
1817 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1818 .ips = addresses_A_3_4,
1819 .apply_expected = true
1824 * unique vs multi homed section,
1827 * unique,active vs. mhomed,active
1828 * => should be replaced
1831 .line = __location__,
1832 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1833 .r1 = {
1834 .owner = &ctx->a,
1835 .type = WREPL_TYPE_UNIQUE,
1836 .state = WREPL_STATE_ACTIVE,
1837 .node = WREPL_NODE_B,
1838 .is_static = false,
1839 .num_ips = ARRAY_SIZE(addresses_A_1),
1840 .ips = addresses_A_1,
1841 .apply_expected = true
1843 .r2 = {
1844 .owner = &ctx->b,
1845 .type = WREPL_TYPE_MHOMED,
1846 .state = WREPL_STATE_ACTIVE,
1847 .node = WREPL_NODE_B,
1848 .is_static = false,
1849 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1850 .ips = addresses_B_3_4,
1851 .apply_expected = true
1856 * unique,active vs. mhomed,tombstone
1857 * => should NOT be replaced
1860 .line = __location__,
1861 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1862 .r1 = {
1863 .owner = &ctx->b,
1864 .type = WREPL_TYPE_UNIQUE,
1865 .state = WREPL_STATE_ACTIVE,
1866 .node = WREPL_NODE_B,
1867 .is_static = false,
1868 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1869 .ips = addresses_B_3_4,
1870 .apply_expected = true
1872 .r2 = {
1873 .owner = &ctx->a,
1874 .type = WREPL_TYPE_MHOMED,
1875 .state = WREPL_STATE_TOMBSTONE,
1876 .node = WREPL_NODE_B,
1877 .is_static = false,
1878 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1879 .ips = addresses_B_3_4,
1880 .apply_expected = false
1885 * unique,released vs. mhomed,active
1886 * => should be replaced
1889 .line = __location__,
1890 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1891 .r1 = {
1892 .owner = &ctx->b,
1893 .type = WREPL_TYPE_UNIQUE,
1894 .state = WREPL_STATE_RELEASED,
1895 .node = WREPL_NODE_B,
1896 .is_static = false,
1897 .num_ips = ARRAY_SIZE(addresses_B_1),
1898 .ips = addresses_B_1,
1899 .apply_expected = false
1901 .r2 = {
1902 .owner = &ctx->a,
1903 .type = WREPL_TYPE_MHOMED,
1904 .state = WREPL_STATE_ACTIVE,
1905 .node = WREPL_NODE_B,
1906 .is_static = false,
1907 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1908 .ips = addresses_A_3_4,
1909 .apply_expected = true
1914 * unique,released vs. mhomed,tombstone
1915 * => should be replaced
1918 .line = __location__,
1919 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1920 .r1 = {
1921 .owner = &ctx->a,
1922 .type = WREPL_TYPE_UNIQUE,
1923 .state = WREPL_STATE_RELEASED,
1924 .node = WREPL_NODE_B,
1925 .is_static = false,
1926 .num_ips = ARRAY_SIZE(addresses_A_1),
1927 .ips = addresses_A_1,
1928 .apply_expected = false
1930 .r2 = {
1931 .owner = &ctx->b,
1932 .type = WREPL_TYPE_MHOMED,
1933 .state = WREPL_STATE_TOMBSTONE,
1934 .node = WREPL_NODE_B,
1935 .is_static = false,
1936 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1937 .ips = addresses_B_3_4,
1938 .apply_expected = true
1943 * unique,tombstone vs. mhomed,active
1944 * => should be replaced
1947 .line = __location__,
1948 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1949 .r1 = {
1950 .owner = &ctx->b,
1951 .type = WREPL_TYPE_UNIQUE,
1952 .state = WREPL_STATE_TOMBSTONE,
1953 .node = WREPL_NODE_B,
1954 .is_static = false,
1955 .num_ips = ARRAY_SIZE(addresses_B_1),
1956 .ips = addresses_B_1,
1957 .apply_expected = true
1959 .r2 = {
1960 .owner = &ctx->a,
1961 .type = WREPL_TYPE_MHOMED,
1962 .state = WREPL_STATE_ACTIVE,
1963 .node = WREPL_NODE_B,
1964 .is_static = false,
1965 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1966 .ips = addresses_A_3_4,
1967 .apply_expected = true
1972 * unique,tombstone vs. mhomed,tombstone
1973 * => should be replaced
1976 .line = __location__,
1977 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1978 .r1 = {
1979 .owner = &ctx->a,
1980 .type = WREPL_TYPE_UNIQUE,
1981 .state = WREPL_STATE_TOMBSTONE,
1982 .node = WREPL_NODE_B,
1983 .is_static = false,
1984 .num_ips = ARRAY_SIZE(addresses_A_1),
1985 .ips = addresses_A_1,
1986 .apply_expected = true
1988 .r2 = {
1989 .owner = &ctx->b,
1990 .type = WREPL_TYPE_MHOMED,
1991 .state = WREPL_STATE_TOMBSTONE,
1992 .node = WREPL_NODE_B,
1993 .is_static = false,
1994 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1995 .ips = addresses_B_3_4,
1996 .apply_expected = true
2001 * normal groups vs unique section,
2004 * group,active vs. unique,active
2005 * => should NOT be replaced
2008 .line = __location__,
2009 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2010 .r1 = {
2011 .owner = &ctx->a,
2012 .type = WREPL_TYPE_GROUP,
2013 .state = WREPL_STATE_ACTIVE,
2014 .node = WREPL_NODE_B,
2015 .is_static = false,
2016 .num_ips = ARRAY_SIZE(addresses_A_1),
2017 .ips = addresses_A_1,
2018 .apply_expected = true
2020 .r2 = {
2021 .owner = &ctx->b,
2022 .type = WREPL_TYPE_UNIQUE,
2023 .state = WREPL_STATE_ACTIVE,
2024 .node = WREPL_NODE_B,
2025 .is_static = false,
2026 .num_ips = ARRAY_SIZE(addresses_A_1),
2027 .ips = addresses_A_1,
2028 .apply_expected = false
2033 * group,active vs. unique,tombstone
2034 * => should NOT be replaced
2037 .line = __location__,
2038 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2039 .r1 = {
2040 .owner = &ctx->a,
2041 .type = WREPL_TYPE_GROUP,
2042 .state = WREPL_STATE_ACTIVE,
2043 .node = WREPL_NODE_B,
2044 .is_static = false,
2045 .num_ips = ARRAY_SIZE(addresses_A_1),
2046 .ips = addresses_A_1,
2047 .apply_expected = true
2049 .r2 = {
2050 .owner = &ctx->b,
2051 .type = WREPL_TYPE_UNIQUE,
2052 .state = WREPL_STATE_TOMBSTONE,
2053 .node = WREPL_NODE_B,
2054 .is_static = false,
2055 .num_ips = ARRAY_SIZE(addresses_A_1),
2056 .ips = addresses_A_1,
2057 .apply_expected = false
2062 * group,released vs. unique,active
2063 * => should NOT be replaced
2066 .line = __location__,
2067 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2068 .r1 = {
2069 .owner = &ctx->a,
2070 .type = WREPL_TYPE_GROUP,
2071 .state = WREPL_STATE_RELEASED,
2072 .node = WREPL_NODE_B,
2073 .is_static = false,
2074 .num_ips = ARRAY_SIZE(addresses_A_1),
2075 .ips = addresses_A_1,
2076 .apply_expected = false
2078 .r2 = {
2079 .owner = &ctx->b,
2080 .type = WREPL_TYPE_UNIQUE,
2081 .state = WREPL_STATE_ACTIVE,
2082 .node = WREPL_NODE_B,
2083 .is_static = false,
2084 .num_ips = ARRAY_SIZE(addresses_A_1),
2085 .ips = addresses_A_1,
2086 .apply_expected = false
2091 * group,released vs. unique,tombstone
2092 * => should NOT be replaced
2095 .line = __location__,
2096 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2097 .r1 = {
2098 .owner = &ctx->a,
2099 .type = WREPL_TYPE_GROUP,
2100 .state = WREPL_STATE_RELEASED,
2101 .node = WREPL_NODE_B,
2102 .is_static = false,
2103 .num_ips = ARRAY_SIZE(addresses_A_1),
2104 .ips = addresses_A_1,
2105 .apply_expected = false
2107 .r2 = {
2108 .owner = &ctx->b,
2109 .type = WREPL_TYPE_UNIQUE,
2110 .state = WREPL_STATE_TOMBSTONE,
2111 .node = WREPL_NODE_B,
2112 .is_static = false,
2113 .num_ips = ARRAY_SIZE(addresses_A_1),
2114 .ips = addresses_A_1,
2115 .apply_expected = false
2120 * group,tombstone vs. unique,active
2121 * => should NOT be replaced
2124 .line = __location__,
2125 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2126 .r1 = {
2127 .owner = &ctx->a,
2128 .type = WREPL_TYPE_GROUP,
2129 .state = WREPL_STATE_TOMBSTONE,
2130 .node = WREPL_NODE_B,
2131 .is_static = false,
2132 .num_ips = ARRAY_SIZE(addresses_A_1),
2133 .ips = addresses_A_1,
2134 .apply_expected = true
2136 .r2 = {
2137 .owner = &ctx->b,
2138 .type = WREPL_TYPE_UNIQUE,
2139 .state = WREPL_STATE_ACTIVE,
2140 .node = WREPL_NODE_B,
2141 .is_static = false,
2142 .num_ips = ARRAY_SIZE(addresses_A_1),
2143 .ips = addresses_A_1,
2144 .apply_expected = false
2149 * group,tombstone vs. unique,tombstone
2150 * => should NOT be replaced
2153 .line = __location__,
2154 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2155 .r1 = {
2156 .owner = &ctx->a,
2157 .type = WREPL_TYPE_GROUP,
2158 .state = WREPL_STATE_TOMBSTONE,
2159 .node = WREPL_NODE_B,
2160 .is_static = false,
2161 .num_ips = ARRAY_SIZE(addresses_A_1),
2162 .ips = addresses_A_1,
2163 .apply_expected = true
2165 .r2 = {
2166 .owner = &ctx->b,
2167 .type = WREPL_TYPE_UNIQUE,
2168 .state = WREPL_STATE_TOMBSTONE,
2169 .node = WREPL_NODE_B,
2170 .is_static = false,
2171 .num_ips = ARRAY_SIZE(addresses_A_1),
2172 .ips = addresses_A_1,
2173 .apply_expected = false
2178 * normal groups vs normal groups section,
2181 * group,active vs. group,active
2182 * => should NOT be replaced
2185 .line = __location__,
2186 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2187 .r1 = {
2188 .owner = &ctx->a,
2189 .type = WREPL_TYPE_GROUP,
2190 .state = WREPL_STATE_ACTIVE,
2191 .node = WREPL_NODE_B,
2192 .is_static = false,
2193 .num_ips = ARRAY_SIZE(addresses_A_1),
2194 .ips = addresses_A_1,
2195 .apply_expected = true
2197 .r2 = {
2198 .owner = &ctx->b,
2199 .type = WREPL_TYPE_GROUP,
2200 .state = WREPL_STATE_ACTIVE,
2201 .node = WREPL_NODE_B,
2202 .is_static = false,
2203 .num_ips = ARRAY_SIZE(addresses_A_1),
2204 .ips = addresses_A_1,
2205 .apply_expected = false
2210 * group,active vs. group,tombstone
2211 * => should NOT be replaced
2214 .line = __location__,
2215 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2216 .r1 = {
2217 .owner = &ctx->a,
2218 .type = WREPL_TYPE_GROUP,
2219 .state = WREPL_STATE_ACTIVE,
2220 .node = WREPL_NODE_B,
2221 .is_static = false,
2222 .num_ips = ARRAY_SIZE(addresses_A_1),
2223 .ips = addresses_A_1,
2224 .apply_expected = true
2226 .r2 = {
2227 .owner = &ctx->b,
2228 .type = WREPL_TYPE_GROUP,
2229 .state = WREPL_STATE_TOMBSTONE,
2230 .node = WREPL_NODE_B,
2231 .is_static = false,
2232 .num_ips = ARRAY_SIZE(addresses_A_1),
2233 .ips = addresses_A_1,
2234 .apply_expected = false
2239 * group,released vs. group,active
2240 * => should be replaced
2243 .line = __location__,
2244 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2245 .r1 = {
2246 .owner = &ctx->a,
2247 .type = WREPL_TYPE_GROUP,
2248 .state = WREPL_STATE_RELEASED,
2249 .node = WREPL_NODE_B,
2250 .is_static = false,
2251 .num_ips = ARRAY_SIZE(addresses_A_1),
2252 .ips = addresses_A_1,
2253 .apply_expected = false
2255 .r2 = {
2256 .owner = &ctx->b,
2257 .type = WREPL_TYPE_GROUP,
2258 .state = WREPL_STATE_ACTIVE,
2259 .node = WREPL_NODE_B,
2260 .is_static = false,
2261 .num_ips = ARRAY_SIZE(addresses_B_1),
2262 .ips = addresses_B_1,
2263 .apply_expected = true
2268 * group,released vs. group,tombstone
2269 * => should be replaced
2272 .line = __location__,
2273 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2274 .r1 = {
2275 .owner = &ctx->a,
2276 .type = WREPL_TYPE_GROUP,
2277 .state = WREPL_STATE_RELEASED,
2278 .node = WREPL_NODE_B,
2279 .is_static = false,
2280 .num_ips = ARRAY_SIZE(addresses_A_1),
2281 .ips = addresses_A_1,
2282 .apply_expected = false
2284 .r2 = {
2285 .owner = &ctx->b,
2286 .type = WREPL_TYPE_GROUP,
2287 .state = WREPL_STATE_TOMBSTONE,
2288 .node = WREPL_NODE_B,
2289 .is_static = false,
2290 .num_ips = ARRAY_SIZE(addresses_B_1),
2291 .ips = addresses_B_1,
2292 .apply_expected = true
2297 * group,tombstone vs. group,active
2298 * => should be replaced
2301 .line = __location__,
2302 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2303 .r1 = {
2304 .owner = &ctx->b,
2305 .type = WREPL_TYPE_GROUP,
2306 .state = WREPL_STATE_TOMBSTONE,
2307 .node = WREPL_NODE_B,
2308 .is_static = false,
2309 .num_ips = ARRAY_SIZE(addresses_B_1),
2310 .ips = addresses_B_1,
2311 .apply_expected = true
2313 .r2 = {
2314 .owner = &ctx->a,
2315 .type = WREPL_TYPE_GROUP,
2316 .state = WREPL_STATE_ACTIVE,
2317 .node = WREPL_NODE_B,
2318 .is_static = false,
2319 .num_ips = ARRAY_SIZE(addresses_A_1),
2320 .ips = addresses_A_1,
2321 .apply_expected = true
2326 * group,tombstone vs. group,tombstone
2327 * => should be replaced
2330 .line = __location__,
2331 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2332 .r1 = {
2333 .owner = &ctx->a,
2334 .type = WREPL_TYPE_GROUP,
2335 .state = WREPL_STATE_TOMBSTONE,
2336 .node = WREPL_NODE_B,
2337 .is_static = false,
2338 .num_ips = ARRAY_SIZE(addresses_A_1),
2339 .ips = addresses_A_1,
2340 .apply_expected = true
2342 .r2 = {
2343 .owner = &ctx->b,
2344 .type = WREPL_TYPE_GROUP,
2345 .state = WREPL_STATE_TOMBSTONE,
2346 .node = WREPL_NODE_B,
2347 .is_static = false,
2348 .num_ips = ARRAY_SIZE(addresses_B_1),
2349 .ips = addresses_B_1,
2350 .apply_expected = true
2355 * normal groups vs special groups section,
2358 * group,active vs. sgroup,active
2359 * => should NOT be replaced
2362 .line = __location__,
2363 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2364 .r1 = {
2365 .owner = &ctx->b,
2366 .type = WREPL_TYPE_GROUP,
2367 .state = WREPL_STATE_ACTIVE,
2368 .node = WREPL_NODE_B,
2369 .is_static = false,
2370 .num_ips = ARRAY_SIZE(addresses_B_1),
2371 .ips = addresses_B_1,
2372 .apply_expected = true
2374 .r2 = {
2375 .owner = &ctx->a,
2376 .type = WREPL_TYPE_SGROUP,
2377 .state = WREPL_STATE_ACTIVE,
2378 .node = WREPL_NODE_B,
2379 .is_static = false,
2380 .num_ips = ARRAY_SIZE(addresses_B_1),
2381 .ips = addresses_B_1,
2382 .apply_expected = false
2387 * group,active vs. sgroup,tombstone
2388 * => should NOT be replaced
2391 .line = __location__,
2392 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2393 .r1 = {
2394 .owner = &ctx->b,
2395 .type = WREPL_TYPE_GROUP,
2396 .state = WREPL_STATE_ACTIVE,
2397 .node = WREPL_NODE_B,
2398 .is_static = false,
2399 .num_ips = ARRAY_SIZE(addresses_B_1),
2400 .ips = addresses_B_1,
2401 .apply_expected = true
2403 .r2 = {
2404 .owner = &ctx->a,
2405 .type = WREPL_TYPE_SGROUP,
2406 .state = WREPL_STATE_TOMBSTONE,
2407 .node = WREPL_NODE_B,
2408 .is_static = false,
2409 .num_ips = ARRAY_SIZE(addresses_B_1),
2410 .ips = addresses_B_1,
2411 .apply_expected = false
2416 * group,released vs. sgroup,active
2417 * => should be replaced
2420 .line = __location__,
2421 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2422 .r1 = {
2423 .owner = &ctx->a,
2424 .type = WREPL_TYPE_GROUP,
2425 .state = WREPL_STATE_RELEASED,
2426 .node = WREPL_NODE_B,
2427 .is_static = false,
2428 .num_ips = ARRAY_SIZE(addresses_A_1),
2429 .ips = addresses_A_1,
2430 .apply_expected = false
2432 .r2 = {
2433 .owner = &ctx->b,
2434 .type = WREPL_TYPE_SGROUP,
2435 .state = WREPL_STATE_ACTIVE,
2436 .node = WREPL_NODE_B,
2437 .is_static = false,
2438 .num_ips = ARRAY_SIZE(addresses_B_1),
2439 .ips = addresses_B_1,
2440 .apply_expected = true
2445 * group,released vs. sgroup,tombstone
2446 * => should NOT be replaced
2449 .line = __location__,
2450 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2451 .r1 = {
2452 .owner = &ctx->b,
2453 .type = WREPL_TYPE_GROUP,
2454 .state = WREPL_STATE_RELEASED,
2455 .node = WREPL_NODE_B,
2456 .is_static = false,
2457 .num_ips = ARRAY_SIZE(addresses_B_1),
2458 .ips = addresses_B_1,
2459 .apply_expected = false
2461 .r2 = {
2462 .owner = &ctx->a,
2463 .type = WREPL_TYPE_SGROUP,
2464 .state = WREPL_STATE_TOMBSTONE,
2465 .node = WREPL_NODE_B,
2466 .is_static = false,
2467 .num_ips = ARRAY_SIZE(addresses_B_1),
2468 .ips = addresses_B_1,
2469 .apply_expected = false
2474 * group,tombstone vs. sgroup,active
2475 * => should be replaced
2478 .line = __location__,
2479 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2480 .r1 = {
2481 .owner = &ctx->b,
2482 .type = WREPL_TYPE_GROUP,
2483 .state = WREPL_STATE_TOMBSTONE,
2484 .node = WREPL_NODE_B,
2485 .is_static = false,
2486 .num_ips = ARRAY_SIZE(addresses_B_1),
2487 .ips = addresses_B_1,
2488 .apply_expected = true
2490 .r2 = {
2491 .owner = &ctx->a,
2492 .type = WREPL_TYPE_SGROUP,
2493 .state = WREPL_STATE_ACTIVE,
2494 .node = WREPL_NODE_B,
2495 .is_static = false,
2496 .num_ips = ARRAY_SIZE(addresses_A_1),
2497 .ips = addresses_A_1,
2498 .apply_expected = true
2503 * group,tombstone vs. sgroup,tombstone
2504 * => should be replaced
2507 .line = __location__,
2508 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2509 .r1 = {
2510 .owner = &ctx->a,
2511 .type = WREPL_TYPE_GROUP,
2512 .state = WREPL_STATE_TOMBSTONE,
2513 .node = WREPL_NODE_B,
2514 .is_static = false,
2515 .num_ips = ARRAY_SIZE(addresses_A_1),
2516 .ips = addresses_A_1,
2517 .apply_expected = true
2519 .r2 = {
2520 .owner = &ctx->b,
2521 .type = WREPL_TYPE_SGROUP,
2522 .state = WREPL_STATE_TOMBSTONE,
2523 .node = WREPL_NODE_B,
2524 .is_static = false,
2525 .num_ips = ARRAY_SIZE(addresses_B_1),
2526 .ips = addresses_B_1,
2527 .apply_expected = true
2532 * normal groups vs multi homed section,
2535 * group,active vs. mhomed,active
2536 * => should NOT be replaced
2539 .line = __location__,
2540 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2541 .r1 = {
2542 .owner = &ctx->b,
2543 .type = WREPL_TYPE_GROUP,
2544 .state = WREPL_STATE_ACTIVE,
2545 .node = WREPL_NODE_B,
2546 .is_static = false,
2547 .num_ips = ARRAY_SIZE(addresses_B_1),
2548 .ips = addresses_B_1,
2549 .apply_expected = true
2551 .r2 = {
2552 .owner = &ctx->a,
2553 .type = WREPL_TYPE_MHOMED,
2554 .state = WREPL_STATE_ACTIVE,
2555 .node = WREPL_NODE_B,
2556 .is_static = false,
2557 .num_ips = ARRAY_SIZE(addresses_B_1),
2558 .ips = addresses_B_1,
2559 .apply_expected = false
2564 * group,active vs. mhomed,tombstone
2565 * => should NOT be replaced
2568 .line = __location__,
2569 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2570 .r1 = {
2571 .owner = &ctx->b,
2572 .type = WREPL_TYPE_GROUP,
2573 .state = WREPL_STATE_ACTIVE,
2574 .node = WREPL_NODE_B,
2575 .is_static = false,
2576 .num_ips = ARRAY_SIZE(addresses_B_1),
2577 .ips = addresses_B_1,
2578 .apply_expected = true
2580 .r2 = {
2581 .owner = &ctx->a,
2582 .type = WREPL_TYPE_MHOMED,
2583 .state = WREPL_STATE_TOMBSTONE,
2584 .node = WREPL_NODE_B,
2585 .is_static = false,
2586 .num_ips = ARRAY_SIZE(addresses_B_1),
2587 .ips = addresses_B_1,
2588 .apply_expected = false
2593 * group,released vs. mhomed,active
2594 * => should NOT be replaced
2597 .line = __location__,
2598 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2599 .r1 = {
2600 .owner = &ctx->b,
2601 .type = WREPL_TYPE_GROUP,
2602 .state = WREPL_STATE_RELEASED,
2603 .node = WREPL_NODE_B,
2604 .is_static = false,
2605 .num_ips = ARRAY_SIZE(addresses_B_1),
2606 .ips = addresses_B_1,
2607 .apply_expected = false
2609 .r2 = {
2610 .owner = &ctx->a,
2611 .type = WREPL_TYPE_MHOMED,
2612 .state = WREPL_STATE_ACTIVE,
2613 .node = WREPL_NODE_B,
2614 .is_static = false,
2615 .num_ips = ARRAY_SIZE(addresses_B_1),
2616 .ips = addresses_B_1,
2617 .apply_expected = false
2622 * group,released vs. mhomed,tombstone
2623 * => should NOT be replaced
2626 .line = __location__,
2627 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2628 .r1 = {
2629 .owner = &ctx->b,
2630 .type = WREPL_TYPE_GROUP,
2631 .state = WREPL_STATE_RELEASED,
2632 .node = WREPL_NODE_B,
2633 .is_static = false,
2634 .num_ips = ARRAY_SIZE(addresses_B_1),
2635 .ips = addresses_B_1,
2636 .apply_expected = false
2638 .r2 = {
2639 .owner = &ctx->a,
2640 .type = WREPL_TYPE_MHOMED,
2641 .state = WREPL_STATE_TOMBSTONE,
2642 .node = WREPL_NODE_B,
2643 .is_static = false,
2644 .num_ips = ARRAY_SIZE(addresses_B_1),
2645 .ips = addresses_B_1,
2646 .apply_expected = false
2651 * group,tombstone vs. mhomed,active
2652 * => should be replaced
2655 .line = __location__,
2656 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2657 .r1 = {
2658 .owner = &ctx->b,
2659 .type = WREPL_TYPE_GROUP,
2660 .state = WREPL_STATE_TOMBSTONE,
2661 .node = WREPL_NODE_B,
2662 .is_static = false,
2663 .num_ips = ARRAY_SIZE(addresses_B_1),
2664 .ips = addresses_B_1,
2665 .apply_expected = true
2667 .r2 = {
2668 .owner = &ctx->a,
2669 .type = WREPL_TYPE_MHOMED,
2670 .state = WREPL_STATE_ACTIVE,
2671 .node = WREPL_NODE_B,
2672 .is_static = false,
2673 .num_ips = ARRAY_SIZE(addresses_A_1),
2674 .ips = addresses_A_1,
2675 .apply_expected = true
2680 * group,tombstone vs. mhomed,tombstone
2681 * => should be replaced
2684 .line = __location__,
2685 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2686 .r1 = {
2687 .owner = &ctx->a,
2688 .type = WREPL_TYPE_GROUP,
2689 .state = WREPL_STATE_TOMBSTONE,
2690 .node = WREPL_NODE_B,
2691 .is_static = false,
2692 .num_ips = ARRAY_SIZE(addresses_A_1),
2693 .ips = addresses_A_1,
2694 .apply_expected = true
2696 .r2 = {
2697 .owner = &ctx->b,
2698 .type = WREPL_TYPE_MHOMED,
2699 .state = WREPL_STATE_TOMBSTONE,
2700 .node = WREPL_NODE_B,
2701 .is_static = false,
2702 .num_ips = ARRAY_SIZE(addresses_B_1),
2703 .ips = addresses_B_1,
2704 .apply_expected = true
2709 * special groups vs unique section,
2712 * sgroup,active vs. unique,active
2713 * => should NOT be replaced
2716 .line = __location__,
2717 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2718 .r1 = {
2719 .owner = &ctx->b,
2720 .type = WREPL_TYPE_SGROUP,
2721 .state = WREPL_STATE_ACTIVE,
2722 .node = WREPL_NODE_B,
2723 .is_static = false,
2724 .num_ips = ARRAY_SIZE(addresses_B_1),
2725 .ips = addresses_B_1,
2726 .apply_expected = true
2728 .r2 = {
2729 .owner = &ctx->a,
2730 .type = WREPL_TYPE_UNIQUE,
2731 .state = WREPL_STATE_ACTIVE,
2732 .node = WREPL_NODE_B,
2733 .is_static = false,
2734 .num_ips = ARRAY_SIZE(addresses_B_1),
2735 .ips = addresses_B_1,
2736 .apply_expected = false
2741 * sgroup,active vs. unique,tombstone
2742 * => should NOT be replaced
2745 .line = __location__,
2746 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2747 .r1 = {
2748 .owner = &ctx->b,
2749 .type = WREPL_TYPE_SGROUP,
2750 .state = WREPL_STATE_ACTIVE,
2751 .node = WREPL_NODE_B,
2752 .is_static = false,
2753 .num_ips = ARRAY_SIZE(addresses_B_1),
2754 .ips = addresses_B_1,
2755 .apply_expected = true
2757 .r2 = {
2758 .owner = &ctx->a,
2759 .type = WREPL_TYPE_UNIQUE,
2760 .state = WREPL_STATE_TOMBSTONE,
2761 .node = WREPL_NODE_B,
2762 .is_static = false,
2763 .num_ips = ARRAY_SIZE(addresses_B_1),
2764 .ips = addresses_B_1,
2765 .apply_expected = false
2770 * sgroup,released vs. unique,active
2771 * => should be replaced
2774 .line = __location__,
2775 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2776 .r1 = {
2777 .owner = &ctx->b,
2778 .type = WREPL_TYPE_SGROUP,
2779 .state = WREPL_STATE_RELEASED,
2780 .node = WREPL_NODE_B,
2781 .is_static = false,
2782 .num_ips = ARRAY_SIZE(addresses_B_1),
2783 .ips = addresses_B_1,
2784 .apply_expected = false
2786 .r2 = {
2787 .owner = &ctx->a,
2788 .type = WREPL_TYPE_UNIQUE,
2789 .state = WREPL_STATE_ACTIVE,
2790 .node = WREPL_NODE_B,
2791 .is_static = false,
2792 .num_ips = ARRAY_SIZE(addresses_A_1),
2793 .ips = addresses_A_1,
2794 .apply_expected = true
2799 * sgroup,released vs. unique,tombstone
2800 * => should be replaced
2803 .line = __location__,
2804 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2805 .r1 = {
2806 .owner = &ctx->a,
2807 .type = WREPL_TYPE_SGROUP,
2808 .state = WREPL_STATE_RELEASED,
2809 .node = WREPL_NODE_B,
2810 .is_static = false,
2811 .num_ips = ARRAY_SIZE(addresses_A_1),
2812 .ips = addresses_A_1,
2813 .apply_expected = false
2815 .r2 = {
2816 .owner = &ctx->b,
2817 .type = WREPL_TYPE_UNIQUE,
2818 .state = WREPL_STATE_TOMBSTONE,
2819 .node = WREPL_NODE_B,
2820 .is_static = false,
2821 .num_ips = ARRAY_SIZE(addresses_B_1),
2822 .ips = addresses_B_1,
2823 .apply_expected = true
2828 * sgroup,tombstone vs. unique,active
2829 * => should be replaced
2832 .line = __location__,
2833 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2834 .r1 = {
2835 .owner = &ctx->a,
2836 .type = WREPL_TYPE_SGROUP,
2837 .state = WREPL_STATE_TOMBSTONE,
2838 .node = WREPL_NODE_B,
2839 .is_static = false,
2840 .num_ips = ARRAY_SIZE(addresses_A_1),
2841 .ips = addresses_A_1,
2842 .apply_expected = true
2844 .r2 = {
2845 .owner = &ctx->b,
2846 .type = WREPL_TYPE_UNIQUE,
2847 .state = WREPL_STATE_ACTIVE,
2848 .node = WREPL_NODE_B,
2849 .is_static = false,
2850 .num_ips = ARRAY_SIZE(addresses_B_1),
2851 .ips = addresses_B_1,
2852 .apply_expected = true
2857 * sgroup,tombstone vs. unique,tombstone
2858 * => should be replaced
2861 .line = __location__,
2862 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2863 .r1 = {
2864 .owner = &ctx->b,
2865 .type = WREPL_TYPE_SGROUP,
2866 .state = WREPL_STATE_TOMBSTONE,
2867 .node = WREPL_NODE_B,
2868 .is_static = false,
2869 .num_ips = ARRAY_SIZE(addresses_B_1),
2870 .ips = addresses_B_1,
2871 .apply_expected = true
2873 .r2 = {
2874 .owner = &ctx->a,
2875 .type = WREPL_TYPE_UNIQUE,
2876 .state = WREPL_STATE_TOMBSTONE,
2877 .node = WREPL_NODE_B,
2878 .is_static = false,
2879 .num_ips = ARRAY_SIZE(addresses_A_1),
2880 .ips = addresses_A_1,
2881 .apply_expected = true
2886 * special groups vs normal group section,
2889 * sgroup,active vs. group,active
2890 * => should NOT be replaced
2893 .line = __location__,
2894 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2895 .r1 = {
2896 .owner = &ctx->a,
2897 .type = WREPL_TYPE_SGROUP,
2898 .state = WREPL_STATE_ACTIVE,
2899 .node = WREPL_NODE_B,
2900 .is_static = false,
2901 .num_ips = ARRAY_SIZE(addresses_A_1),
2902 .ips = addresses_A_1,
2903 .apply_expected = true
2905 .r2 = {
2906 .owner = &ctx->b,
2907 .type = WREPL_TYPE_GROUP,
2908 .state = WREPL_STATE_ACTIVE,
2909 .node = WREPL_NODE_B,
2910 .is_static = false,
2911 .num_ips = ARRAY_SIZE(addresses_A_1),
2912 .ips = addresses_A_1,
2913 .apply_expected = false
2918 * sgroup,active vs. group,tombstone
2919 * => should NOT be replaced
2922 .line = __location__,
2923 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2924 .r1 = {
2925 .owner = &ctx->a,
2926 .type = WREPL_TYPE_SGROUP,
2927 .state = WREPL_STATE_ACTIVE,
2928 .node = WREPL_NODE_B,
2929 .is_static = false,
2930 .num_ips = ARRAY_SIZE(addresses_A_1),
2931 .ips = addresses_A_1,
2932 .apply_expected = true
2934 .r2 = {
2935 .owner = &ctx->b,
2936 .type = WREPL_TYPE_GROUP,
2937 .state = WREPL_STATE_TOMBSTONE,
2938 .node = WREPL_NODE_B,
2939 .is_static = false,
2940 .num_ips = ARRAY_SIZE(addresses_A_1),
2941 .ips = addresses_A_1,
2942 .apply_expected = false
2947 * sgroup,released vs. group,active
2948 * => should be replaced
2951 .line = __location__,
2952 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2953 .r1 = {
2954 .owner = &ctx->a,
2955 .type = WREPL_TYPE_SGROUP,
2956 .state = WREPL_STATE_RELEASED,
2957 .node = WREPL_NODE_B,
2958 .is_static = false,
2959 .num_ips = ARRAY_SIZE(addresses_A_1),
2960 .ips = addresses_A_1,
2961 .apply_expected = false
2963 .r2 = {
2964 .owner = &ctx->b,
2965 .type = WREPL_TYPE_GROUP,
2966 .state = WREPL_STATE_ACTIVE,
2967 .node = WREPL_NODE_B,
2968 .is_static = false,
2969 .num_ips = ARRAY_SIZE(addresses_B_1),
2970 .ips = addresses_B_1,
2971 .apply_expected = true
2976 * sgroup,released vs. group,tombstone
2977 * => should be replaced
2980 .line = __location__,
2981 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2982 .r1 = {
2983 .owner = &ctx->b,
2984 .type = WREPL_TYPE_SGROUP,
2985 .state = WREPL_STATE_RELEASED,
2986 .node = WREPL_NODE_B,
2987 .is_static = false,
2988 .num_ips = ARRAY_SIZE(addresses_B_1),
2989 .ips = addresses_B_1,
2990 .apply_expected = false
2992 .r2 = {
2993 .owner = &ctx->a,
2994 .type = WREPL_TYPE_GROUP,
2995 .state = WREPL_STATE_TOMBSTONE,
2996 .node = WREPL_NODE_B,
2997 .is_static = false,
2998 .num_ips = ARRAY_SIZE(addresses_A_1),
2999 .ips = addresses_A_1,
3000 .apply_expected = true
3005 * sgroup,tombstone vs. group,active
3006 * => should NOT be replaced
3009 .line = __location__,
3010 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3011 .r1 = {
3012 .owner = &ctx->a,
3013 .type = WREPL_TYPE_SGROUP,
3014 .state = WREPL_STATE_TOMBSTONE,
3015 .node = WREPL_NODE_B,
3016 .is_static = false,
3017 .num_ips = ARRAY_SIZE(addresses_A_1),
3018 .ips = addresses_A_1,
3019 .apply_expected = true
3021 .r2 = {
3022 .owner = &ctx->b,
3023 .type = WREPL_TYPE_GROUP,
3024 .state = WREPL_STATE_ACTIVE,
3025 .node = WREPL_NODE_B,
3026 .is_static = false,
3027 .num_ips = ARRAY_SIZE(addresses_B_1),
3028 .ips = addresses_B_1,
3029 .apply_expected = true
3034 * sgroup,tombstone vs. group,tombstone
3035 * => should NOT be replaced
3038 .line = __location__,
3039 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3040 .r1 = {
3041 .owner = &ctx->b,
3042 .type = WREPL_TYPE_SGROUP,
3043 .state = WREPL_STATE_TOMBSTONE,
3044 .node = WREPL_NODE_B,
3045 .is_static = false,
3046 .num_ips = ARRAY_SIZE(addresses_B_1),
3047 .ips = addresses_B_1,
3048 .apply_expected = true
3050 .r2 = {
3051 .owner = &ctx->a,
3052 .type = WREPL_TYPE_GROUP,
3053 .state = WREPL_STATE_TOMBSTONE,
3054 .node = WREPL_NODE_B,
3055 .is_static = false,
3056 .num_ips = ARRAY_SIZE(addresses_A_1),
3057 .ips = addresses_A_1,
3058 .apply_expected = true
3063 * special groups (not active) vs special group section,
3066 * sgroup,released vs. sgroup,active
3067 * => should be replaced
3070 .line = __location__,
3071 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3072 .r1 = {
3073 .owner = &ctx->a,
3074 .type = WREPL_TYPE_SGROUP,
3075 .state = WREPL_STATE_RELEASED,
3076 .node = WREPL_NODE_B,
3077 .is_static = false,
3078 .num_ips = ARRAY_SIZE(addresses_A_1),
3079 .ips = addresses_A_1,
3080 .apply_expected = false
3082 .r2 = {
3083 .owner = &ctx->b,
3084 .type = WREPL_TYPE_SGROUP,
3085 .state = WREPL_STATE_ACTIVE,
3086 .node = WREPL_NODE_B,
3087 .is_static = false,
3088 .num_ips = ARRAY_SIZE(addresses_B_1),
3089 .ips = addresses_B_1,
3090 .apply_expected = true
3095 * sgroup,released vs. sgroup,tombstone
3096 * => should be replaced
3099 .line = __location__,
3100 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3101 .r1 = {
3102 .owner = &ctx->b,
3103 .type = WREPL_TYPE_SGROUP,
3104 .state = WREPL_STATE_RELEASED,
3105 .node = WREPL_NODE_B,
3106 .is_static = false,
3107 .num_ips = ARRAY_SIZE(addresses_B_1),
3108 .ips = addresses_B_1,
3109 .apply_expected = false
3111 .r2 = {
3112 .owner = &ctx->a,
3113 .type = WREPL_TYPE_SGROUP,
3114 .state = WREPL_STATE_TOMBSTONE,
3115 .node = WREPL_NODE_B,
3116 .is_static = false,
3117 .num_ips = ARRAY_SIZE(addresses_A_1),
3118 .ips = addresses_A_1,
3119 .apply_expected = true
3124 * sgroup,tombstone vs. sgroup,active
3125 * => should NOT be replaced
3128 .line = __location__,
3129 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3130 .r1 = {
3131 .owner = &ctx->a,
3132 .type = WREPL_TYPE_SGROUP,
3133 .state = WREPL_STATE_TOMBSTONE,
3134 .node = WREPL_NODE_B,
3135 .is_static = false,
3136 .num_ips = ARRAY_SIZE(addresses_A_1),
3137 .ips = addresses_A_1,
3138 .apply_expected = true
3140 .r2 = {
3141 .owner = &ctx->b,
3142 .type = WREPL_TYPE_SGROUP,
3143 .state = WREPL_STATE_ACTIVE,
3144 .node = WREPL_NODE_B,
3145 .is_static = false,
3146 .num_ips = ARRAY_SIZE(addresses_B_1),
3147 .ips = addresses_B_1,
3148 .apply_expected = true
3153 * sgroup,tombstone vs. sgroup,tombstone
3154 * => should NOT be replaced
3157 .line = __location__,
3158 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3159 .r1 = {
3160 .owner = &ctx->b,
3161 .type = WREPL_TYPE_SGROUP,
3162 .state = WREPL_STATE_TOMBSTONE,
3163 .node = WREPL_NODE_B,
3164 .is_static = false,
3165 .num_ips = ARRAY_SIZE(addresses_B_1),
3166 .ips = addresses_B_1,
3167 .apply_expected = true
3169 .r2 = {
3170 .owner = &ctx->a,
3171 .type = WREPL_TYPE_SGROUP,
3172 .state = WREPL_STATE_TOMBSTONE,
3173 .node = WREPL_NODE_B,
3174 .is_static = false,
3175 .num_ips = ARRAY_SIZE(addresses_A_1),
3176 .ips = addresses_A_1,
3177 .apply_expected = true
3182 * special groups vs multi homed section,
3185 * sgroup,active vs. mhomed,active
3186 * => should NOT be replaced
3189 .line = __location__,
3190 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3191 .r1 = {
3192 .owner = &ctx->a,
3193 .type = WREPL_TYPE_SGROUP,
3194 .state = WREPL_STATE_ACTIVE,
3195 .node = WREPL_NODE_B,
3196 .is_static = false,
3197 .num_ips = ARRAY_SIZE(addresses_A_1),
3198 .ips = addresses_A_1,
3199 .apply_expected = true
3201 .r2 = {
3202 .owner = &ctx->b,
3203 .type = WREPL_TYPE_MHOMED,
3204 .state = WREPL_STATE_ACTIVE,
3205 .node = WREPL_NODE_B,
3206 .is_static = false,
3207 .num_ips = ARRAY_SIZE(addresses_A_1),
3208 .ips = addresses_A_1,
3209 .apply_expected = false
3214 * sgroup,active vs. mhomed,tombstone
3215 * => should NOT be replaced
3218 .line = __location__,
3219 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3220 .r1 = {
3221 .owner = &ctx->a,
3222 .type = WREPL_TYPE_SGROUP,
3223 .state = WREPL_STATE_ACTIVE,
3224 .node = WREPL_NODE_B,
3225 .is_static = false,
3226 .num_ips = ARRAY_SIZE(addresses_A_1),
3227 .ips = addresses_A_1,
3228 .apply_expected = true
3230 .r2 = {
3231 .owner = &ctx->b,
3232 .type = WREPL_TYPE_MHOMED,
3233 .state = WREPL_STATE_TOMBSTONE,
3234 .node = WREPL_NODE_B,
3235 .is_static = false,
3236 .num_ips = ARRAY_SIZE(addresses_A_1),
3237 .ips = addresses_A_1,
3238 .apply_expected = false
3243 * sgroup,released vs. mhomed,active
3244 * => should be replaced
3247 .line = __location__,
3248 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3249 .r1 = {
3250 .owner = &ctx->a,
3251 .type = WREPL_TYPE_SGROUP,
3252 .state = WREPL_STATE_RELEASED,
3253 .node = WREPL_NODE_B,
3254 .is_static = false,
3255 .num_ips = ARRAY_SIZE(addresses_A_1),
3256 .ips = addresses_A_1,
3257 .apply_expected = false
3259 .r2 = {
3260 .owner = &ctx->b,
3261 .type = WREPL_TYPE_MHOMED,
3262 .state = WREPL_STATE_ACTIVE,
3263 .node = WREPL_NODE_B,
3264 .is_static = false,
3265 .num_ips = ARRAY_SIZE(addresses_B_1),
3266 .ips = addresses_B_1,
3267 .apply_expected = true
3272 * sgroup,released vs. mhomed,tombstone
3273 * => should be replaced
3276 .line = __location__,
3277 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3278 .r1 = {
3279 .owner = &ctx->b,
3280 .type = WREPL_TYPE_SGROUP,
3281 .state = WREPL_STATE_RELEASED,
3282 .node = WREPL_NODE_B,
3283 .is_static = false,
3284 .num_ips = ARRAY_SIZE(addresses_B_1),
3285 .ips = addresses_B_1,
3286 .apply_expected = false
3288 .r2 = {
3289 .owner = &ctx->a,
3290 .type = WREPL_TYPE_MHOMED,
3291 .state = WREPL_STATE_TOMBSTONE,
3292 .node = WREPL_NODE_B,
3293 .is_static = false,
3294 .num_ips = ARRAY_SIZE(addresses_A_1),
3295 .ips = addresses_A_1,
3296 .apply_expected = true
3301 * sgroup,tombstone vs. mhomed,active
3302 * => should be replaced
3305 .line = __location__,
3306 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3307 .r1 = {
3308 .owner = &ctx->a,
3309 .type = WREPL_TYPE_SGROUP,
3310 .state = WREPL_STATE_TOMBSTONE,
3311 .node = WREPL_NODE_B,
3312 .is_static = false,
3313 .num_ips = ARRAY_SIZE(addresses_A_1),
3314 .ips = addresses_A_1,
3315 .apply_expected = true
3317 .r2 = {
3318 .owner = &ctx->b,
3319 .type = WREPL_TYPE_MHOMED,
3320 .state = WREPL_STATE_ACTIVE,
3321 .node = WREPL_NODE_B,
3322 .is_static = false,
3323 .num_ips = ARRAY_SIZE(addresses_B_1),
3324 .ips = addresses_B_1,
3325 .apply_expected = true
3330 * sgroup,tombstone vs. mhomed,tombstone
3331 * => should be replaced
3334 .line = __location__,
3335 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3336 .r1 = {
3337 .owner = &ctx->b,
3338 .type = WREPL_TYPE_SGROUP,
3339 .state = WREPL_STATE_TOMBSTONE,
3340 .node = WREPL_NODE_B,
3341 .is_static = false,
3342 .num_ips = ARRAY_SIZE(addresses_B_1),
3343 .ips = addresses_B_1,
3344 .apply_expected = true
3346 .r2 = {
3347 .owner = &ctx->a,
3348 .type = WREPL_TYPE_MHOMED,
3349 .state = WREPL_STATE_TOMBSTONE,
3350 .node = WREPL_NODE_B,
3351 .is_static = false,
3352 .num_ips = ARRAY_SIZE(addresses_A_1),
3353 .ips = addresses_A_1,
3354 .apply_expected = true
3359 * multi homed vs. unique section,
3362 * mhomed,active vs. unique,active
3363 * => should be replaced
3366 .line = __location__,
3367 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3368 .r1 = {
3369 .owner = &ctx->a,
3370 .type = WREPL_TYPE_MHOMED,
3371 .state = WREPL_STATE_ACTIVE,
3372 .node = WREPL_NODE_B,
3373 .is_static = false,
3374 .num_ips = ARRAY_SIZE(addresses_A_3_4),
3375 .ips = addresses_A_3_4,
3376 .apply_expected = true
3378 .r2 = {
3379 .owner = &ctx->b,
3380 .type = WREPL_TYPE_UNIQUE,
3381 .state = WREPL_STATE_ACTIVE,
3382 .node = WREPL_NODE_B,
3383 .is_static = false,
3384 .num_ips = ARRAY_SIZE(addresses_B_1),
3385 .ips = addresses_B_1,
3386 .apply_expected = true
3391 * mhomed,active vs. unique,tombstone
3392 * => should NOT be replaced
3395 .line = __location__,
3396 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3397 .r1 = {
3398 .owner = &ctx->b,
3399 .type = WREPL_TYPE_MHOMED,
3400 .state = WREPL_STATE_ACTIVE,
3401 .node = WREPL_NODE_B,
3402 .is_static = false,
3403 .num_ips = ARRAY_SIZE(addresses_B_1),
3404 .ips = addresses_B_1,
3405 .apply_expected = true
3407 .r2 = {
3408 .owner = &ctx->a,
3409 .type = WREPL_TYPE_UNIQUE,
3410 .state = WREPL_STATE_TOMBSTONE,
3411 .node = WREPL_NODE_B,
3412 .is_static = false,
3413 .num_ips = ARRAY_SIZE(addresses_B_1),
3414 .ips = addresses_B_1,
3415 .apply_expected = false
3420 * mhomed,released vs. unique,active
3421 * => should be replaced
3424 .line = __location__,
3425 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3426 .r1 = {
3427 .owner = &ctx->a,
3428 .type = WREPL_TYPE_MHOMED,
3429 .state = WREPL_STATE_RELEASED,
3430 .node = WREPL_NODE_B,
3431 .is_static = false,
3432 .num_ips = ARRAY_SIZE(addresses_A_1),
3433 .ips = addresses_A_1,
3434 .apply_expected = false
3436 .r2 = {
3437 .owner = &ctx->b,
3438 .type = WREPL_TYPE_UNIQUE,
3439 .state = WREPL_STATE_ACTIVE,
3440 .node = WREPL_NODE_B,
3441 .is_static = false,
3442 .num_ips = ARRAY_SIZE(addresses_B_1),
3443 .ips = addresses_B_1,
3444 .apply_expected = true
3449 * mhomed,released vs. uinique,tombstone
3450 * => should be replaced
3453 .line = __location__,
3454 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3455 .r1 = {
3456 .owner = &ctx->b,
3457 .type = WREPL_TYPE_MHOMED,
3458 .state = WREPL_STATE_RELEASED,
3459 .node = WREPL_NODE_B,
3460 .is_static = false,
3461 .num_ips = ARRAY_SIZE(addresses_B_1),
3462 .ips = addresses_B_1,
3463 .apply_expected = false
3465 .r2 = {
3466 .owner = &ctx->a,
3467 .type = WREPL_TYPE_UNIQUE,
3468 .state = WREPL_STATE_TOMBSTONE,
3469 .node = WREPL_NODE_B,
3470 .is_static = false,
3471 .num_ips = ARRAY_SIZE(addresses_A_1),
3472 .ips = addresses_A_1,
3473 .apply_expected = true
3478 * mhomed,tombstone vs. unique,active
3479 * => should be replaced
3482 .line = __location__,
3483 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3484 .r1 = {
3485 .owner = &ctx->a,
3486 .type = WREPL_TYPE_MHOMED,
3487 .state = WREPL_STATE_TOMBSTONE,
3488 .node = WREPL_NODE_B,
3489 .is_static = false,
3490 .num_ips = ARRAY_SIZE(addresses_A_1),
3491 .ips = addresses_A_1,
3492 .apply_expected = true
3494 .r2 = {
3495 .owner = &ctx->b,
3496 .type = WREPL_TYPE_UNIQUE,
3497 .state = WREPL_STATE_ACTIVE,
3498 .node = WREPL_NODE_B,
3499 .is_static = false,
3500 .num_ips = ARRAY_SIZE(addresses_B_1),
3501 .ips = addresses_B_1,
3502 .apply_expected = true
3507 * mhomed,tombstone vs. uinique,tombstone
3508 * => should be replaced
3511 .line = __location__,
3512 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3513 .r1 = {
3514 .owner = &ctx->b,
3515 .type = WREPL_TYPE_MHOMED,
3516 .state = WREPL_STATE_TOMBSTONE,
3517 .node = WREPL_NODE_B,
3518 .is_static = false,
3519 .num_ips = ARRAY_SIZE(addresses_B_1),
3520 .ips = addresses_B_1,
3521 .apply_expected = true
3523 .r2 = {
3524 .owner = &ctx->a,
3525 .type = WREPL_TYPE_UNIQUE,
3526 .state = WREPL_STATE_TOMBSTONE,
3527 .node = WREPL_NODE_B,
3528 .is_static = false,
3529 .num_ips = ARRAY_SIZE(addresses_A_1),
3530 .ips = addresses_A_1,
3531 .apply_expected = true
3536 * multi homed vs. normal group section,
3539 * mhomed,active vs. group,active
3540 * => should be replaced
3543 .line = __location__,
3544 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3545 .r1 = {
3546 .owner = &ctx->a,
3547 .type = WREPL_TYPE_MHOMED,
3548 .state = WREPL_STATE_ACTIVE,
3549 .node = WREPL_NODE_B,
3550 .is_static = false,
3551 .num_ips = ARRAY_SIZE(addresses_A_1),
3552 .ips = addresses_A_1,
3553 .apply_expected = true
3555 .r2 = {
3556 .owner = &ctx->b,
3557 .type = WREPL_TYPE_GROUP,
3558 .state = WREPL_STATE_ACTIVE,
3559 .node = WREPL_NODE_B,
3560 .is_static = false,
3561 .num_ips = ARRAY_SIZE(addresses_B_1),
3562 .ips = addresses_B_1,
3563 .apply_expected = true
3568 * mhomed,active vs. group,tombstone
3569 * => should NOT be replaced
3572 .line = __location__,
3573 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3574 .r1 = {
3575 .owner = &ctx->b,
3576 .type = WREPL_TYPE_MHOMED,
3577 .state = WREPL_STATE_ACTIVE,
3578 .node = WREPL_NODE_B,
3579 .is_static = false,
3580 .num_ips = ARRAY_SIZE(addresses_B_1),
3581 .ips = addresses_B_1,
3582 .apply_expected = true
3584 .r2 = {
3585 .owner = &ctx->a,
3586 .type = WREPL_TYPE_GROUP,
3587 .state = WREPL_STATE_TOMBSTONE,
3588 .node = WREPL_NODE_B,
3589 .is_static = false,
3590 .num_ips = ARRAY_SIZE(addresses_B_1),
3591 .ips = addresses_B_1,
3592 .apply_expected = false
3597 * mhomed,released vs. group,active
3598 * => should be replaced
3601 .line = __location__,
3602 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3603 .r1 = {
3604 .owner = &ctx->b,
3605 .type = WREPL_TYPE_MHOMED,
3606 .state = WREPL_STATE_RELEASED,
3607 .node = WREPL_NODE_B,
3608 .is_static = false,
3609 .num_ips = ARRAY_SIZE(addresses_B_1),
3610 .ips = addresses_B_1,
3611 .apply_expected = false
3613 .r2 = {
3614 .owner = &ctx->a,
3615 .type = WREPL_TYPE_GROUP,
3616 .state = WREPL_STATE_ACTIVE,
3617 .node = WREPL_NODE_B,
3618 .is_static = false,
3619 .num_ips = ARRAY_SIZE(addresses_A_1),
3620 .ips = addresses_A_1,
3621 .apply_expected = true
3626 * mhomed,released vs. group,tombstone
3627 * => should be replaced
3630 .line = __location__,
3631 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3632 .r1 = {
3633 .owner = &ctx->a,
3634 .type = WREPL_TYPE_MHOMED,
3635 .state = WREPL_STATE_RELEASED,
3636 .node = WREPL_NODE_B,
3637 .is_static = false,
3638 .num_ips = ARRAY_SIZE(addresses_A_1),
3639 .ips = addresses_A_1,
3640 .apply_expected = false
3642 .r2 = {
3643 .owner = &ctx->b,
3644 .type = WREPL_TYPE_GROUP,
3645 .state = WREPL_STATE_TOMBSTONE,
3646 .node = WREPL_NODE_B,
3647 .is_static = false,
3648 .num_ips = ARRAY_SIZE(addresses_B_1),
3649 .ips = addresses_B_1,
3650 .apply_expected = true
3655 * mhomed,tombstone vs. group,active
3656 * => should be replaced
3659 .line = __location__,
3660 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3661 .r1 = {
3662 .owner = &ctx->b,
3663 .type = WREPL_TYPE_MHOMED,
3664 .state = WREPL_STATE_TOMBSTONE,
3665 .node = WREPL_NODE_B,
3666 .is_static = false,
3667 .num_ips = ARRAY_SIZE(addresses_B_1),
3668 .ips = addresses_B_1,
3669 .apply_expected = true
3671 .r2 = {
3672 .owner = &ctx->a,
3673 .type = WREPL_TYPE_GROUP,
3674 .state = WREPL_STATE_ACTIVE,
3675 .node = WREPL_NODE_B,
3676 .is_static = false,
3677 .num_ips = ARRAY_SIZE(addresses_A_1),
3678 .ips = addresses_A_1,
3679 .apply_expected = true
3684 * mhomed,tombstone vs. group,tombstone
3685 * => should be replaced
3688 .line = __location__,
3689 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3690 .r1 = {
3691 .owner = &ctx->a,
3692 .type = WREPL_TYPE_MHOMED,
3693 .state = WREPL_STATE_TOMBSTONE,
3694 .node = WREPL_NODE_B,
3695 .is_static = false,
3696 .num_ips = ARRAY_SIZE(addresses_A_1),
3697 .ips = addresses_A_1,
3698 .apply_expected = true
3700 .r2 = {
3701 .owner = &ctx->b,
3702 .type = WREPL_TYPE_GROUP,
3703 .state = WREPL_STATE_TOMBSTONE,
3704 .node = WREPL_NODE_B,
3705 .is_static = false,
3706 .num_ips = ARRAY_SIZE(addresses_B_1),
3707 .ips = addresses_B_1,
3708 .apply_expected = true
3713 * multi homed vs. special group section,
3716 * mhomed,active vs. sgroup,active
3717 * => should NOT be replaced
3720 .line = __location__,
3721 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3722 .r1 = {
3723 .owner = &ctx->a,
3724 .type = WREPL_TYPE_MHOMED,
3725 .state = WREPL_STATE_ACTIVE,
3726 .node = WREPL_NODE_B,
3727 .is_static = false,
3728 .num_ips = ARRAY_SIZE(addresses_A_1),
3729 .ips = addresses_A_1,
3730 .apply_expected = true
3732 .r2 = {
3733 .owner = &ctx->b,
3734 .type = WREPL_TYPE_SGROUP,
3735 .state = WREPL_STATE_ACTIVE,
3736 .node = WREPL_NODE_B,
3737 .is_static = false,
3738 .num_ips = ARRAY_SIZE(addresses_A_1),
3739 .ips = addresses_A_1,
3740 .apply_expected = false
3745 * mhomed,active vs. sgroup,tombstone
3746 * => should NOT be replaced
3749 .line = __location__,
3750 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3751 .r1 = {
3752 .owner = &ctx->a,
3753 .type = WREPL_TYPE_MHOMED,
3754 .state = WREPL_STATE_ACTIVE,
3755 .node = WREPL_NODE_B,
3756 .is_static = false,
3757 .num_ips = ARRAY_SIZE(addresses_A_1),
3758 .ips = addresses_A_1,
3759 .apply_expected = true
3761 .r2 = {
3762 .owner = &ctx->b,
3763 .type = WREPL_TYPE_SGROUP,
3764 .state = WREPL_STATE_TOMBSTONE,
3765 .node = WREPL_NODE_B,
3766 .is_static = false,
3767 .num_ips = ARRAY_SIZE(addresses_A_1),
3768 .ips = addresses_A_1,
3769 .apply_expected = false
3774 * mhomed,released vs. sgroup,active
3775 * => should be replaced
3778 .line = __location__,
3779 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3780 .r1 = {
3781 .owner = &ctx->a,
3782 .type = WREPL_TYPE_MHOMED,
3783 .state = WREPL_STATE_RELEASED,
3784 .node = WREPL_NODE_B,
3785 .is_static = false,
3786 .num_ips = ARRAY_SIZE(addresses_A_1),
3787 .ips = addresses_A_1,
3788 .apply_expected = false
3790 .r2 = {
3791 .owner = &ctx->b,
3792 .type = WREPL_TYPE_SGROUP,
3793 .state = WREPL_STATE_ACTIVE,
3794 .node = WREPL_NODE_B,
3795 .is_static = false,
3796 .num_ips = ARRAY_SIZE(addresses_B_1),
3797 .ips = addresses_B_1,
3798 .apply_expected = true
3803 * mhomed,released vs. sgroup,tombstone
3804 * => should be replaced
3807 .line = __location__,
3808 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3809 .r1 = {
3810 .owner = &ctx->b,
3811 .type = WREPL_TYPE_MHOMED,
3812 .state = WREPL_STATE_RELEASED,
3813 .node = WREPL_NODE_B,
3814 .is_static = false,
3815 .num_ips = ARRAY_SIZE(addresses_B_1),
3816 .ips = addresses_B_1,
3817 .apply_expected = false
3819 .r2 = {
3820 .owner = &ctx->a,
3821 .type = WREPL_TYPE_SGROUP,
3822 .state = WREPL_STATE_TOMBSTONE,
3823 .node = WREPL_NODE_B,
3824 .is_static = false,
3825 .num_ips = ARRAY_SIZE(addresses_A_1),
3826 .ips = addresses_A_1,
3827 .apply_expected = true
3832 * mhomed,tombstone vs. sgroup,active
3833 * => should be replaced
3836 .line = __location__,
3837 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3838 .r1 = {
3839 .owner = &ctx->a,
3840 .type = WREPL_TYPE_MHOMED,
3841 .state = WREPL_STATE_TOMBSTONE,
3842 .node = WREPL_NODE_B,
3843 .is_static = false,
3844 .num_ips = ARRAY_SIZE(addresses_A_1),
3845 .ips = addresses_A_1,
3846 .apply_expected = true
3848 .r2 = {
3849 .owner = &ctx->b,
3850 .type = WREPL_TYPE_SGROUP,
3851 .state = WREPL_STATE_ACTIVE,
3852 .node = WREPL_NODE_B,
3853 .is_static = false,
3854 .num_ips = ARRAY_SIZE(addresses_B_1),
3855 .ips = addresses_B_1,
3856 .apply_expected = true
3861 * mhomed,tombstone vs. sgroup,tombstone
3862 * => should be replaced
3865 .line = __location__,
3866 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3867 .r1 = {
3868 .owner = &ctx->b,
3869 .type = WREPL_TYPE_MHOMED,
3870 .state = WREPL_STATE_TOMBSTONE,
3871 .node = WREPL_NODE_B,
3872 .is_static = false,
3873 .num_ips = ARRAY_SIZE(addresses_B_1),
3874 .ips = addresses_B_1,
3875 .apply_expected = true
3877 .r2 = {
3878 .owner = &ctx->a,
3879 .type = WREPL_TYPE_SGROUP,
3880 .state = WREPL_STATE_TOMBSTONE,
3881 .node = WREPL_NODE_B,
3882 .is_static = false,
3883 .num_ips = ARRAY_SIZE(addresses_A_1),
3884 .ips = addresses_A_1,
3885 .apply_expected = true
3890 * multi homed vs. mlti homed section,
3893 * mhomed,active vs. mhomed,active
3894 * => should be replaced
3897 .line = __location__,
3898 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3899 .r1 = {
3900 .owner = &ctx->a,
3901 .type = WREPL_TYPE_MHOMED,
3902 .state = WREPL_STATE_ACTIVE,
3903 .node = WREPL_NODE_B,
3904 .is_static = false,
3905 .num_ips = ARRAY_SIZE(addresses_A_3_4),
3906 .ips = addresses_A_3_4,
3907 .apply_expected = true
3909 .r2 = {
3910 .owner = &ctx->b,
3911 .type = WREPL_TYPE_MHOMED,
3912 .state = WREPL_STATE_ACTIVE,
3913 .node = WREPL_NODE_B,
3914 .is_static = false,
3915 .num_ips = ARRAY_SIZE(addresses_B_3_4),
3916 .ips = addresses_B_3_4,
3917 .apply_expected = true
3922 * mhomed,active vs. mhomed,tombstone
3923 * => should NOT be replaced
3926 .line = __location__,
3927 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3928 .r1 = {
3929 .owner = &ctx->b,
3930 .type = WREPL_TYPE_MHOMED,
3931 .state = WREPL_STATE_ACTIVE,
3932 .node = WREPL_NODE_B,
3933 .is_static = false,
3934 .num_ips = ARRAY_SIZE(addresses_B_3_4),
3935 .ips = addresses_B_3_4,
3936 .apply_expected = true
3938 .r2 = {
3939 .owner = &ctx->a,
3940 .type = WREPL_TYPE_MHOMED,
3941 .state = WREPL_STATE_TOMBSTONE,
3942 .node = WREPL_NODE_B,
3943 .is_static = false,
3944 .num_ips = ARRAY_SIZE(addresses_B_3_4),
3945 .ips = addresses_B_3_4,
3946 .apply_expected = false
3951 * mhomed,released vs. mhomed,active
3952 * => should be replaced
3955 .line = __location__,
3956 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3957 .r1 = {
3958 .owner = &ctx->b,
3959 .type = WREPL_TYPE_MHOMED,
3960 .state = WREPL_STATE_RELEASED,
3961 .node = WREPL_NODE_B,
3962 .is_static = false,
3963 .num_ips = ARRAY_SIZE(addresses_B_3_4),
3964 .ips = addresses_B_3_4,
3965 .apply_expected = false
3967 .r2 = {
3968 .owner = &ctx->a,
3969 .type = WREPL_TYPE_MHOMED,
3970 .state = WREPL_STATE_ACTIVE,
3971 .node = WREPL_NODE_B,
3972 .is_static = false,
3973 .num_ips = ARRAY_SIZE(addresses_A_3_4),
3974 .ips = addresses_A_3_4,
3975 .apply_expected = true
3980 * mhomed,released vs. mhomed,tombstone
3981 * => should be replaced
3984 .line = __location__,
3985 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3986 .r1 = {
3987 .owner = &ctx->a,
3988 .type = WREPL_TYPE_MHOMED,
3989 .state = WREPL_STATE_RELEASED,
3990 .node = WREPL_NODE_B,
3991 .is_static = false,
3992 .num_ips = ARRAY_SIZE(addresses_A_3_4),
3993 .ips = addresses_A_3_4,
3994 .apply_expected = false
3996 .r2 = {
3997 .owner = &ctx->b,
3998 .type = WREPL_TYPE_MHOMED,
3999 .state = WREPL_STATE_TOMBSTONE,
4000 .node = WREPL_NODE_B,
4001 .is_static = false,
4002 .num_ips = ARRAY_SIZE(addresses_B_3_4),
4003 .ips = addresses_B_3_4,
4004 .apply_expected = true
4009 * mhomed,tombstone vs. mhomed,active
4010 * => should be replaced
4013 .line = __location__,
4014 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4015 .r1 = {
4016 .owner = &ctx->b,
4017 .type = WREPL_TYPE_MHOMED,
4018 .state = WREPL_STATE_TOMBSTONE,
4019 .node = WREPL_NODE_B,
4020 .is_static = false,
4021 .num_ips = ARRAY_SIZE(addresses_B_3_4),
4022 .ips = addresses_B_3_4,
4023 .apply_expected = true
4025 .r2 = {
4026 .owner = &ctx->a,
4027 .type = WREPL_TYPE_MHOMED,
4028 .state = WREPL_STATE_ACTIVE,
4029 .node = WREPL_NODE_B,
4030 .is_static = false,
4031 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4032 .ips = addresses_A_3_4,
4033 .apply_expected = true
4038 * mhomed,tombstone vs. mhomed,tombstone
4039 * => should be replaced
4042 .line = __location__,
4043 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4044 .r1 = {
4045 .owner = &ctx->a,
4046 .type = WREPL_TYPE_MHOMED,
4047 .state = WREPL_STATE_TOMBSTONE,
4048 .node = WREPL_NODE_B,
4049 .is_static = false,
4050 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4051 .ips = addresses_A_3_4,
4052 .apply_expected = true
4054 .r2 = {
4055 .owner = &ctx->b,
4056 .type = WREPL_TYPE_MHOMED,
4057 .state = WREPL_STATE_TOMBSTONE,
4058 .node = WREPL_NODE_B,
4059 .is_static = false,
4060 .num_ips = ARRAY_SIZE(addresses_B_3_4),
4061 .ips = addresses_B_3_4,
4062 .apply_expected = true
4066 .line = __location__,
4067 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4068 .cleanup= true,
4069 .r1 = {
4070 .owner = &ctx->b,
4071 .type = WREPL_TYPE_UNIQUE,
4072 .state = WREPL_STATE_TOMBSTONE,
4073 .node = WREPL_NODE_B,
4074 .is_static = false,
4075 .num_ips = ARRAY_SIZE(addresses_B_1),
4076 .ips = addresses_B_1,
4077 .apply_expected = true,
4079 .r2 = {
4080 .owner = &ctx->a,
4081 .type = WREPL_TYPE_UNIQUE,
4082 .state = WREPL_STATE_TOMBSTONE,
4083 .node = WREPL_NODE_B,
4084 .is_static = false,
4085 .num_ips = ARRAY_SIZE(addresses_A_1),
4086 .ips = addresses_A_1,
4087 .apply_expected = true,
4091 * special group vs special group section,
4094 * sgroup,active vs. sgroup,active same addresses
4095 * => should be NOT replaced
4098 .line = __location__,
4099 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4100 .comment= "A:A_3_4 vs. B:A_3_4",
4101 .extra = true,
4102 .r1 = {
4103 .owner = &ctx->a,
4104 .type = WREPL_TYPE_SGROUP,
4105 .state = WREPL_STATE_ACTIVE,
4106 .node = WREPL_NODE_B,
4107 .is_static = false,
4108 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4109 .ips = addresses_A_3_4,
4110 .apply_expected = true
4112 .r2 = {
4113 .owner = &ctx->b,
4114 .type = WREPL_TYPE_SGROUP,
4115 .state = WREPL_STATE_ACTIVE,
4116 .node = WREPL_NODE_B,
4117 .is_static = false,
4118 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4119 .ips = addresses_A_3_4,
4120 .apply_expected = false,
4121 .sgroup_cleanup = true
4125 * sgroup,active vs. sgroup,active same addresses
4126 * => should be NOT replaced
4129 .line = __location__,
4130 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4131 .comment= "A:A_3_4 vs. B:NULL",
4132 .extra = true,
4133 .r1 = {
4134 .owner = &ctx->a,
4135 .type = WREPL_TYPE_SGROUP,
4136 .state = WREPL_STATE_ACTIVE,
4137 .node = WREPL_NODE_B,
4138 .is_static = false,
4139 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4140 .ips = addresses_A_3_4,
4141 .apply_expected = true
4143 .r2 = {
4144 .owner = &ctx->b,
4145 .type = WREPL_TYPE_SGROUP,
4146 .state = WREPL_STATE_ACTIVE,
4147 .node = WREPL_NODE_B,
4148 .is_static = false,
4149 .num_ips = 0,
4150 .ips = NULL,
4151 .apply_expected = false,
4152 .sgroup_cleanup = true
4156 * sgroup,active vs. sgroup,active subset addresses, special case...
4157 * => should NOT be replaced
4160 .line = __location__,
4161 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4162 .comment= "A:A_3_4_X_3_4 vs. B:A_3_4",
4163 .extra = true,
4164 .r1 = {
4165 .owner = &ctx->a,
4166 .type = WREPL_TYPE_SGROUP,
4167 .state = WREPL_STATE_ACTIVE,
4168 .node = WREPL_NODE_B,
4169 .is_static = false,
4170 .num_ips = ARRAY_SIZE(addresses_A_3_4_X_3_4),
4171 .ips = addresses_A_3_4_X_3_4,
4172 .apply_expected = true,
4174 .r2 = {
4175 .owner = &ctx->b,
4176 .type = WREPL_TYPE_SGROUP,
4177 .state = WREPL_STATE_ACTIVE,
4178 .node = WREPL_NODE_B,
4179 .is_static = false,
4180 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4181 .ips = addresses_A_3_4,
4182 .apply_expected = false,
4186 .line = __location__,
4187 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4188 .cleanup= true,
4189 .r1 = {
4190 .owner = &ctx->a,
4191 .type = WREPL_TYPE_SGROUP,
4192 .state = WREPL_STATE_ACTIVE,
4193 .node = WREPL_NODE_B,
4194 .is_static = false,
4195 .num_ips = 0,
4196 .ips = NULL,
4197 .apply_expected = false,
4199 .r2 = {
4200 .owner = &ctx->x,
4201 .type = WREPL_TYPE_SGROUP,
4202 .state = WREPL_STATE_ACTIVE,
4203 .node = WREPL_NODE_B,
4204 .is_static = false,
4205 .num_ips = 0,
4206 .ips = NULL,
4207 .apply_expected = false,
4211 * sgroup,active vs. sgroup,active different addresses, but owner changed
4212 * => should be replaced
4215 .line = __location__,
4216 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4217 .comment= "A:B_3_4 vs. B:A_3_4",
4218 .extra = true,
4219 .r1 = {
4220 .owner = &ctx->a,
4221 .type = WREPL_TYPE_SGROUP,
4222 .state = WREPL_STATE_ACTIVE,
4223 .node = WREPL_NODE_B,
4224 .is_static = false,
4225 .num_ips = ARRAY_SIZE(addresses_B_3_4),
4226 .ips = addresses_B_3_4,
4227 .apply_expected = true,
4229 .r2 = {
4230 .owner = &ctx->b,
4231 .type = WREPL_TYPE_SGROUP,
4232 .state = WREPL_STATE_ACTIVE,
4233 .node = WREPL_NODE_B,
4234 .is_static = false,
4235 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4236 .ips = addresses_A_3_4,
4237 .apply_expected = true,
4238 .sgroup_cleanup = true
4242 * sgroup,active vs. sgroup,active different addresses, but owner changed
4243 * => should be replaced
4246 .line = __location__,
4247 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4248 .comment= "A:A_3_4 vs. B:A_3_4_OWNER_B",
4249 .extra = true,
4250 .r1 = {
4251 .owner = &ctx->a,
4252 .type = WREPL_TYPE_SGROUP,
4253 .state = WREPL_STATE_ACTIVE,
4254 .node = WREPL_NODE_B,
4255 .is_static = false,
4256 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4257 .ips = addresses_A_3_4,
4258 .apply_expected = true,
4260 .r2 = {
4261 .owner = &ctx->b,
4262 .type = WREPL_TYPE_SGROUP,
4263 .state = WREPL_STATE_ACTIVE,
4264 .node = WREPL_NODE_B,
4265 .is_static = false,
4266 .num_ips = ARRAY_SIZE(addresses_A_3_4_OWNER_B),
4267 .ips = addresses_A_3_4_OWNER_B,
4268 .apply_expected = true,
4269 .sgroup_cleanup = true
4273 * sgroup,active vs. sgroup,active different addresses, but owner changed
4274 * => should be replaced
4277 .line = __location__,
4278 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4279 .comment= "A:A_3_4_OWNER_B vs. B:A_3_4",
4280 .extra = true,
4281 .r1 = {
4282 .owner = &ctx->a,
4283 .type = WREPL_TYPE_SGROUP,
4284 .state = WREPL_STATE_ACTIVE,
4285 .node = WREPL_NODE_B,
4286 .is_static = false,
4287 .num_ips = ARRAY_SIZE(addresses_A_3_4_OWNER_B),
4288 .ips = addresses_A_3_4_OWNER_B,
4289 .apply_expected = true,
4291 .r2 = {
4292 .owner = &ctx->b,
4293 .type = WREPL_TYPE_SGROUP,
4294 .state = WREPL_STATE_ACTIVE,
4295 .node = WREPL_NODE_B,
4296 .is_static = false,
4297 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4298 .ips = addresses_A_3_4,
4299 .apply_expected = true,
4300 .sgroup_cleanup = true
4304 * sgroup,active vs. sgroup,active different addresses
4305 * => should be merged
4308 .line = __location__,
4309 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4310 .comment= "A:A_3_4 vs. B:B_3_4 => C:A_3_4_B_3_4",
4311 .extra = true,
4312 .r1 = {
4313 .owner = &ctx->a,
4314 .type = WREPL_TYPE_SGROUP,
4315 .state = WREPL_STATE_ACTIVE,
4316 .node = WREPL_NODE_B,
4317 .is_static = false,
4318 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4319 .ips = addresses_A_3_4,
4320 .apply_expected = true,
4322 .r2 = {
4323 .owner = &ctx->b,
4324 .type = WREPL_TYPE_SGROUP,
4325 .state = WREPL_STATE_ACTIVE,
4326 .node = WREPL_NODE_B,
4327 .is_static = false,
4328 .num_ips = ARRAY_SIZE(addresses_B_3_4),
4329 .ips = addresses_B_3_4,
4330 .sgroup_merge = true,
4331 .sgroup_cleanup = true,
4335 * sgroup,active vs. sgroup,active different addresses, special case...
4336 * => should be merged
4339 .line = __location__,
4340 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4341 .comment= "A:B_3_4_X_3_4 vs. B:A_3_4 => B:A_3_4_X_3_4",
4342 .extra = true,
4343 .r1 = {
4344 .owner = &ctx->a,
4345 .type = WREPL_TYPE_SGROUP,
4346 .state = WREPL_STATE_ACTIVE,
4347 .node = WREPL_NODE_B,
4348 .is_static = false,
4349 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4350 .ips = addresses_B_3_4_X_3_4,
4351 .apply_expected = true,
4353 .r2 = {
4354 .owner = &ctx->b,
4355 .type = WREPL_TYPE_SGROUP,
4356 .state = WREPL_STATE_ACTIVE,
4357 .node = WREPL_NODE_B,
4358 .is_static = false,
4359 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4360 .ips = addresses_A_3_4,
4361 .sgroup_merge = true,
4362 .merge_owner = &ctx->b,
4363 .sgroup_cleanup = false
4367 .line = __location__,
4368 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4369 .cleanup= true,
4370 .r1 = {
4371 .owner = &ctx->b,
4372 .type = WREPL_TYPE_SGROUP,
4373 .state = WREPL_STATE_ACTIVE,
4374 .node = WREPL_NODE_B,
4375 .is_static = false,
4376 .num_ips = ARRAY_SIZE(addresses_A_3_4_X_3_4_OWNER_B),
4377 .ips = addresses_A_3_4_X_3_4_OWNER_B,
4378 .apply_expected = true,
4380 .r2 = {
4381 .owner = &ctx->b,
4382 .type = WREPL_TYPE_SGROUP,
4383 .state = WREPL_STATE_ACTIVE,
4384 .node = WREPL_NODE_B,
4385 .is_static = false,
4386 .num_ips = 0,
4387 .ips = NULL,
4388 .apply_expected = false,
4392 * sgroup,active vs. sgroup,active different addresses, special case...
4393 * => should be merged
4396 .line = __location__,
4397 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4398 .comment= "A:X_3_4 vs. B:A_3_4 => C:A_3_4_X_3_4",
4399 .extra = true,
4400 .r1 = {
4401 .owner = &ctx->a,
4402 .type = WREPL_TYPE_SGROUP,
4403 .state = WREPL_STATE_ACTIVE,
4404 .node = WREPL_NODE_B,
4405 .is_static = false,
4406 .num_ips = ARRAY_SIZE(addresses_X_3_4),
4407 .ips = addresses_X_3_4,
4408 .apply_expected = true,
4410 .r2 = {
4411 .owner = &ctx->b,
4412 .type = WREPL_TYPE_SGROUP,
4413 .state = WREPL_STATE_ACTIVE,
4414 .node = WREPL_NODE_B,
4415 .is_static = false,
4416 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4417 .ips = addresses_A_3_4,
4418 .sgroup_merge = true,
4419 .sgroup_cleanup = false
4423 .line = __location__,
4424 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4425 .cleanup= true,
4426 .r1 = {
4427 .owner = &ctx->a,
4428 .type = WREPL_TYPE_SGROUP,
4429 .state = WREPL_STATE_ACTIVE,
4430 .node = WREPL_NODE_B,
4431 .is_static = false,
4432 .num_ips = 0,
4433 .ips = NULL,
4434 .apply_expected = false,
4436 .r2 = {
4437 .owner = &ctx->x,
4438 .type = WREPL_TYPE_SGROUP,
4439 .state = WREPL_STATE_ACTIVE,
4440 .node = WREPL_NODE_B,
4441 .is_static = false,
4442 .num_ips = 0,
4443 .ips = NULL,
4444 .apply_expected = false,
4448 * sgroup,active vs. sgroup,active different addresses, special case...
4449 * => should be merged
4452 .line = __location__,
4453 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4454 .comment= "A:A_3_4_X_3_4 vs. B:A_3_4_OWNER_B => B:A_3_4_OWNER_B_X_3_4",
4455 .extra = true,
4456 .r1 = {
4457 .owner = &ctx->a,
4458 .type = WREPL_TYPE_SGROUP,
4459 .state = WREPL_STATE_ACTIVE,
4460 .node = WREPL_NODE_B,
4461 .is_static = false,
4462 .num_ips = ARRAY_SIZE(addresses_A_3_4_X_3_4),
4463 .ips = addresses_A_3_4_X_3_4,
4464 .apply_expected = true,
4466 .r2 = {
4467 .owner = &ctx->b,
4468 .type = WREPL_TYPE_SGROUP,
4469 .state = WREPL_STATE_ACTIVE,
4470 .node = WREPL_NODE_B,
4471 .is_static = false,
4472 .num_ips = ARRAY_SIZE(addresses_A_3_4_OWNER_B),
4473 .ips = addresses_A_3_4_OWNER_B,
4474 .sgroup_merge = true,
4475 .merge_owner = &ctx->b,
4479 .line = __location__,
4480 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4481 .cleanup= true,
4482 .r1 = {
4483 .owner = &ctx->b,
4484 .type = WREPL_TYPE_SGROUP,
4485 .state = WREPL_STATE_ACTIVE,
4486 .node = WREPL_NODE_B,
4487 .is_static = false,
4488 .num_ips = 0,
4489 .ips = NULL,
4490 .apply_expected = false,
4492 .r2 = {
4493 .owner = &ctx->x,
4494 .type = WREPL_TYPE_SGROUP,
4495 .state = WREPL_STATE_ACTIVE,
4496 .node = WREPL_NODE_B,
4497 .is_static = false,
4498 .num_ips = 0,
4499 .ips = NULL,
4500 .apply_expected = false,
4504 * sgroup,active vs. sgroup,active partly different addresses, special case...
4505 * => should be merged
4508 .line = __location__,
4509 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4510 .comment= "A:B_3_4_X_3_4 vs. B:B_3_4_X_1_2 => C:B_3_4_X_1_2_3_4",
4511 .extra = true,
4512 .r1 = {
4513 .owner = &ctx->a,
4514 .type = WREPL_TYPE_SGROUP,
4515 .state = WREPL_STATE_ACTIVE,
4516 .node = WREPL_NODE_B,
4517 .is_static = false,
4518 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4519 .ips = addresses_B_3_4_X_3_4,
4520 .apply_expected = true,
4522 .r2 = {
4523 .owner = &ctx->b,
4524 .type = WREPL_TYPE_SGROUP,
4525 .state = WREPL_STATE_ACTIVE,
4526 .node = WREPL_NODE_B,
4527 .is_static = false,
4528 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_1_2),
4529 .ips = addresses_B_3_4_X_1_2,
4530 .sgroup_merge = true,
4531 .sgroup_cleanup = false
4535 .line = __location__,
4536 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4537 .cleanup= true,
4538 .r1 = {
4539 .owner = &ctx->b,
4540 .type = WREPL_TYPE_SGROUP,
4541 .state = WREPL_STATE_ACTIVE,
4542 .node = WREPL_NODE_B,
4543 .is_static = false,
4544 .num_ips = 0,
4545 .ips = NULL,
4546 .apply_expected = false,
4548 .r2 = {
4549 .owner = &ctx->x,
4550 .type = WREPL_TYPE_SGROUP,
4551 .state = WREPL_STATE_ACTIVE,
4552 .node = WREPL_NODE_B,
4553 .is_static = false,
4554 .num_ips = 0,
4555 .ips = NULL,
4556 .apply_expected = false,
4560 * sgroup,active vs. sgroup,active different addresses, special case...
4561 * => should be merged
4564 .line = __location__,
4565 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4566 .comment= "A:A_3_4_B_3_4 vs. B:NULL => B:A_3_4",
4567 .extra = true,
4568 .r1 = {
4569 .owner = &ctx->a,
4570 .type = WREPL_TYPE_SGROUP,
4571 .state = WREPL_STATE_ACTIVE,
4572 .node = WREPL_NODE_B,
4573 .is_static = false,
4574 .num_ips = ARRAY_SIZE(addresses_A_3_4_B_3_4),
4575 .ips = addresses_A_3_4_B_3_4,
4576 .apply_expected = true,
4578 .r2 = {
4579 .owner = &ctx->b,
4580 .type = WREPL_TYPE_SGROUP,
4581 .state = WREPL_STATE_ACTIVE,
4582 .node = WREPL_NODE_B,
4583 .is_static = false,
4584 .num_ips = 0,
4585 .ips = NULL,
4586 .sgroup_merge = true,
4587 .merge_owner = &ctx->b,
4588 .sgroup_cleanup = true
4592 .line = __location__,
4593 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4594 .cleanup= true,
4595 .r1 = {
4596 .owner = &ctx->a,
4597 .type = WREPL_TYPE_SGROUP,
4598 .state = WREPL_STATE_ACTIVE,
4599 .node = WREPL_NODE_B,
4600 .is_static = false,
4601 .num_ips = 0,
4602 .ips = NULL,
4603 .apply_expected = false,
4605 .r2 = {
4606 .owner = &ctx->a,
4607 .type = WREPL_TYPE_UNIQUE,
4608 .state = WREPL_STATE_TOMBSTONE,
4609 .node = WREPL_NODE_B,
4610 .is_static = false,
4611 .num_ips = ARRAY_SIZE(addresses_A_1),
4612 .ips = addresses_A_1,
4613 .apply_expected = true,
4617 * sgroup,active vs. sgroup,active different addresses, special case...
4618 * => should be merged
4621 .line = __location__,
4622 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4623 .comment= "A:B_3_4_X_3_4 vs. B:NULL => B:X_3_4",
4624 .extra = true,
4625 .r1 = {
4626 .owner = &ctx->a,
4627 .type = WREPL_TYPE_SGROUP,
4628 .state = WREPL_STATE_ACTIVE,
4629 .node = WREPL_NODE_B,
4630 .is_static = false,
4631 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4632 .ips = addresses_B_3_4_X_3_4,
4633 .apply_expected = true,
4635 .r2 = {
4636 .owner = &ctx->b,
4637 .type = WREPL_TYPE_SGROUP,
4638 .state = WREPL_STATE_ACTIVE,
4639 .node = WREPL_NODE_B,
4640 .is_static = false,
4641 .num_ips = 0,
4642 .ips = NULL,
4643 .sgroup_merge = true,
4644 .merge_owner = &ctx->b,
4645 .sgroup_cleanup = true
4649 .line = __location__,
4650 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4651 .cleanup= true,
4652 .r1 = {
4653 .owner = &ctx->x,
4654 .type = WREPL_TYPE_SGROUP,
4655 .state = WREPL_STATE_ACTIVE,
4656 .node = WREPL_NODE_B,
4657 .is_static = false,
4658 .num_ips = 0,
4659 .ips = NULL,
4660 .apply_expected = false,
4662 .r2 = {
4663 .owner = &ctx->x,
4664 .type = WREPL_TYPE_UNIQUE,
4665 .state = WREPL_STATE_TOMBSTONE,
4666 .node = WREPL_NODE_B,
4667 .is_static = false,
4668 .num_ips = ARRAY_SIZE(addresses_A_1),
4669 .ips = addresses_A_1,
4670 .apply_expected = true,
4675 * sgroup,active vs. sgroup,tombstone different no addresses, special
4676 * => should be replaced
4679 .line = __location__,
4680 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4681 .comment= "A:B_3_4_X_3_4 vs. B:NULL => B:NULL",
4682 .extra = true,
4683 .r1 = {
4684 .owner = &ctx->a,
4685 .type = WREPL_TYPE_SGROUP,
4686 .state = WREPL_STATE_ACTIVE,
4687 .node = WREPL_NODE_B,
4688 .is_static = false,
4689 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4690 .ips = addresses_B_3_4_X_3_4,
4691 .apply_expected = true,
4693 .r2 = {
4694 .owner = &ctx->b,
4695 .type = WREPL_TYPE_SGROUP,
4696 .state = WREPL_STATE_TOMBSTONE,
4697 .node = WREPL_NODE_B,
4698 .is_static = false,
4699 .num_ips = 0,
4700 .ips = NULL,
4701 .apply_expected = true,
4705 * sgroup,active vs. sgroup,tombstone different addresses
4706 * => should be replaced
4709 .line = __location__,
4710 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4711 .comment= "A:B_3_4_X_3_4 vs. B:A_3_4 => B:A_3_4",
4712 .extra = true,
4713 .r1 = {
4714 .owner = &ctx->a,
4715 .type = WREPL_TYPE_SGROUP,
4716 .state = WREPL_STATE_ACTIVE,
4717 .node = WREPL_NODE_B,
4718 .is_static = false,
4719 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4720 .ips = addresses_B_3_4_X_3_4,
4721 .apply_expected = true,
4723 .r2 = {
4724 .owner = &ctx->b,
4725 .type = WREPL_TYPE_SGROUP,
4726 .state = WREPL_STATE_TOMBSTONE,
4727 .node = WREPL_NODE_B,
4728 .is_static = false,
4729 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4730 .ips = addresses_A_3_4,
4731 .apply_expected = true,
4735 * sgroup,active vs. sgroup,tombstone subset addresses
4736 * => should be replaced
4739 .line = __location__,
4740 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4741 .comment= "A:B_3_4_X_3_4 vs. B:B_3_4 => B:B_3_4",
4742 .extra = true,
4743 .r1 = {
4744 .owner = &ctx->a,
4745 .type = WREPL_TYPE_SGROUP,
4746 .state = WREPL_STATE_ACTIVE,
4747 .node = WREPL_NODE_B,
4748 .is_static = false,
4749 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4750 .ips = addresses_B_3_4_X_3_4,
4751 .apply_expected = true,
4753 .r2 = {
4754 .owner = &ctx->b,
4755 .type = WREPL_TYPE_SGROUP,
4756 .state = WREPL_STATE_TOMBSTONE,
4757 .node = WREPL_NODE_B,
4758 .is_static = false,
4759 .num_ips = ARRAY_SIZE(addresses_B_3_4),
4760 .ips = addresses_B_3_4,
4761 .apply_expected = true,
4765 * sgroup,active vs. sgroup,active same addresses
4766 * => should be replaced
4769 .line = __location__,
4770 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4771 .comment= "A:B_3_4_X_3_4 vs. B:B_3_4_X_3_4 => B:B_3_4_X_3_4",
4772 .extra = true,
4773 .r1 = {
4774 .owner = &ctx->a,
4775 .type = WREPL_TYPE_SGROUP,
4776 .state = WREPL_STATE_ACTIVE,
4777 .node = WREPL_NODE_B,
4778 .is_static = false,
4779 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4780 .ips = addresses_B_3_4_X_3_4,
4781 .apply_expected = true,
4783 .r2 = {
4784 .owner = &ctx->b,
4785 .type = WREPL_TYPE_SGROUP,
4786 .state = WREPL_STATE_TOMBSTONE,
4787 .node = WREPL_NODE_B,
4788 .is_static = false,
4789 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4790 .ips = addresses_B_3_4_X_3_4,
4791 .apply_expected = true,
4796 * This should be the last record in this array,
4797 * we need to make sure the we leave a tombstoned unique entry
4798 * owned by OWNER_A
4801 .line = __location__,
4802 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4803 .cleanup= true,
4804 .r1 = {
4805 .owner = &ctx->a,
4806 .type = WREPL_TYPE_UNIQUE,
4807 .state = WREPL_STATE_TOMBSTONE,
4808 .node = WREPL_NODE_B,
4809 .is_static = false,
4810 .num_ips = ARRAY_SIZE(addresses_A_1),
4811 .ips = addresses_A_1,
4812 .apply_expected = true
4814 .r2 = {
4815 .owner = &ctx->a,
4816 .type = WREPL_TYPE_UNIQUE,
4817 .state = WREPL_STATE_TOMBSTONE,
4818 .node = WREPL_NODE_B,
4819 .is_static = false,
4820 .num_ips = ARRAY_SIZE(addresses_A_1),
4821 .ips = addresses_A_1,
4822 .apply_expected = true
4824 }}; /* do not add entries here, this should be the last record! */
4826 wins_name_r1 = &wins_name1;
4827 wins_name_r2 = &wins_name2;
4829 torture_comment(tctx, "Test Replica Conflicts with different owners\n");
4831 for(i=0; ret && i < ARRAY_SIZE(records); i++) {
4833 if (!records[i].extra && !records[i].cleanup) {
4834 /* we should test the worst cases */
4835 if (records[i].r2.apply_expected && records[i].r1.ips==records[i].r2.ips) {
4836 torture_comment(tctx, "(%s) Programmer error, invalid record[%u]: %s\n",
4837 __location__, i, records[i].line);
4838 return false;
4839 } else if (!records[i].r2.apply_expected && records[i].r1.ips!=records[i].r2.ips) {
4840 torture_comment(tctx, "(%s) Programmer error, invalid record[%u]: %s\n",
4841 __location__, i, records[i].line);
4842 return false;
4846 if (!records[i].cleanup) {
4847 const char *expected;
4848 const char *ips;
4850 if (records[i].r2.sgroup_merge) {
4851 expected = "SGROUP_MERGE";
4852 } else if (records[i].r2.apply_expected) {
4853 expected = "REPLACE";
4854 } else {
4855 expected = "NOT REPLACE";
4858 if (!records[i].r1.ips && !records[i].r2.ips) {
4859 ips = "with no ip(s)";
4860 } else if (records[i].r1.ips==records[i].r2.ips) {
4861 ips = "with same ip(s)";
4862 } else {
4863 ips = "with different ip(s)";
4866 torture_comment(tctx, "%s,%s%s vs. %s,%s%s %s => %s\n",
4867 wrepl_name_type_string(records[i].r1.type),
4868 wrepl_name_state_string(records[i].r1.state),
4869 (records[i].r1.is_static?",static":""),
4870 wrepl_name_type_string(records[i].r2.type),
4871 wrepl_name_state_string(records[i].r2.state),
4872 (records[i].r2.is_static?",static":""),
4873 (records[i].comment?records[i].comment:ips),
4874 expected);
4878 * Setup R1
4880 wins_name_r1->name = &records[i].name;
4881 wins_name_r1->flags = WREPL_NAME_FLAGS(records[i].r1.type,
4882 records[i].r1.state,
4883 records[i].r1.node,
4884 records[i].r1.is_static);
4885 wins_name_r1->id = ++records[i].r1.owner->max_version;
4886 if (wins_name_r1->flags & 2) {
4887 wins_name_r1->addresses.addresses.num_ips = records[i].r1.num_ips;
4888 wins_name_r1->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
4889 records[i].r1.ips);
4890 } else {
4891 wins_name_r1->addresses.ip = records[i].r1.ips[0].ip;
4893 wins_name_r1->unknown = "255.255.255.255";
4895 /* now apply R1 */
4896 ret &= test_wrepl_update_one(tctx, ctx, records[i].r1.owner, wins_name_r1);
4897 ret &= test_wrepl_is_applied(tctx, ctx, records[i].r1.owner,
4898 wins_name_r1, records[i].r1.apply_expected);
4901 * Setup R2
4903 wins_name_r2->name = &records[i].name;
4904 wins_name_r2->flags = WREPL_NAME_FLAGS(records[i].r2.type,
4905 records[i].r2.state,
4906 records[i].r2.node,
4907 records[i].r2.is_static);
4908 wins_name_r2->id = ++records[i].r2.owner->max_version;
4909 if (wins_name_r2->flags & 2) {
4910 wins_name_r2->addresses.addresses.num_ips = records[i].r2.num_ips;
4911 wins_name_r2->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
4912 records[i].r2.ips);
4913 } else {
4914 wins_name_r2->addresses.ip = records[i].r2.ips[0].ip;
4916 wins_name_r2->unknown = "255.255.255.255";
4918 /* now apply R2 */
4919 ret &= test_wrepl_update_one(tctx, ctx, records[i].r2.owner, wins_name_r2);
4920 if (records[i].r1.state == WREPL_STATE_RELEASED) {
4921 ret &= test_wrepl_is_applied(tctx, ctx, records[i].r1.owner,
4922 wins_name_r1, false);
4923 } else if (records[i].r2.sgroup_merge) {
4924 ret &= test_wrepl_sgroup_merged(tctx, ctx, records[i].r2.merge_owner,
4925 records[i].r1.owner,
4926 records[i].r1.num_ips, records[i].r1.ips,
4927 records[i].r2.owner,
4928 records[i].r2.num_ips, records[i].r2.ips,
4929 wins_name_r2);
4930 } else if (records[i].r1.owner != records[i].r2.owner) {
4931 bool _expected;
4932 _expected = (records[i].r1.apply_expected && !records[i].r2.apply_expected);
4933 ret &= test_wrepl_is_applied(tctx, ctx, records[i].r1.owner,
4934 wins_name_r1, _expected);
4936 if (records[i].r2.state == WREPL_STATE_RELEASED) {
4937 ret &= test_wrepl_is_applied(tctx, ctx, records[i].r2.owner,
4938 wins_name_r2, false);
4939 } else if (!records[i].r2.sgroup_merge) {
4940 ret &= test_wrepl_is_applied(tctx, ctx, records[i].r2.owner,
4941 wins_name_r2, records[i].r2.apply_expected);
4944 if (records[i].r2.sgroup_cleanup) {
4945 if (!ret) {
4946 torture_comment(tctx, "failed before sgroup_cleanup record[%u]: %s\n", i, records[i].line);
4947 return ret;
4950 /* clean up the SGROUP record */
4951 wins_name_r1->name = &records[i].name;
4952 wins_name_r1->flags = WREPL_NAME_FLAGS(WREPL_TYPE_SGROUP,
4953 WREPL_STATE_ACTIVE,
4954 WREPL_NODE_B, false);
4955 wins_name_r1->id = ++records[i].r1.owner->max_version;
4956 wins_name_r1->addresses.addresses.num_ips = 0;
4957 wins_name_r1->addresses.addresses.ips = NULL;
4958 wins_name_r1->unknown = "255.255.255.255";
4959 ret &= test_wrepl_update_one(tctx, ctx, records[i].r1.owner, wins_name_r1);
4961 /* here we test how names from an owner are deleted */
4962 if (records[i].r2.sgroup_merge && records[i].r2.num_ips) {
4963 ret &= test_wrepl_sgroup_merged(tctx, ctx, NULL,
4964 records[i].r2.owner,
4965 records[i].r2.num_ips, records[i].r2.ips,
4966 records[i].r1.owner,
4967 0, NULL,
4968 wins_name_r2);
4971 /* clean up the SGROUP record */
4972 wins_name_r2->name = &records[i].name;
4973 wins_name_r2->flags = WREPL_NAME_FLAGS(WREPL_TYPE_SGROUP,
4974 WREPL_STATE_ACTIVE,
4975 WREPL_NODE_B, false);
4976 wins_name_r2->id = ++records[i].r2.owner->max_version;
4977 wins_name_r2->addresses.addresses.num_ips = 0;
4978 wins_name_r2->addresses.addresses.ips = NULL;
4979 wins_name_r2->unknown = "255.255.255.255";
4980 ret &= test_wrepl_update_one(tctx, ctx, records[i].r2.owner, wins_name_r2);
4982 /* take ownership of the SGROUP record */
4983 wins_name_r2->name = &records[i].name;
4984 wins_name_r2->flags = WREPL_NAME_FLAGS(WREPL_TYPE_SGROUP,
4985 WREPL_STATE_ACTIVE,
4986 WREPL_NODE_B, false);
4987 wins_name_r2->id = ++records[i].r2.owner->max_version;
4988 wins_name_r2->addresses.addresses.num_ips = ARRAY_SIZE(addresses_B_1);
4989 wins_name_r2->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
4990 addresses_B_1);
4991 wins_name_r2->unknown = "255.255.255.255";
4992 ret &= test_wrepl_update_one(tctx, ctx, records[i].r2.owner, wins_name_r2);
4993 ret &= test_wrepl_is_applied(tctx, ctx, records[i].r2.owner, wins_name_r2, true);
4995 /* overwrite the SGROUP record with unique,tombstone */
4996 wins_name_r2->name = &records[i].name;
4997 wins_name_r2->flags = WREPL_NAME_FLAGS(WREPL_TYPE_SGROUP,
4998 WREPL_STATE_TOMBSTONE,
4999 WREPL_NODE_B, false);
5000 wins_name_r2->id = ++records[i].r2.owner->max_version;
5001 wins_name_r2->addresses.addresses.num_ips = ARRAY_SIZE(addresses_B_1);
5002 wins_name_r2->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
5003 addresses_B_1);
5004 wins_name_r2->unknown = "255.255.255.255";
5005 ret &= test_wrepl_update_one(tctx, ctx, records[i].r2.owner, wins_name_r2);
5006 ret &= test_wrepl_is_applied(tctx, ctx, records[i].r2.owner, wins_name_r2, true);
5008 if (!ret) {
5009 torture_comment(tctx, "failed in sgroup_cleanup record[%u]: %s\n", i, records[i].line);
5010 return ret;
5014 /* the first one is a cleanup run */
5015 if (!ret && i == 0) ret = true;
5017 if (!ret) {
5018 torture_comment(tctx, "conflict handled wrong or record[%u]: %s\n", i, records[i].line);
5019 return ret;
5023 return ret;
5026 static bool test_conflict_owned_released_vs_replica(struct torture_context *tctx,
5027 struct test_wrepl_conflict_conn *ctx)
5029 bool ret = true;
5030 NTSTATUS status;
5031 struct wrepl_wins_name wins_name_;
5032 struct wrepl_wins_name *wins_name = &wins_name_;
5033 struct nbt_name_register name_register_;
5034 struct nbt_name_register *name_register = &name_register_;
5035 struct nbt_name_release release_;
5036 struct nbt_name_release *release = &release_;
5037 uint32_t i;
5038 struct {
5039 const char *line; /* just better debugging */
5040 struct nbt_name name;
5041 struct {
5042 uint32_t nb_flags;
5043 bool mhomed;
5044 uint32_t num_ips;
5045 const struct wrepl_ip *ips;
5046 bool apply_expected;
5047 } wins;
5048 struct {
5049 enum wrepl_name_type type;
5050 enum wrepl_name_state state;
5051 enum wrepl_name_node node;
5052 bool is_static;
5053 uint32_t num_ips;
5054 const struct wrepl_ip *ips;
5055 bool apply_expected;
5056 } replica;
5057 } records[] = {
5059 * unique vs. unique section
5062 * unique,released vs. unique,active with same ip(s)
5065 .line = __location__,
5066 .name = _NBT_NAME("_UR_UA_SI", 0x00, NULL),
5067 .wins = {
5068 .nb_flags = 0,
5069 .mhomed = false,
5070 .num_ips = ctx->addresses_best_num,
5071 .ips = ctx->addresses_best,
5072 .apply_expected = true
5074 .replica= {
5075 .type = WREPL_TYPE_UNIQUE,
5076 .state = WREPL_STATE_ACTIVE,
5077 .node = WREPL_NODE_B,
5078 .is_static = false,
5079 .num_ips = ctx->addresses_best_num,
5080 .ips = ctx->addresses_best,
5081 .apply_expected = true
5085 * unique,released vs. unique,active with different ip(s)
5088 .line = __location__,
5089 .name = _NBT_NAME("_UR_UA_DI", 0x00, NULL),
5090 .wins = {
5091 .nb_flags = 0,
5092 .mhomed = false,
5093 .num_ips = ctx->addresses_best_num,
5094 .ips = ctx->addresses_best,
5095 .apply_expected = true
5097 .replica= {
5098 .type = WREPL_TYPE_UNIQUE,
5099 .state = WREPL_STATE_ACTIVE,
5100 .node = WREPL_NODE_B,
5101 .is_static = false,
5102 .num_ips = ARRAY_SIZE(addresses_B_1),
5103 .ips = addresses_B_1,
5104 .apply_expected = true
5108 * unique,released vs. unique,tombstone with same ip(s)
5111 .line = __location__,
5112 .name = _NBT_NAME("_UR_UT_SI", 0x00, NULL),
5113 .wins = {
5114 .nb_flags = 0,
5115 .mhomed = false,
5116 .num_ips = ctx->addresses_best_num,
5117 .ips = ctx->addresses_best,
5118 .apply_expected = true
5120 .replica= {
5121 .type = WREPL_TYPE_UNIQUE,
5122 .state = WREPL_STATE_TOMBSTONE,
5123 .node = WREPL_NODE_B,
5124 .is_static = false,
5125 .num_ips = ctx->addresses_best_num,
5126 .ips = ctx->addresses_best,
5127 .apply_expected = true
5131 * unique,released vs. unique,tombstone with different ip(s)
5134 .line = __location__,
5135 .name = _NBT_NAME("_UR_UT_DI", 0x00, NULL),
5136 .wins = {
5137 .nb_flags = 0,
5138 .mhomed = false,
5139 .num_ips = ctx->addresses_best_num,
5140 .ips = ctx->addresses_best,
5141 .apply_expected = true
5143 .replica= {
5144 .type = WREPL_TYPE_UNIQUE,
5145 .state = WREPL_STATE_TOMBSTONE,
5146 .node = WREPL_NODE_B,
5147 .is_static = false,
5148 .num_ips = ARRAY_SIZE(addresses_B_1),
5149 .ips = addresses_B_1,
5150 .apply_expected = true
5154 * unique vs. group section
5157 * unique,released vs. group,active with same ip(s)
5160 .line = __location__,
5161 .name = _NBT_NAME("_UR_GA_SI", 0x00, NULL),
5162 .wins = {
5163 .nb_flags = 0,
5164 .mhomed = false,
5165 .num_ips = ctx->addresses_best_num,
5166 .ips = ctx->addresses_best,
5167 .apply_expected = true
5169 .replica= {
5170 .type = WREPL_TYPE_GROUP,
5171 .state = WREPL_STATE_ACTIVE,
5172 .node = WREPL_NODE_B,
5173 .is_static = false,
5174 .num_ips = ctx->addresses_best_num,
5175 .ips = ctx->addresses_best,
5176 .apply_expected = true
5180 * unique,released vs. group,active with different ip(s)
5183 .line = __location__,
5184 .name = _NBT_NAME("_UR_GA_DI", 0x00, NULL),
5185 .wins = {
5186 .nb_flags = 0,
5187 .mhomed = false,
5188 .num_ips = ctx->addresses_best_num,
5189 .ips = ctx->addresses_best,
5190 .apply_expected = true
5192 .replica= {
5193 .type = WREPL_TYPE_GROUP,
5194 .state = WREPL_STATE_ACTIVE,
5195 .node = WREPL_NODE_B,
5196 .is_static = false,
5197 .num_ips = ARRAY_SIZE(addresses_B_1),
5198 .ips = addresses_B_1,
5199 .apply_expected = true
5203 * unique,released vs. group,tombstone with same ip(s)
5206 .line = __location__,
5207 .name = _NBT_NAME("_UR_GT_SI", 0x00, NULL),
5208 .wins = {
5209 .nb_flags = 0,
5210 .mhomed = false,
5211 .num_ips = ctx->addresses_best_num,
5212 .ips = ctx->addresses_best,
5213 .apply_expected = true
5215 .replica= {
5216 .type = WREPL_TYPE_GROUP,
5217 .state = WREPL_STATE_TOMBSTONE,
5218 .node = WREPL_NODE_B,
5219 .is_static = false,
5220 .num_ips = ctx->addresses_best_num,
5221 .ips = ctx->addresses_best,
5222 .apply_expected = true
5226 * unique,released vs. group,tombstone with different ip(s)
5229 .line = __location__,
5230 .name = _NBT_NAME("_UR_GT_DI", 0x00, NULL),
5231 .wins = {
5232 .nb_flags = 0,
5233 .mhomed = false,
5234 .num_ips = ctx->addresses_best_num,
5235 .ips = ctx->addresses_best,
5236 .apply_expected = true
5238 .replica= {
5239 .type = WREPL_TYPE_GROUP,
5240 .state = WREPL_STATE_TOMBSTONE,
5241 .node = WREPL_NODE_B,
5242 .is_static = false,
5243 .num_ips = ARRAY_SIZE(addresses_B_1),
5244 .ips = addresses_B_1,
5245 .apply_expected = true
5249 * unique vs. special group section
5252 * unique,released vs. sgroup,active with same ip(s)
5255 .line = __location__,
5256 .name = _NBT_NAME("_UR_SA_SI", 0x00, NULL),
5257 .wins = {
5258 .nb_flags = 0,
5259 .mhomed = false,
5260 .num_ips = ctx->addresses_best_num,
5261 .ips = ctx->addresses_best,
5262 .apply_expected = true
5264 .replica= {
5265 .type = WREPL_TYPE_SGROUP,
5266 .state = WREPL_STATE_ACTIVE,
5267 .node = WREPL_NODE_B,
5268 .is_static = false,
5269 .num_ips = ctx->addresses_best_num,
5270 .ips = ctx->addresses_best,
5271 .apply_expected = true
5275 * unique,released vs. sgroup,active with different ip(s)
5278 .line = __location__,
5279 .name = _NBT_NAME("_UR_SA_DI", 0x00, NULL),
5280 .wins = {
5281 .nb_flags = 0,
5282 .mhomed = false,
5283 .num_ips = ctx->addresses_best_num,
5284 .ips = ctx->addresses_best,
5285 .apply_expected = true
5287 .replica= {
5288 .type = WREPL_TYPE_SGROUP,
5289 .state = WREPL_STATE_ACTIVE,
5290 .node = WREPL_NODE_B,
5291 .is_static = false,
5292 .num_ips = ARRAY_SIZE(addresses_B_1),
5293 .ips = addresses_B_1,
5294 .apply_expected = true
5298 * unique,released vs. sgroup,tombstone with same ip(s)
5301 .line = __location__,
5302 .name = _NBT_NAME("_UR_ST_SI", 0x00, NULL),
5303 .wins = {
5304 .nb_flags = 0,
5305 .mhomed = false,
5306 .num_ips = ctx->addresses_best_num,
5307 .ips = ctx->addresses_best,
5308 .apply_expected = true
5310 .replica= {
5311 .type = WREPL_TYPE_SGROUP,
5312 .state = WREPL_STATE_TOMBSTONE,
5313 .node = WREPL_NODE_B,
5314 .is_static = false,
5315 .num_ips = ctx->addresses_best_num,
5316 .ips = ctx->addresses_best,
5317 .apply_expected = true
5321 * unique,released vs. sgroup,tombstone with different ip(s)
5324 .line = __location__,
5325 .name = _NBT_NAME("_UR_ST_DI", 0x00, NULL),
5326 .wins = {
5327 .nb_flags = 0,
5328 .mhomed = false,
5329 .num_ips = ctx->addresses_best_num,
5330 .ips = ctx->addresses_best,
5331 .apply_expected = true
5333 .replica= {
5334 .type = WREPL_TYPE_SGROUP,
5335 .state = WREPL_STATE_TOMBSTONE,
5336 .node = WREPL_NODE_B,
5337 .is_static = false,
5338 .num_ips = ARRAY_SIZE(addresses_B_1),
5339 .ips = addresses_B_1,
5340 .apply_expected = true
5344 * unique vs. multi homed section
5347 * unique,released vs. mhomed,active with same ip(s)
5350 .line = __location__,
5351 .name = _NBT_NAME("_UR_MA_SI", 0x00, NULL),
5352 .wins = {
5353 .nb_flags = 0,
5354 .mhomed = false,
5355 .num_ips = ctx->addresses_best_num,
5356 .ips = ctx->addresses_best,
5357 .apply_expected = true
5359 .replica= {
5360 .type = WREPL_TYPE_MHOMED,
5361 .state = WREPL_STATE_ACTIVE,
5362 .node = WREPL_NODE_B,
5363 .is_static = false,
5364 .num_ips = ctx->addresses_best_num,
5365 .ips = ctx->addresses_best,
5366 .apply_expected = true
5370 * unique,released vs. mhomed,active with different ip(s)
5373 .line = __location__,
5374 .name = _NBT_NAME("_UR_MA_DI", 0x00, NULL),
5375 .wins = {
5376 .nb_flags = 0,
5377 .mhomed = false,
5378 .num_ips = ctx->addresses_best_num,
5379 .ips = ctx->addresses_best,
5380 .apply_expected = true
5382 .replica= {
5383 .type = WREPL_TYPE_MHOMED,
5384 .state = WREPL_STATE_ACTIVE,
5385 .node = WREPL_NODE_B,
5386 .is_static = false,
5387 .num_ips = ARRAY_SIZE(addresses_B_1),
5388 .ips = addresses_B_1,
5389 .apply_expected = true
5393 * unique,released vs. mhomed,tombstone with same ip(s)
5396 .line = __location__,
5397 .name = _NBT_NAME("_UR_MT_SI", 0x00, NULL),
5398 .wins = {
5399 .nb_flags = 0,
5400 .mhomed = false,
5401 .num_ips = ctx->addresses_best_num,
5402 .ips = ctx->addresses_best,
5403 .apply_expected = true
5405 .replica= {
5406 .type = WREPL_TYPE_MHOMED,
5407 .state = WREPL_STATE_TOMBSTONE,
5408 .node = WREPL_NODE_B,
5409 .is_static = false,
5410 .num_ips = ctx->addresses_best_num,
5411 .ips = ctx->addresses_best,
5412 .apply_expected = true
5416 * unique,released vs. mhomed,tombstone with different ip(s)
5419 .line = __location__,
5420 .name = _NBT_NAME("_UR_MT_DI", 0x00, NULL),
5421 .wins = {
5422 .nb_flags = 0,
5423 .mhomed = false,
5424 .num_ips = ctx->addresses_best_num,
5425 .ips = ctx->addresses_best,
5426 .apply_expected = true
5428 .replica= {
5429 .type = WREPL_TYPE_MHOMED,
5430 .state = WREPL_STATE_TOMBSTONE,
5431 .node = WREPL_NODE_B,
5432 .is_static = false,
5433 .num_ips = ARRAY_SIZE(addresses_B_1),
5434 .ips = addresses_B_1,
5435 .apply_expected = true
5439 * group vs. unique section
5442 * group,released vs. unique,active with same ip(s)
5445 .line = __location__,
5446 .name = _NBT_NAME("_GR_UA_SI", 0x00, NULL),
5447 .wins = {
5448 .nb_flags = NBT_NM_GROUP,
5449 .mhomed = false,
5450 .num_ips = ctx->addresses_best_num,
5451 .ips = ctx->addresses_best,
5452 .apply_expected = true
5454 .replica= {
5455 .type = WREPL_TYPE_UNIQUE,
5456 .state = WREPL_STATE_ACTIVE,
5457 .node = WREPL_NODE_B,
5458 .is_static = false,
5459 .num_ips = ctx->addresses_best_num,
5460 .ips = ctx->addresses_best,
5461 .apply_expected = false
5465 * group,released vs. unique,active with different ip(s)
5468 .line = __location__,
5469 .name = _NBT_NAME("_GR_UA_DI", 0x00, NULL),
5470 .wins = {
5471 .nb_flags = NBT_NM_GROUP,
5472 .mhomed = false,
5473 .num_ips = ctx->addresses_best_num,
5474 .ips = ctx->addresses_best,
5475 .apply_expected = true
5477 .replica= {
5478 .type = WREPL_TYPE_UNIQUE,
5479 .state = WREPL_STATE_ACTIVE,
5480 .node = WREPL_NODE_B,
5481 .is_static = false,
5482 .num_ips = ARRAY_SIZE(addresses_B_1),
5483 .ips = addresses_B_1,
5484 .apply_expected = false
5488 * group,released vs. unique,tombstone with same ip(s)
5491 .line = __location__,
5492 .name = _NBT_NAME("_GR_UT_SI", 0x00, NULL),
5493 .wins = {
5494 .nb_flags = NBT_NM_GROUP,
5495 .mhomed = false,
5496 .num_ips = ctx->addresses_best_num,
5497 .ips = ctx->addresses_best,
5498 .apply_expected = true
5500 .replica= {
5501 .type = WREPL_TYPE_UNIQUE,
5502 .state = WREPL_STATE_TOMBSTONE,
5503 .node = WREPL_NODE_B,
5504 .is_static = false,
5505 .num_ips = ctx->addresses_best_num,
5506 .ips = ctx->addresses_best,
5507 .apply_expected = false
5511 * group,released vs. unique,tombstone with different ip(s)
5514 .line = __location__,
5515 .name = _NBT_NAME("_GR_UT_DI", 0x00, NULL),
5516 .wins = {
5517 .nb_flags = NBT_NM_GROUP,
5518 .mhomed = false,
5519 .num_ips = ctx->addresses_best_num,
5520 .ips = ctx->addresses_best,
5521 .apply_expected = true
5523 .replica= {
5524 .type = WREPL_TYPE_UNIQUE,
5525 .state = WREPL_STATE_TOMBSTONE,
5526 .node = WREPL_NODE_B,
5527 .is_static = false,
5528 .num_ips = ARRAY_SIZE(addresses_B_1),
5529 .ips = addresses_B_1,
5530 .apply_expected = false
5534 * group vs. group section
5537 * group,released vs. group,active with same ip(s)
5540 .line = __location__,
5541 .name = _NBT_NAME("_GR_GA_SI", 0x00, NULL),
5542 .wins = {
5543 .nb_flags = NBT_NM_GROUP,
5544 .mhomed = false,
5545 .num_ips = ctx->addresses_best_num,
5546 .ips = ctx->addresses_best,
5547 .apply_expected = true
5549 .replica= {
5550 .type = WREPL_TYPE_GROUP,
5551 .state = WREPL_STATE_ACTIVE,
5552 .node = WREPL_NODE_B,
5553 .is_static = false,
5554 .num_ips = ctx->addresses_best_num,
5555 .ips = ctx->addresses_best,
5556 .apply_expected = true
5560 * group,released vs. group,active with different ip(s)
5563 .line = __location__,
5564 .name = _NBT_NAME("_GR_GA_DI", 0x00, NULL),
5565 .wins = {
5566 .nb_flags = NBT_NM_GROUP,
5567 .mhomed = false,
5568 .num_ips = ctx->addresses_best_num,
5569 .ips = ctx->addresses_best,
5570 .apply_expected = true
5572 .replica= {
5573 .type = WREPL_TYPE_GROUP,
5574 .state = WREPL_STATE_ACTIVE,
5575 .node = WREPL_NODE_B,
5576 .is_static = false,
5577 .num_ips = ARRAY_SIZE(addresses_B_1),
5578 .ips = addresses_B_1,
5579 .apply_expected = true
5583 * group,released vs. group,tombstone with same ip(s)
5586 .line = __location__,
5587 .name = _NBT_NAME("_GR_GT_SI", 0x00, NULL),
5588 .wins = {
5589 .nb_flags = NBT_NM_GROUP,
5590 .mhomed = false,
5591 .num_ips = ctx->addresses_best_num,
5592 .ips = ctx->addresses_best,
5593 .apply_expected = true
5595 .replica= {
5596 .type = WREPL_TYPE_GROUP,
5597 .state = WREPL_STATE_TOMBSTONE,
5598 .node = WREPL_NODE_B,
5599 .is_static = false,
5600 .num_ips = ctx->addresses_best_num,
5601 .ips = ctx->addresses_best,
5602 .apply_expected = true
5606 * group,released vs. group,tombstone with different ip(s)
5609 .line = __location__,
5610 .name = _NBT_NAME("_GR_GT_DI", 0x00, NULL),
5611 .wins = {
5612 .nb_flags = NBT_NM_GROUP,
5613 .mhomed = false,
5614 .num_ips = ctx->addresses_best_num,
5615 .ips = ctx->addresses_best,
5616 .apply_expected = true
5618 .replica= {
5619 .type = WREPL_TYPE_GROUP,
5620 .state = WREPL_STATE_TOMBSTONE,
5621 .node = WREPL_NODE_B,
5622 .is_static = false,
5623 .num_ips = ARRAY_SIZE(addresses_B_1),
5624 .ips = addresses_B_1,
5625 .apply_expected = true
5629 * group vs. special group section
5632 * group,released vs. sgroup,active with same ip(s)
5635 .line = __location__,
5636 .name = _NBT_NAME("_GR_SA_SI", 0x00, NULL),
5637 .wins = {
5638 .nb_flags = NBT_NM_GROUP,
5639 .mhomed = false,
5640 .num_ips = ctx->addresses_best_num,
5641 .ips = ctx->addresses_best,
5642 .apply_expected = true
5644 .replica= {
5645 .type = WREPL_TYPE_SGROUP,
5646 .state = WREPL_STATE_ACTIVE,
5647 .node = WREPL_NODE_B,
5648 .is_static = false,
5649 .num_ips = ctx->addresses_best_num,
5650 .ips = ctx->addresses_best,
5651 .apply_expected = false
5655 * group,released vs. sgroup,active with different ip(s)
5658 .line = __location__,
5659 .name = _NBT_NAME("_GR_SA_DI", 0x00, NULL),
5660 .wins = {
5661 .nb_flags = NBT_NM_GROUP,
5662 .mhomed = false,
5663 .num_ips = ctx->addresses_best_num,
5664 .ips = ctx->addresses_best,
5665 .apply_expected = true
5667 .replica= {
5668 .type = WREPL_TYPE_SGROUP,
5669 .state = WREPL_STATE_ACTIVE,
5670 .node = WREPL_NODE_B,
5671 .is_static = false,
5672 .num_ips = ARRAY_SIZE(addresses_B_1),
5673 .ips = addresses_B_1,
5674 .apply_expected = false
5678 * group,released vs. sgroup,tombstone with same ip(s)
5681 .line = __location__,
5682 .name = _NBT_NAME("_GR_ST_SI", 0x00, NULL),
5683 .wins = {
5684 .nb_flags = NBT_NM_GROUP,
5685 .mhomed = false,
5686 .num_ips = ctx->addresses_best_num,
5687 .ips = ctx->addresses_best,
5688 .apply_expected = true
5690 .replica= {
5691 .type = WREPL_TYPE_SGROUP,
5692 .state = WREPL_STATE_TOMBSTONE,
5693 .node = WREPL_NODE_B,
5694 .is_static = false,
5695 .num_ips = ctx->addresses_best_num,
5696 .ips = ctx->addresses_best,
5697 .apply_expected = false
5701 * group,released vs. sgroup,tombstone with different ip(s)
5704 .line = __location__,
5705 .name = _NBT_NAME("_GR_ST_DI", 0x00, NULL),
5706 .wins = {
5707 .nb_flags = NBT_NM_GROUP,
5708 .mhomed = false,
5709 .num_ips = ctx->addresses_best_num,
5710 .ips = ctx->addresses_best,
5711 .apply_expected = true
5713 .replica= {
5714 .type = WREPL_TYPE_SGROUP,
5715 .state = WREPL_STATE_TOMBSTONE,
5716 .node = WREPL_NODE_B,
5717 .is_static = false,
5718 .num_ips = ARRAY_SIZE(addresses_B_1),
5719 .ips = addresses_B_1,
5720 .apply_expected = false
5724 * group vs. multi homed section
5727 * group,released vs. mhomed,active with same ip(s)
5730 .line = __location__,
5731 .name = _NBT_NAME("_GR_MA_SI", 0x00, NULL),
5732 .wins = {
5733 .nb_flags = NBT_NM_GROUP,
5734 .mhomed = false,
5735 .num_ips = ctx->addresses_best_num,
5736 .ips = ctx->addresses_best,
5737 .apply_expected = true
5739 .replica= {
5740 .type = WREPL_TYPE_MHOMED,
5741 .state = WREPL_STATE_ACTIVE,
5742 .node = WREPL_NODE_B,
5743 .is_static = false,
5744 .num_ips = ctx->addresses_best_num,
5745 .ips = ctx->addresses_best,
5746 .apply_expected = false
5750 * group,released vs. mhomed,active with different ip(s)
5753 .line = __location__,
5754 .name = _NBT_NAME("_GR_MA_DI", 0x00, NULL),
5755 .wins = {
5756 .nb_flags = NBT_NM_GROUP,
5757 .mhomed = false,
5758 .num_ips = ctx->addresses_best_num,
5759 .ips = ctx->addresses_best,
5760 .apply_expected = true
5762 .replica= {
5763 .type = WREPL_TYPE_MHOMED,
5764 .state = WREPL_STATE_ACTIVE,
5765 .node = WREPL_NODE_B,
5766 .is_static = false,
5767 .num_ips = ARRAY_SIZE(addresses_B_1),
5768 .ips = addresses_B_1,
5769 .apply_expected = false
5773 * group,released vs. mhomed,tombstone with same ip(s)
5776 .line = __location__,
5777 .name = _NBT_NAME("_GR_MT_SI", 0x00, NULL),
5778 .wins = {
5779 .nb_flags = NBT_NM_GROUP,
5780 .mhomed = false,
5781 .num_ips = ctx->addresses_best_num,
5782 .ips = ctx->addresses_best,
5783 .apply_expected = true
5785 .replica= {
5786 .type = WREPL_TYPE_MHOMED,
5787 .state = WREPL_STATE_TOMBSTONE,
5788 .node = WREPL_NODE_B,
5789 .is_static = false,
5790 .num_ips = ctx->addresses_best_num,
5791 .ips = ctx->addresses_best,
5792 .apply_expected = false
5796 * group,released vs. mhomed,tombstone with different ip(s)
5799 .line = __location__,
5800 .name = _NBT_NAME("_GR_MT_DI", 0x00, NULL),
5801 .wins = {
5802 .nb_flags = NBT_NM_GROUP,
5803 .mhomed = false,
5804 .num_ips = ctx->addresses_best_num,
5805 .ips = ctx->addresses_best,
5806 .apply_expected = true
5808 .replica= {
5809 .type = WREPL_TYPE_MHOMED,
5810 .state = WREPL_STATE_TOMBSTONE,
5811 .node = WREPL_NODE_B,
5812 .is_static = false,
5813 .num_ips = ARRAY_SIZE(addresses_B_1),
5814 .ips = addresses_B_1,
5815 .apply_expected = false
5819 * special group vs. unique section
5822 * sgroup,released vs. unique,active with same ip(s)
5825 .line = __location__,
5826 .name = _NBT_NAME("_SR_UA_SI", 0x1C, NULL),
5827 .wins = {
5828 .nb_flags = NBT_NM_GROUP,
5829 .mhomed = false,
5830 .num_ips = ctx->addresses_best_num,
5831 .ips = ctx->addresses_best,
5832 .apply_expected = true
5834 .replica= {
5835 .type = WREPL_TYPE_UNIQUE,
5836 .state = WREPL_STATE_ACTIVE,
5837 .node = WREPL_NODE_B,
5838 .is_static = false,
5839 .num_ips = ctx->addresses_best_num,
5840 .ips = ctx->addresses_best,
5841 .apply_expected = true
5845 * sgroup,released vs. unique,active with different ip(s)
5848 .line = __location__,
5849 .name = _NBT_NAME("_SR_UA_DI", 0x1C, NULL),
5850 .wins = {
5851 .nb_flags = NBT_NM_GROUP,
5852 .mhomed = false,
5853 .num_ips = ctx->addresses_best_num,
5854 .ips = ctx->addresses_best,
5855 .apply_expected = true
5857 .replica= {
5858 .type = WREPL_TYPE_UNIQUE,
5859 .state = WREPL_STATE_ACTIVE,
5860 .node = WREPL_NODE_B,
5861 .is_static = false,
5862 .num_ips = ARRAY_SIZE(addresses_B_1),
5863 .ips = addresses_B_1,
5864 .apply_expected = true
5868 * sgroup,released vs. unique,tombstone with same ip(s)
5871 .line = __location__,
5872 .name = _NBT_NAME("_SR_UT_SI", 0x1C, NULL),
5873 .wins = {
5874 .nb_flags = NBT_NM_GROUP,
5875 .mhomed = false,
5876 .num_ips = ctx->addresses_best_num,
5877 .ips = ctx->addresses_best,
5878 .apply_expected = true
5880 .replica= {
5881 .type = WREPL_TYPE_UNIQUE,
5882 .state = WREPL_STATE_TOMBSTONE,
5883 .node = WREPL_NODE_B,
5884 .is_static = false,
5885 .num_ips = ctx->addresses_best_num,
5886 .ips = ctx->addresses_best,
5887 .apply_expected = true
5891 * sgroup,released vs. unique,tombstone with different ip(s)
5894 .line = __location__,
5895 .name = _NBT_NAME("_SR_UT_DI", 0x1C, NULL),
5896 .wins = {
5897 .nb_flags = NBT_NM_GROUP,
5898 .mhomed = false,
5899 .num_ips = ctx->addresses_best_num,
5900 .ips = ctx->addresses_best,
5901 .apply_expected = true
5903 .replica= {
5904 .type = WREPL_TYPE_UNIQUE,
5905 .state = WREPL_STATE_TOMBSTONE,
5906 .node = WREPL_NODE_B,
5907 .is_static = false,
5908 .num_ips = ARRAY_SIZE(addresses_B_1),
5909 .ips = addresses_B_1,
5910 .apply_expected = true
5914 * special group vs. group section
5917 * sgroup,released vs. group,active with same ip(s)
5920 .line = __location__,
5921 .name = _NBT_NAME("_SR_GA_SI", 0x1C, NULL),
5922 .wins = {
5923 .nb_flags = NBT_NM_GROUP,
5924 .mhomed = false,
5925 .num_ips = ctx->addresses_best_num,
5926 .ips = ctx->addresses_best,
5927 .apply_expected = true
5929 .replica= {
5930 .type = WREPL_TYPE_GROUP,
5931 .state = WREPL_STATE_ACTIVE,
5932 .node = WREPL_NODE_B,
5933 .is_static = false,
5934 .num_ips = ctx->addresses_best_num,
5935 .ips = ctx->addresses_best,
5936 .apply_expected = true
5940 * sgroup,released vs. group,active with different ip(s)
5943 .line = __location__,
5944 .name = _NBT_NAME("_SR_GA_DI", 0x1C, NULL),
5945 .wins = {
5946 .nb_flags = NBT_NM_GROUP,
5947 .mhomed = false,
5948 .num_ips = ctx->addresses_best_num,
5949 .ips = ctx->addresses_best,
5950 .apply_expected = true
5952 .replica= {
5953 .type = WREPL_TYPE_GROUP,
5954 .state = WREPL_STATE_ACTIVE,
5955 .node = WREPL_NODE_B,
5956 .is_static = false,
5957 .num_ips = ARRAY_SIZE(addresses_B_1),
5958 .ips = addresses_B_1,
5959 .apply_expected = true
5963 * sgroup,released vs. group,tombstone with same ip(s)
5966 .line = __location__,
5967 .name = _NBT_NAME("_SR_GT_SI", 0x1C, NULL),
5968 .wins = {
5969 .nb_flags = NBT_NM_GROUP,
5970 .mhomed = false,
5971 .num_ips = ctx->addresses_best_num,
5972 .ips = ctx->addresses_best,
5973 .apply_expected = true
5975 .replica= {
5976 .type = WREPL_TYPE_GROUP,
5977 .state = WREPL_STATE_TOMBSTONE,
5978 .node = WREPL_NODE_B,
5979 .is_static = false,
5980 .num_ips = ctx->addresses_best_num,
5981 .ips = ctx->addresses_best,
5982 .apply_expected = true
5986 * sgroup,released vs. group,tombstone with different ip(s)
5989 .line = __location__,
5990 .name = _NBT_NAME("_SR_GT_DI", 0x1C, NULL),
5991 .wins = {
5992 .nb_flags = NBT_NM_GROUP,
5993 .mhomed = false,
5994 .num_ips = ctx->addresses_best_num,
5995 .ips = ctx->addresses_best,
5996 .apply_expected = true
5998 .replica= {
5999 .type = WREPL_TYPE_GROUP,
6000 .state = WREPL_STATE_TOMBSTONE,
6001 .node = WREPL_NODE_B,
6002 .is_static = false,
6003 .num_ips = ARRAY_SIZE(addresses_B_1),
6004 .ips = addresses_B_1,
6005 .apply_expected = true
6009 * special group vs. special group section
6012 * sgroup,released vs. sgroup,active with same ip(s)
6015 .line = __location__,
6016 .name = _NBT_NAME("_SR_SA_SI", 0x1C, NULL),
6017 .wins = {
6018 .nb_flags = NBT_NM_GROUP,
6019 .mhomed = false,
6020 .num_ips = ctx->addresses_best_num,
6021 .ips = ctx->addresses_best,
6022 .apply_expected = true
6024 .replica= {
6025 .type = WREPL_TYPE_SGROUP,
6026 .state = WREPL_STATE_ACTIVE,
6027 .node = WREPL_NODE_B,
6028 .is_static = false,
6029 .num_ips = ctx->addresses_best_num,
6030 .ips = ctx->addresses_best,
6031 .apply_expected = true
6035 * sgroup,released vs. sgroup,active with different ip(s)
6038 .line = __location__,
6039 .name = _NBT_NAME("_SR_SA_DI", 0x1C, NULL),
6040 .wins = {
6041 .nb_flags = NBT_NM_GROUP,
6042 .mhomed = false,
6043 .num_ips = ctx->addresses_best_num,
6044 .ips = ctx->addresses_best,
6045 .apply_expected = true
6047 .replica= {
6048 .type = WREPL_TYPE_SGROUP,
6049 .state = WREPL_STATE_ACTIVE,
6050 .node = WREPL_NODE_B,
6051 .is_static = false,
6052 .num_ips = ARRAY_SIZE(addresses_B_1),
6053 .ips = addresses_B_1,
6054 .apply_expected = true
6058 * sgroup,released vs. sgroup,tombstone with same ip(s)
6061 .line = __location__,
6062 .name = _NBT_NAME("_SR_ST_SI", 0x1C, NULL),
6063 .wins = {
6064 .nb_flags = NBT_NM_GROUP,
6065 .mhomed = false,
6066 .num_ips = ctx->addresses_best_num,
6067 .ips = ctx->addresses_best,
6068 .apply_expected = true
6070 .replica= {
6071 .type = WREPL_TYPE_SGROUP,
6072 .state = WREPL_STATE_TOMBSTONE,
6073 .node = WREPL_NODE_B,
6074 .is_static = false,
6075 .num_ips = ctx->addresses_best_num,
6076 .ips = ctx->addresses_best,
6077 .apply_expected = true
6081 * sgroup,released vs. sgroup,tombstone with different ip(s)
6084 .line = __location__,
6085 .name = _NBT_NAME("_SR_ST_DI", 0x1C, NULL),
6086 .wins = {
6087 .nb_flags = NBT_NM_GROUP,
6088 .mhomed = false,
6089 .num_ips = ctx->addresses_best_num,
6090 .ips = ctx->addresses_best,
6091 .apply_expected = true
6093 .replica= {
6094 .type = WREPL_TYPE_SGROUP,
6095 .state = WREPL_STATE_TOMBSTONE,
6096 .node = WREPL_NODE_B,
6097 .is_static = false,
6098 .num_ips = ARRAY_SIZE(addresses_B_1),
6099 .ips = addresses_B_1,
6100 .apply_expected = true
6104 * special group vs. multi homed section
6107 * sgroup,released vs. mhomed,active with same ip(s)
6110 .line = __location__,
6111 .name = _NBT_NAME("_SR_MA_SI", 0x1C, NULL),
6112 .wins = {
6113 .nb_flags = NBT_NM_GROUP,
6114 .mhomed = false,
6115 .num_ips = ctx->addresses_best_num,
6116 .ips = ctx->addresses_best,
6117 .apply_expected = true
6119 .replica= {
6120 .type = WREPL_TYPE_MHOMED,
6121 .state = WREPL_STATE_ACTIVE,
6122 .node = WREPL_NODE_B,
6123 .is_static = false,
6124 .num_ips = ctx->addresses_best_num,
6125 .ips = ctx->addresses_best,
6126 .apply_expected = true
6130 * sgroup,released vs. mhomed,active with different ip(s)
6133 .line = __location__,
6134 .name = _NBT_NAME("_SR_MA_DI", 0x1C, NULL),
6135 .wins = {
6136 .nb_flags = NBT_NM_GROUP,
6137 .mhomed = false,
6138 .num_ips = ctx->addresses_best_num,
6139 .ips = ctx->addresses_best,
6140 .apply_expected = true
6142 .replica= {
6143 .type = WREPL_TYPE_MHOMED,
6144 .state = WREPL_STATE_ACTIVE,
6145 .node = WREPL_NODE_B,
6146 .is_static = false,
6147 .num_ips = ARRAY_SIZE(addresses_B_1),
6148 .ips = addresses_B_1,
6149 .apply_expected = true
6153 * sgroup,released vs. mhomed,tombstone with same ip(s)
6156 .line = __location__,
6157 .name = _NBT_NAME("_SR_MT_SI", 0x1C, NULL),
6158 .wins = {
6159 .nb_flags = NBT_NM_GROUP,
6160 .mhomed = false,
6161 .num_ips = ctx->addresses_best_num,
6162 .ips = ctx->addresses_best,
6163 .apply_expected = true
6165 .replica= {
6166 .type = WREPL_TYPE_MHOMED,
6167 .state = WREPL_STATE_TOMBSTONE,
6168 .node = WREPL_NODE_B,
6169 .is_static = false,
6170 .num_ips = ctx->addresses_best_num,
6171 .ips = ctx->addresses_best,
6172 .apply_expected = true
6176 * sgroup,released vs. mhomed,tombstone with different ip(s)
6179 .line = __location__,
6180 .name = _NBT_NAME("_SR_MT_DI", 0x1C, NULL),
6181 .wins = {
6182 .nb_flags = NBT_NM_GROUP,
6183 .mhomed = false,
6184 .num_ips = ctx->addresses_best_num,
6185 .ips = ctx->addresses_best,
6186 .apply_expected = true
6188 .replica= {
6189 .type = WREPL_TYPE_MHOMED,
6190 .state = WREPL_STATE_TOMBSTONE,
6191 .node = WREPL_NODE_B,
6192 .is_static = false,
6193 .num_ips = ARRAY_SIZE(addresses_B_1),
6194 .ips = addresses_B_1,
6195 .apply_expected = true
6199 * multi homed vs. unique section
6202 * mhomed,released vs. unique,active with same ip(s)
6205 .line = __location__,
6206 .name = _NBT_NAME("_MR_UA_SI", 0x00, NULL),
6207 .wins = {
6208 .nb_flags = 0,
6209 .mhomed = true,
6210 .num_ips = ctx->addresses_best_num,
6211 .ips = ctx->addresses_best,
6212 .apply_expected = true
6214 .replica= {
6215 .type = WREPL_TYPE_UNIQUE,
6216 .state = WREPL_STATE_ACTIVE,
6217 .node = WREPL_NODE_B,
6218 .is_static = false,
6219 .num_ips = ctx->addresses_best_num,
6220 .ips = ctx->addresses_best,
6221 .apply_expected = true
6225 * mhomed,released vs. unique,active with different ip(s)
6228 .line = __location__,
6229 .name = _NBT_NAME("_MR_UA_DI", 0x00, NULL),
6230 .wins = {
6231 .nb_flags = 0,
6232 .mhomed = true,
6233 .num_ips = ctx->addresses_best_num,
6234 .ips = ctx->addresses_best,
6235 .apply_expected = true
6237 .replica= {
6238 .type = WREPL_TYPE_UNIQUE,
6239 .state = WREPL_STATE_ACTIVE,
6240 .node = WREPL_NODE_B,
6241 .is_static = false,
6242 .num_ips = ARRAY_SIZE(addresses_B_1),
6243 .ips = addresses_B_1,
6244 .apply_expected = true
6248 * mhomed,released vs. unique,tombstone with same ip(s)
6251 .line = __location__,
6252 .name = _NBT_NAME("_MR_UT_SI", 0x00, NULL),
6253 .wins = {
6254 .nb_flags = 0,
6255 .mhomed = true,
6256 .num_ips = ctx->addresses_best_num,
6257 .ips = ctx->addresses_best,
6258 .apply_expected = true
6260 .replica= {
6261 .type = WREPL_TYPE_UNIQUE,
6262 .state = WREPL_STATE_TOMBSTONE,
6263 .node = WREPL_NODE_B,
6264 .is_static = false,
6265 .num_ips = ctx->addresses_best_num,
6266 .ips = ctx->addresses_best,
6267 .apply_expected = true
6271 * mhomed,released vs. unique,tombstone with different ip(s)
6274 .line = __location__,
6275 .name = _NBT_NAME("_MR_UT_DI", 0x00, NULL),
6276 .wins = {
6277 .nb_flags = 0,
6278 .mhomed = true,
6279 .num_ips = ctx->addresses_best_num,
6280 .ips = ctx->addresses_best,
6281 .apply_expected = true
6283 .replica= {
6284 .type = WREPL_TYPE_UNIQUE,
6285 .state = WREPL_STATE_TOMBSTONE,
6286 .node = WREPL_NODE_B,
6287 .is_static = false,
6288 .num_ips = ARRAY_SIZE(addresses_B_1),
6289 .ips = addresses_B_1,
6290 .apply_expected = true
6294 * multi homed vs. group section
6297 * mhomed,released vs. group,active with same ip(s)
6300 .line = __location__,
6301 .name = _NBT_NAME("_MR_GA_SI", 0x00, NULL),
6302 .wins = {
6303 .nb_flags = 0,
6304 .mhomed = true,
6305 .num_ips = ctx->addresses_best_num,
6306 .ips = ctx->addresses_best,
6307 .apply_expected = true
6309 .replica= {
6310 .type = WREPL_TYPE_GROUP,
6311 .state = WREPL_STATE_ACTIVE,
6312 .node = WREPL_NODE_B,
6313 .is_static = false,
6314 .num_ips = ctx->addresses_best_num,
6315 .ips = ctx->addresses_best,
6316 .apply_expected = true
6320 * mhomed,released vs. group,active with different ip(s)
6323 .line = __location__,
6324 .name = _NBT_NAME("_MR_GA_DI", 0x00, NULL),
6325 .wins = {
6326 .nb_flags = 0,
6327 .mhomed = true,
6328 .num_ips = ctx->addresses_best_num,
6329 .ips = ctx->addresses_best,
6330 .apply_expected = true
6332 .replica= {
6333 .type = WREPL_TYPE_GROUP,
6334 .state = WREPL_STATE_ACTIVE,
6335 .node = WREPL_NODE_B,
6336 .is_static = false,
6337 .num_ips = ARRAY_SIZE(addresses_B_1),
6338 .ips = addresses_B_1,
6339 .apply_expected = true
6343 * mhomed,released vs. group,tombstone with same ip(s)
6346 .line = __location__,
6347 .name = _NBT_NAME("_MR_GT_SI", 0x00, NULL),
6348 .wins = {
6349 .nb_flags = 0,
6350 .mhomed = true,
6351 .num_ips = ctx->addresses_best_num,
6352 .ips = ctx->addresses_best,
6353 .apply_expected = true
6355 .replica= {
6356 .type = WREPL_TYPE_GROUP,
6357 .state = WREPL_STATE_TOMBSTONE,
6358 .node = WREPL_NODE_B,
6359 .is_static = false,
6360 .num_ips = ctx->addresses_best_num,
6361 .ips = ctx->addresses_best,
6362 .apply_expected = true
6366 * mhomed,released vs. group,tombstone with different ip(s)
6369 .line = __location__,
6370 .name = _NBT_NAME("_MR_GT_DI", 0x00, NULL),
6371 .wins = {
6372 .nb_flags = 0,
6373 .mhomed = true,
6374 .num_ips = ctx->addresses_best_num,
6375 .ips = ctx->addresses_best,
6376 .apply_expected = true
6378 .replica= {
6379 .type = WREPL_TYPE_GROUP,
6380 .state = WREPL_STATE_TOMBSTONE,
6381 .node = WREPL_NODE_B,
6382 .is_static = false,
6383 .num_ips = ARRAY_SIZE(addresses_B_1),
6384 .ips = addresses_B_1,
6385 .apply_expected = true
6389 * multi homed vs. special group section
6392 * mhomed,released vs. sgroup,active with same ip(s)
6395 .line = __location__,
6396 .name = _NBT_NAME("_MR_SA_SI", 0x00, NULL),
6397 .wins = {
6398 .nb_flags = 0,
6399 .mhomed = true,
6400 .num_ips = ctx->addresses_best_num,
6401 .ips = ctx->addresses_best,
6402 .apply_expected = true
6404 .replica= {
6405 .type = WREPL_TYPE_SGROUP,
6406 .state = WREPL_STATE_ACTIVE,
6407 .node = WREPL_NODE_B,
6408 .is_static = false,
6409 .num_ips = ctx->addresses_best_num,
6410 .ips = ctx->addresses_best,
6411 .apply_expected = true
6415 * mhomed,released vs. sgroup,active with different ip(s)
6418 .line = __location__,
6419 .name = _NBT_NAME("_MR_SA_DI", 0x00, NULL),
6420 .wins = {
6421 .nb_flags = 0,
6422 .mhomed = true,
6423 .num_ips = ctx->addresses_best_num,
6424 .ips = ctx->addresses_best,
6425 .apply_expected = true
6427 .replica= {
6428 .type = WREPL_TYPE_SGROUP,
6429 .state = WREPL_STATE_ACTIVE,
6430 .node = WREPL_NODE_B,
6431 .is_static = false,
6432 .num_ips = ARRAY_SIZE(addresses_B_1),
6433 .ips = addresses_B_1,
6434 .apply_expected = true
6438 * mhomed,released vs. sgroup,tombstone with same ip(s)
6441 .line = __location__,
6442 .name = _NBT_NAME("_MR_ST_SI", 0x00, NULL),
6443 .wins = {
6444 .nb_flags = 0,
6445 .mhomed = true,
6446 .num_ips = ctx->addresses_best_num,
6447 .ips = ctx->addresses_best,
6448 .apply_expected = true
6450 .replica= {
6451 .type = WREPL_TYPE_SGROUP,
6452 .state = WREPL_STATE_TOMBSTONE,
6453 .node = WREPL_NODE_B,
6454 .is_static = false,
6455 .num_ips = ctx->addresses_best_num,
6456 .ips = ctx->addresses_best,
6457 .apply_expected = true
6461 * mhomed,released vs. sgroup,tombstone with different ip(s)
6464 .line = __location__,
6465 .name = _NBT_NAME("_MR_ST_DI", 0x00, NULL),
6466 .wins = {
6467 .nb_flags = 0,
6468 .mhomed = true,
6469 .num_ips = ctx->addresses_best_num,
6470 .ips = ctx->addresses_best,
6471 .apply_expected = true
6473 .replica= {
6474 .type = WREPL_TYPE_SGROUP,
6475 .state = WREPL_STATE_TOMBSTONE,
6476 .node = WREPL_NODE_B,
6477 .is_static = false,
6478 .num_ips = ARRAY_SIZE(addresses_B_1),
6479 .ips = addresses_B_1,
6480 .apply_expected = true
6484 * multi homed vs. multi homed section
6487 * mhomed,released vs. mhomed,active with same ip(s)
6490 .line = __location__,
6491 .name = _NBT_NAME("_MR_MA_SI", 0x00, NULL),
6492 .wins = {
6493 .nb_flags = 0,
6494 .mhomed = true,
6495 .num_ips = ctx->addresses_best_num,
6496 .ips = ctx->addresses_best,
6497 .apply_expected = true
6499 .replica= {
6500 .type = WREPL_TYPE_MHOMED,
6501 .state = WREPL_STATE_ACTIVE,
6502 .node = WREPL_NODE_B,
6503 .is_static = false,
6504 .num_ips = ctx->addresses_best_num,
6505 .ips = ctx->addresses_best,
6506 .apply_expected = true
6510 * mhomed,released vs. mhomed,active with different ip(s)
6513 .line = __location__,
6514 .name = _NBT_NAME("_MR_MA_DI", 0x00, NULL),
6515 .wins = {
6516 .nb_flags = 0,
6517 .mhomed = true,
6518 .num_ips = ctx->addresses_best_num,
6519 .ips = ctx->addresses_best,
6520 .apply_expected = true
6522 .replica= {
6523 .type = WREPL_TYPE_MHOMED,
6524 .state = WREPL_STATE_ACTIVE,
6525 .node = WREPL_NODE_B,
6526 .is_static = false,
6527 .num_ips = ARRAY_SIZE(addresses_B_1),
6528 .ips = addresses_B_1,
6529 .apply_expected = true
6533 * mhomed,released vs. mhomed,tombstone with same ip(s)
6536 .line = __location__,
6537 .name = _NBT_NAME("_MR_MT_SI", 0x00, NULL),
6538 .wins = {
6539 .nb_flags = 0,
6540 .mhomed = true,
6541 .num_ips = ctx->addresses_best_num,
6542 .ips = ctx->addresses_best,
6543 .apply_expected = true
6545 .replica= {
6546 .type = WREPL_TYPE_MHOMED,
6547 .state = WREPL_STATE_TOMBSTONE,
6548 .node = WREPL_NODE_B,
6549 .is_static = false,
6550 .num_ips = ctx->addresses_best_num,
6551 .ips = ctx->addresses_best,
6552 .apply_expected = true
6556 * mhomed,released vs. mhomed,tombstone with different ip(s)
6559 .line = __location__,
6560 .name = _NBT_NAME("_MR_MT_DI", 0x00, NULL),
6561 .wins = {
6562 .nb_flags = 0,
6563 .mhomed = true,
6564 .num_ips = ctx->addresses_best_num,
6565 .ips = ctx->addresses_best,
6566 .apply_expected = true
6568 .replica= {
6569 .type = WREPL_TYPE_MHOMED,
6570 .state = WREPL_STATE_TOMBSTONE,
6571 .node = WREPL_NODE_B,
6572 .is_static = false,
6573 .num_ips = ARRAY_SIZE(addresses_B_1),
6574 .ips = addresses_B_1,
6575 .apply_expected = true
6580 torture_comment(tctx, "Test Replica records vs. owned released records\n");
6582 for(i=0; ret && i < ARRAY_SIZE(records); i++) {
6583 torture_comment(tctx, "%s => %s\n", nbt_name_string(ctx, &records[i].name),
6584 (records[i].replica.apply_expected?"REPLACE":"NOT REPLACE"));
6587 * Setup Register
6589 name_register->in.name = records[i].name;
6590 name_register->in.dest_addr = ctx->address;
6591 name_register->in.dest_port = lpcfg_nbt_port(tctx->lp_ctx);
6592 name_register->in.address = records[i].wins.ips[0].ip;
6593 name_register->in.nb_flags = records[i].wins.nb_flags;
6594 name_register->in.register_demand= false;
6595 name_register->in.broadcast = false;
6596 name_register->in.multi_homed = records[i].wins.mhomed;
6597 name_register->in.ttl = 300000;
6598 name_register->in.timeout = 70;
6599 name_register->in.retries = 0;
6601 status = nbt_name_register(ctx->nbtsock, ctx, name_register);
6602 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
6603 torture_comment(tctx, "No response from %s for name register\n", ctx->address);
6604 ret = false;
6606 if (!NT_STATUS_IS_OK(status)) {
6607 torture_comment(tctx, "Bad response from %s for name register - %s\n",
6608 ctx->address, nt_errstr(status));
6609 ret = false;
6611 CHECK_VALUE(tctx, name_register->out.rcode, 0);
6612 CHECK_VALUE_STRING(tctx, name_register->out.reply_from, ctx->address);
6613 CHECK_VALUE(tctx, name_register->out.name.type, records[i].name.type);
6614 CHECK_VALUE_STRING(tctx, name_register->out.name.name, records[i].name.name);
6615 CHECK_VALUE_STRING(tctx, name_register->out.name.scope, records[i].name.scope);
6616 CHECK_VALUE_STRING(tctx, name_register->out.reply_addr, records[i].wins.ips[0].ip);
6618 /* release the record */
6619 release->in.name = records[i].name;
6620 release->in.dest_port = lpcfg_nbt_port(tctx->lp_ctx);
6621 release->in.dest_addr = ctx->address;
6622 release->in.address = records[i].wins.ips[0].ip;
6623 release->in.nb_flags = records[i].wins.nb_flags;
6624 release->in.broadcast = false;
6625 release->in.timeout = 30;
6626 release->in.retries = 0;
6628 status = nbt_name_release(ctx->nbtsock, ctx, release);
6629 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
6630 torture_comment(tctx, "No response from %s for name release\n", ctx->address);
6631 return false;
6633 if (!NT_STATUS_IS_OK(status)) {
6634 torture_comment(tctx, "Bad response from %s for name query - %s\n",
6635 ctx->address, nt_errstr(status));
6636 return false;
6638 CHECK_VALUE(tctx, release->out.rcode, 0);
6641 * Setup Replica
6643 wins_name->name = &records[i].name;
6644 wins_name->flags = WREPL_NAME_FLAGS(records[i].replica.type,
6645 records[i].replica.state,
6646 records[i].replica.node,
6647 records[i].replica.is_static);
6648 wins_name->id = ++ctx->b.max_version;
6649 if (wins_name->flags & 2) {
6650 wins_name->addresses.addresses.num_ips = records[i].replica.num_ips;
6651 wins_name->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
6652 records[i].replica.ips);
6653 } else {
6654 wins_name->addresses.ip = records[i].replica.ips[0].ip;
6656 wins_name->unknown = "255.255.255.255";
6658 ret &= test_wrepl_update_one(tctx, ctx, &ctx->b, wins_name);
6659 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->b, wins_name,
6660 records[i].replica.apply_expected);
6662 if (records[i].replica.apply_expected) {
6663 wins_name->name = &records[i].name;
6664 wins_name->flags = WREPL_NAME_FLAGS(WREPL_TYPE_UNIQUE,
6665 WREPL_STATE_TOMBSTONE,
6666 WREPL_NODE_B, false);
6667 wins_name->id = ++ctx->b.max_version;
6668 wins_name->addresses.ip = addresses_B_1[0].ip;
6669 wins_name->unknown = "255.255.255.255";
6671 ret &= test_wrepl_update_one(tctx, ctx, &ctx->b, wins_name);
6672 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->b, wins_name, true);
6673 } else {
6674 release->in.name = records[i].name;
6675 release->in.dest_addr = ctx->address;
6676 release->in.dest_port = lpcfg_nbt_port(tctx->lp_ctx);
6677 release->in.address = records[i].wins.ips[0].ip;
6678 release->in.nb_flags = records[i].wins.nb_flags;
6679 release->in.broadcast = false;
6680 release->in.timeout = 30;
6681 release->in.retries = 0;
6683 status = nbt_name_release(ctx->nbtsock, ctx, release);
6684 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
6685 torture_comment(tctx, "No response from %s for name release\n", ctx->address);
6686 return false;
6688 if (!NT_STATUS_IS_OK(status)) {
6689 torture_comment(tctx, "Bad response from %s for name query - %s\n",
6690 ctx->address, nt_errstr(status));
6691 return false;
6693 CHECK_VALUE(tctx, release->out.rcode, 0);
6695 if (!ret) {
6696 torture_comment(tctx, "conflict handled wrong or record[%u]: %s\n", i, records[i].line);
6697 return ret;
6701 return ret;
6704 struct test_conflict_owned_active_vs_replica_struct {
6705 struct torture_context *tctx;
6706 const char *line; /* just better debugging */
6707 const char *section; /* just better debugging */
6708 struct nbt_name name;
6709 const char *comment;
6710 bool skip;
6711 struct {
6712 uint32_t nb_flags;
6713 bool mhomed;
6714 uint32_t num_ips;
6715 const struct wrepl_ip *ips;
6716 bool apply_expected;
6717 } wins;
6718 struct {
6719 uint32_t timeout;
6720 bool positive;
6721 bool expect_release;
6722 bool late_release;
6723 bool ret;
6724 /* when num_ips == 0, then .wins.ips are used */
6725 uint32_t num_ips;
6726 const struct wrepl_ip *ips;
6727 } defend;
6728 struct {
6729 enum wrepl_name_type type;
6730 enum wrepl_name_state state;
6731 enum wrepl_name_node node;
6732 bool is_static;
6733 uint32_t num_ips;
6734 const struct wrepl_ip *ips;
6735 bool apply_expected;
6736 bool mhomed_merge;
6737 bool sgroup_merge;
6738 } replica;
6741 static void test_conflict_owned_active_vs_replica_handler(struct nbt_name_socket *nbtsock,
6742 struct nbt_name_packet *req_packet,
6743 struct socket_address *src);
6745 static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx,
6746 struct test_wrepl_conflict_conn *ctx)
6748 bool ret = true;
6749 NTSTATUS status;
6750 struct wrepl_wins_name wins_name_;
6751 struct wrepl_wins_name *wins_name = &wins_name_;
6752 struct nbt_name_register name_register_;
6753 struct nbt_name_register *name_register = &name_register_;
6754 struct nbt_name_release release_;
6755 struct nbt_name_release *release = &release_;
6756 uint32_t i;
6757 struct test_conflict_owned_active_vs_replica_struct records[] = {
6759 * unique vs. unique section
6762 * unique,active vs. unique,active with same ip(s), unchecked
6765 .tctx = tctx,
6766 .line = __location__,
6767 .name = _NBT_NAME("_UA_UA_SI_U", 0x00, NULL),
6768 .wins = {
6769 .nb_flags = 0,
6770 .mhomed = false,
6771 .num_ips = ctx->addresses_best_num,
6772 .ips = ctx->addresses_best,
6773 .apply_expected = true
6775 .defend = {
6776 .timeout = 0,
6778 .replica= {
6779 .type = WREPL_TYPE_UNIQUE,
6780 .state = WREPL_STATE_ACTIVE,
6781 .node = WREPL_NODE_B,
6782 .is_static = false,
6783 .num_ips = ctx->addresses_best_num,
6784 .ips = ctx->addresses_best,
6785 .apply_expected = true
6789 * unique,active vs. unique,active with different ip(s), positive response
6792 .tctx = tctx,
6793 .line = __location__,
6794 .name = _NBT_NAME("_UA_UA_DI_P", 0x00, NULL),
6795 .wins = {
6796 .nb_flags = 0,
6797 .mhomed = false,
6798 .num_ips = ctx->addresses_best_num,
6799 .ips = ctx->addresses_best,
6800 .apply_expected = true
6802 .defend = {
6803 .timeout = 10,
6804 .positive = true,
6806 .replica= {
6807 .type = WREPL_TYPE_UNIQUE,
6808 .state = WREPL_STATE_ACTIVE,
6809 .node = WREPL_NODE_B,
6810 .is_static = false,
6811 .num_ips = ARRAY_SIZE(addresses_B_1),
6812 .ips = addresses_B_1,
6813 .apply_expected = false
6817 * unique,active vs. unique,active with different ip(s), positive response other ips
6820 .tctx = tctx,
6821 .line = __location__,
6822 .name = _NBT_NAME("_UA_UA_DI_O", 0x00, NULL),
6823 .wins = {
6824 .nb_flags = 0,
6825 .mhomed = false,
6826 .num_ips = ctx->addresses_best_num,
6827 .ips = ctx->addresses_best,
6828 .apply_expected = true
6830 .defend = {
6831 .timeout = 10,
6832 .positive = true,
6833 .num_ips = ARRAY_SIZE(addresses_A_3_4),
6834 .ips = addresses_A_3_4,
6836 .replica= {
6837 .type = WREPL_TYPE_UNIQUE,
6838 .state = WREPL_STATE_ACTIVE,
6839 .node = WREPL_NODE_B,
6840 .is_static = false,
6841 .num_ips = ARRAY_SIZE(addresses_B_1),
6842 .ips = addresses_B_1,
6843 .apply_expected = false
6847 * unique,active vs. unique,active with different ip(s), negative response
6850 .tctx = tctx,
6851 .line = __location__,
6852 .name = _NBT_NAME("_UA_UA_DI_N", 0x00, NULL),
6853 .wins = {
6854 .nb_flags = 0,
6855 .mhomed = false,
6856 .num_ips = ctx->addresses_best_num,
6857 .ips = ctx->addresses_best,
6858 .apply_expected = true
6860 .defend = {
6861 .timeout = 10,
6862 .positive = false,
6864 .replica= {
6865 .type = WREPL_TYPE_UNIQUE,
6866 .state = WREPL_STATE_ACTIVE,
6867 .node = WREPL_NODE_B,
6868 .is_static = false,
6869 .num_ips = ARRAY_SIZE(addresses_B_1),
6870 .ips = addresses_B_1,
6871 .apply_expected = true
6875 * unique,active vs. unique,tombstone with same ip(s), unchecked
6878 .tctx = tctx,
6879 .line = __location__,
6880 .name = _NBT_NAME("_UA_UT_SI_U", 0x00, NULL),
6881 .wins = {
6882 .nb_flags = 0,
6883 .mhomed = false,
6884 .num_ips = ctx->addresses_best_num,
6885 .ips = ctx->addresses_best,
6886 .apply_expected = true
6888 .defend = {
6889 .timeout = 0,
6891 .replica= {
6892 .type = WREPL_TYPE_UNIQUE,
6893 .state = WREPL_STATE_TOMBSTONE,
6894 .node = WREPL_NODE_B,
6895 .is_static = false,
6896 .num_ips = ctx->addresses_best_num,
6897 .ips = ctx->addresses_best,
6898 .apply_expected = false
6902 * unique,active vs. unique,tombstone with different ip(s), unchecked
6905 .tctx = tctx,
6906 .line = __location__,
6907 .name = _NBT_NAME("_UA_UT_DI_U", 0x00, NULL),
6908 .wins = {
6909 .nb_flags = 0,
6910 .mhomed = false,
6911 .num_ips = ctx->addresses_best_num,
6912 .ips = ctx->addresses_best,
6913 .apply_expected = true
6915 .defend = {
6916 .timeout = 0,
6918 .replica= {
6919 .type = WREPL_TYPE_UNIQUE,
6920 .state = WREPL_STATE_TOMBSTONE,
6921 .node = WREPL_NODE_B,
6922 .is_static = false,
6923 .num_ips = ARRAY_SIZE(addresses_B_1),
6924 .ips = addresses_B_1,
6925 .apply_expected = false
6929 * unique vs. group section
6932 * unique,active vs. group,active with same ip(s), release expected
6935 .tctx = tctx,
6936 .line = __location__,
6937 .name = _NBT_NAME("_UA_GA_SI_R", 0x00, NULL),
6938 .wins = {
6939 .nb_flags = 0,
6940 .mhomed = false,
6941 .num_ips = ctx->addresses_best_num,
6942 .ips = ctx->addresses_best,
6943 .apply_expected = true
6945 .defend = {
6946 .timeout = 10,
6947 .expect_release = true,
6949 .replica= {
6950 .type = WREPL_TYPE_GROUP,
6951 .state = WREPL_STATE_ACTIVE,
6952 .node = WREPL_NODE_B,
6953 .is_static = false,
6954 .num_ips = ctx->addresses_best_num,
6955 .ips = ctx->addresses_best,
6956 .apply_expected = true
6960 * unique,active vs. group,active with different ip(s), release expected
6963 .tctx = tctx,
6964 .line = __location__,
6965 .name = _NBT_NAME("_UA_GA_DI_R", 0x00, NULL),
6966 .wins = {
6967 .nb_flags = 0,
6968 .mhomed = false,
6969 .num_ips = ctx->addresses_best_num,
6970 .ips = ctx->addresses_best,
6971 .apply_expected = true
6973 .defend = {
6974 .timeout = 10,
6975 .expect_release = true,
6977 .replica= {
6978 .type = WREPL_TYPE_GROUP,
6979 .state = WREPL_STATE_ACTIVE,
6980 .node = WREPL_NODE_B,
6981 .is_static = false,
6982 .num_ips = ARRAY_SIZE(addresses_B_1),
6983 .ips = addresses_B_1,
6984 .apply_expected = true
6988 * unique,active vs. group,tombstone with same ip(s), unchecked
6991 .tctx = tctx,
6992 .line = __location__,
6993 .name = _NBT_NAME("_UA_GT_SI_U", 0x00, NULL),
6994 .wins = {
6995 .nb_flags = 0,
6996 .mhomed = false,
6997 .num_ips = ctx->addresses_best_num,
6998 .ips = ctx->addresses_best,
6999 .apply_expected = true
7001 .defend = {
7002 .timeout = 0,
7004 .replica= {
7005 .type = WREPL_TYPE_GROUP,
7006 .state = WREPL_STATE_TOMBSTONE,
7007 .node = WREPL_NODE_B,
7008 .is_static = false,
7009 .num_ips = ctx->addresses_best_num,
7010 .ips = ctx->addresses_best,
7011 .apply_expected = false
7015 * unique,active vs. group,tombstone with different ip(s), unchecked
7018 .tctx = tctx,
7019 .line = __location__,
7020 .name = _NBT_NAME("_UA_GT_DI_U", 0x00, NULL),
7021 .wins = {
7022 .nb_flags = 0,
7023 .mhomed = false,
7024 .num_ips = ctx->addresses_best_num,
7025 .ips = ctx->addresses_best,
7026 .apply_expected = true
7028 .defend = {
7029 .timeout = 0,
7031 .replica= {
7032 .type = WREPL_TYPE_GROUP,
7033 .state = WREPL_STATE_TOMBSTONE,
7034 .node = WREPL_NODE_B,
7035 .is_static = false,
7036 .num_ips = ARRAY_SIZE(addresses_B_1),
7037 .ips = addresses_B_1,
7038 .apply_expected = false
7042 * unique vs. special group section
7045 * unique,active vs. sgroup,active with same ip(s), release expected
7048 .tctx = tctx,
7049 .line = __location__,
7050 .name = _NBT_NAME("_UA_SA_SI_R", 0x00, NULL),
7051 .wins = {
7052 .nb_flags = 0,
7053 .mhomed = false,
7054 .num_ips = ctx->addresses_best_num,
7055 .ips = ctx->addresses_best,
7056 .apply_expected = true
7058 .defend = {
7059 .timeout = 10,
7060 .expect_release = true,
7062 .replica= {
7063 .type = WREPL_TYPE_SGROUP,
7064 .state = WREPL_STATE_ACTIVE,
7065 .node = WREPL_NODE_B,
7066 .is_static = false,
7067 .num_ips = ctx->addresses_best_num,
7068 .ips = ctx->addresses_best,
7069 .apply_expected = true
7073 * unique,active vs. group,active with different ip(s), release expected
7076 .tctx = tctx,
7077 .line = __location__,
7078 .name = _NBT_NAME("_UA_SA_DI_R", 0x00, NULL),
7079 .wins = {
7080 .nb_flags = 0,
7081 .mhomed = false,
7082 .num_ips = ctx->addresses_best_num,
7083 .ips = ctx->addresses_best,
7084 .apply_expected = true
7086 .defend = {
7087 .timeout = 10,
7088 .expect_release = true,
7090 .replica= {
7091 .type = WREPL_TYPE_SGROUP,
7092 .state = WREPL_STATE_ACTIVE,
7093 .node = WREPL_NODE_B,
7094 .is_static = false,
7095 .num_ips = ARRAY_SIZE(addresses_B_1),
7096 .ips = addresses_B_1,
7097 .apply_expected = true
7101 * unique,active vs. sgroup,tombstone with same ip(s), unchecked
7104 .tctx = tctx,
7105 .line = __location__,
7106 .name = _NBT_NAME("_UA_ST_SI_U", 0x00, NULL),
7107 .wins = {
7108 .nb_flags = 0,
7109 .mhomed = false,
7110 .num_ips = ctx->addresses_best_num,
7111 .ips = ctx->addresses_best,
7112 .apply_expected = true
7114 .defend = {
7115 .timeout = 0,
7117 .replica= {
7118 .type = WREPL_TYPE_SGROUP,
7119 .state = WREPL_STATE_TOMBSTONE,
7120 .node = WREPL_NODE_B,
7121 .is_static = false,
7122 .num_ips = ctx->addresses_best_num,
7123 .ips = ctx->addresses_best,
7124 .apply_expected = false
7128 * unique,active vs. sgroup,tombstone with different ip(s), unchecked
7131 .tctx = tctx,
7132 .line = __location__,
7133 .name = _NBT_NAME("_UA_ST_DI_U", 0x00, NULL),
7134 .wins = {
7135 .nb_flags = 0,
7136 .mhomed = false,
7137 .num_ips = ctx->addresses_best_num,
7138 .ips = ctx->addresses_best,
7139 .apply_expected = true
7141 .defend = {
7142 .timeout = 0,
7144 .replica= {
7145 .type = WREPL_TYPE_SGROUP,
7146 .state = WREPL_STATE_TOMBSTONE,
7147 .node = WREPL_NODE_B,
7148 .is_static = false,
7149 .num_ips = ARRAY_SIZE(addresses_B_1),
7150 .ips = addresses_B_1,
7151 .apply_expected = false
7155 * unique vs. multi homed section
7158 * unique,active vs. mhomed,active with same ip(s), unchecked
7161 .tctx = tctx,
7162 .line = __location__,
7163 .name = _NBT_NAME("_UA_MA_SI_U", 0x00, NULL),
7164 .wins = {
7165 .nb_flags = 0,
7166 .mhomed = false,
7167 .num_ips = ctx->addresses_best_num,
7168 .ips = ctx->addresses_best,
7169 .apply_expected = true
7171 .defend = {
7172 .timeout = 0,
7174 .replica= {
7175 .type = WREPL_TYPE_MHOMED,
7176 .state = WREPL_STATE_ACTIVE,
7177 .node = WREPL_NODE_B,
7178 .is_static = false,
7179 .num_ips = ctx->addresses_best_num,
7180 .ips = ctx->addresses_best,
7181 .apply_expected = true
7185 * unique,active vs. mhomed,active with superset ip(s), unchecked
7188 .tctx = tctx,
7189 .line = __location__,
7190 .name = _NBT_NAME("_UA_MA_SP_U", 0x00, NULL),
7191 .wins = {
7192 .nb_flags = 0,
7193 .mhomed = false,
7194 .num_ips = ctx->addresses_best_num,
7195 .ips = ctx->addresses_best,
7196 .apply_expected = true
7198 .defend = {
7199 .timeout = 0,
7201 .replica= {
7202 .type = WREPL_TYPE_MHOMED,
7203 .state = WREPL_STATE_ACTIVE,
7204 .node = WREPL_NODE_B,
7205 .is_static = false,
7206 .num_ips = ctx->addresses_all_num,
7207 .ips = ctx->addresses_all,
7208 .apply_expected = true
7212 * unique,active vs. mhomed,active with different ip(s), positive response
7215 .tctx = tctx,
7216 .line = __location__,
7217 .name = _NBT_NAME("_UA_MA_DI_P", 0x00, NULL),
7218 .wins = {
7219 .nb_flags = 0,
7220 .mhomed = false,
7221 .num_ips = ctx->addresses_best_num,
7222 .ips = ctx->addresses_best,
7223 .apply_expected = true
7225 .defend = {
7226 .timeout = 10,
7227 .positive = true,
7229 .replica= {
7230 .type = WREPL_TYPE_MHOMED,
7231 .state = WREPL_STATE_ACTIVE,
7232 .node = WREPL_NODE_B,
7233 .is_static = false,
7234 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7235 .ips = addresses_B_3_4,
7236 .apply_expected = false
7240 * unique,active vs. mhomed,active with different ip(s), positive response other ips
7243 .tctx = tctx,
7244 .line = __location__,
7245 .name = _NBT_NAME("_UA_MA_DI_O", 0x00, NULL),
7246 .wins = {
7247 .nb_flags = 0,
7248 .mhomed = false,
7249 .num_ips = ctx->addresses_best_num,
7250 .ips = ctx->addresses_best,
7251 .apply_expected = true
7253 .defend = {
7254 .timeout = 10,
7255 .positive = true,
7256 .num_ips = ARRAY_SIZE(addresses_A_3_4),
7257 .ips = addresses_A_3_4,
7259 .replica= {
7260 .type = WREPL_TYPE_MHOMED,
7261 .state = WREPL_STATE_ACTIVE,
7262 .node = WREPL_NODE_B,
7263 .is_static = false,
7264 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7265 .ips = addresses_B_3_4,
7266 .apply_expected = false
7270 * unique,active vs. mhomed,active with different ip(s), negative response
7273 .tctx = tctx,
7274 .line = __location__,
7275 .name = _NBT_NAME("_UA_MA_DI_N", 0x00, NULL),
7276 .wins = {
7277 .nb_flags = 0,
7278 .mhomed = false,
7279 .num_ips = ctx->addresses_best_num,
7280 .ips = ctx->addresses_best,
7281 .apply_expected = true
7283 .defend = {
7284 .timeout = 10,
7285 .positive = false,
7287 .replica= {
7288 .type = WREPL_TYPE_MHOMED,
7289 .state = WREPL_STATE_ACTIVE,
7290 .node = WREPL_NODE_B,
7291 .is_static = false,
7292 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7293 .ips = addresses_B_3_4,
7294 .apply_expected = true
7298 * unique,active vs. mhomed,tombstone with same ip(s), unchecked
7301 .tctx = tctx,
7302 .line = __location__,
7303 .name = _NBT_NAME("_UA_MT_SI_U", 0x00, NULL),
7304 .wins = {
7305 .nb_flags = 0,
7306 .mhomed = false,
7307 .num_ips = ctx->addresses_best_num,
7308 .ips = ctx->addresses_best,
7309 .apply_expected = true
7311 .defend = {
7312 .timeout = 0,
7314 .replica= {
7315 .type = WREPL_TYPE_MHOMED,
7316 .state = WREPL_STATE_TOMBSTONE,
7317 .node = WREPL_NODE_B,
7318 .is_static = false,
7319 .num_ips = ctx->addresses_best_num,
7320 .ips = ctx->addresses_best,
7321 .apply_expected = false
7325 * unique,active vs. mhomed,tombstone with different ip(s), unchecked
7328 .tctx = tctx,
7329 .line = __location__,
7330 .name = _NBT_NAME("_UA_MT_DI_U", 0x00, NULL),
7331 .wins = {
7332 .nb_flags = 0,
7333 .mhomed = false,
7334 .num_ips = ctx->addresses_best_num,
7335 .ips = ctx->addresses_best,
7336 .apply_expected = true
7338 .defend = {
7339 .timeout = 0,
7341 .replica= {
7342 .type = WREPL_TYPE_MHOMED,
7343 .state = WREPL_STATE_TOMBSTONE,
7344 .node = WREPL_NODE_B,
7345 .is_static = false,
7346 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7347 .ips = addresses_B_3_4,
7348 .apply_expected = false
7352 * normal group vs. unique section
7355 * group,active vs. unique,active with same ip(s), unchecked
7358 .tctx = tctx,
7359 .line = __location__,
7360 .name = _NBT_NAME("_GA_UA_SI_U", 0x00, NULL),
7361 .wins = {
7362 .nb_flags = NBT_NM_GROUP,
7363 .mhomed = false,
7364 .num_ips = ctx->addresses_best_num,
7365 .ips = ctx->addresses_best,
7366 .apply_expected = true
7368 .defend = {
7369 .timeout = 0,
7371 .replica= {
7372 .type = WREPL_TYPE_UNIQUE,
7373 .state = WREPL_STATE_ACTIVE,
7374 .node = WREPL_NODE_B,
7375 .is_static = false,
7376 .num_ips = ctx->addresses_best_num,
7377 .ips = ctx->addresses_best,
7378 .apply_expected = false
7382 * group,active vs. unique,active with different ip(s), unchecked
7385 .tctx = tctx,
7386 .line = __location__,
7387 .name = _NBT_NAME("_GA_UA_DI_U", 0x00, NULL),
7388 .wins = {
7389 .nb_flags = NBT_NM_GROUP,
7390 .mhomed = false,
7391 .num_ips = ctx->addresses_best_num,
7392 .ips = ctx->addresses_best,
7393 .apply_expected = true
7395 .defend = {
7396 .timeout = 0,
7398 .replica= {
7399 .type = WREPL_TYPE_UNIQUE,
7400 .state = WREPL_STATE_ACTIVE,
7401 .node = WREPL_NODE_B,
7402 .is_static = false,
7403 .num_ips = ARRAY_SIZE(addresses_B_1),
7404 .ips = addresses_B_1,
7405 .apply_expected = false
7409 * group,active vs. unique,tombstone with same ip(s), unchecked
7412 .tctx = tctx,
7413 .line = __location__,
7414 .name = _NBT_NAME("_GA_UT_SI_U", 0x00, NULL),
7415 .wins = {
7416 .nb_flags = NBT_NM_GROUP,
7417 .mhomed = false,
7418 .num_ips = ctx->addresses_best_num,
7419 .ips = ctx->addresses_best,
7420 .apply_expected = true
7422 .defend = {
7423 .timeout = 0,
7425 .replica= {
7426 .type = WREPL_TYPE_UNIQUE,
7427 .state = WREPL_STATE_TOMBSTONE,
7428 .node = WREPL_NODE_B,
7429 .is_static = false,
7430 .num_ips = ctx->addresses_best_num,
7431 .ips = ctx->addresses_best,
7432 .apply_expected = false
7436 * group,active vs. unique,tombstone with different ip(s), unchecked
7439 .tctx = tctx,
7440 .line = __location__,
7441 .name = _NBT_NAME("_GA_UT_DI_U", 0x00, NULL),
7442 .wins = {
7443 .nb_flags = NBT_NM_GROUP,
7444 .mhomed = false,
7445 .num_ips = ctx->addresses_best_num,
7446 .ips = ctx->addresses_best,
7447 .apply_expected = true
7449 .defend = {
7450 .timeout = 0,
7452 .replica= {
7453 .type = WREPL_TYPE_UNIQUE,
7454 .state = WREPL_STATE_TOMBSTONE,
7455 .node = WREPL_NODE_B,
7456 .is_static = false,
7457 .num_ips = ARRAY_SIZE(addresses_B_1),
7458 .ips = addresses_B_1,
7459 .apply_expected = false
7463 * normal group vs. normal group section
7466 * group,active vs. group,active with same ip(s), unchecked
7469 .tctx = tctx,
7470 .line = __location__,
7471 .name = _NBT_NAME("_GA_GA_SI_U", 0x00, NULL),
7472 .wins = {
7473 .nb_flags = NBT_NM_GROUP,
7474 .mhomed = false,
7475 .num_ips = ctx->addresses_best_num,
7476 .ips = ctx->addresses_best,
7477 .apply_expected = true
7479 .defend = {
7480 .timeout = 0,
7482 .replica= {
7483 .type = WREPL_TYPE_GROUP,
7484 .state = WREPL_STATE_ACTIVE,
7485 .node = WREPL_NODE_B,
7486 .is_static = false,
7487 .num_ips = ctx->addresses_best_num,
7488 .ips = ctx->addresses_best,
7489 .apply_expected = true
7493 * group,active vs. group,active with different ip(s), unchecked
7496 .tctx = tctx,
7497 .line = __location__,
7498 .name = _NBT_NAME("_GA_GA_DI_U", 0x00, NULL),
7499 .wins = {
7500 .nb_flags = NBT_NM_GROUP,
7501 .mhomed = false,
7502 .num_ips = ctx->addresses_best_num,
7503 .ips = ctx->addresses_best,
7504 .apply_expected = true
7506 .defend = {
7507 .timeout = 0,
7509 .replica= {
7510 .type = WREPL_TYPE_GROUP,
7511 .state = WREPL_STATE_ACTIVE,
7512 .node = WREPL_NODE_B,
7513 .is_static = false,
7514 .num_ips = ARRAY_SIZE(addresses_B_1),
7515 .ips = addresses_B_1,
7516 .apply_expected = true
7520 * group,active vs. group,tombstone with same ip(s), unchecked
7523 .tctx = tctx,
7524 .line = __location__,
7525 .name = _NBT_NAME("_GA_GT_SI_U", 0x00, NULL),
7526 .wins = {
7527 .nb_flags = NBT_NM_GROUP,
7528 .mhomed = false,
7529 .num_ips = ctx->addresses_best_num,
7530 .ips = ctx->addresses_best,
7531 .apply_expected = true
7533 .defend = {
7534 .timeout = 0,
7536 .replica= {
7537 .type = WREPL_TYPE_GROUP,
7538 .state = WREPL_STATE_TOMBSTONE,
7539 .node = WREPL_NODE_B,
7540 .is_static = false,
7541 .num_ips = ctx->addresses_best_num,
7542 .ips = ctx->addresses_best,
7543 .apply_expected = false
7547 * group,active vs. group,tombstone with different ip(s), unchecked
7550 .tctx = tctx,
7551 .line = __location__,
7552 .name = _NBT_NAME("_GA_GT_DI_U", 0x00, NULL),
7553 .wins = {
7554 .nb_flags = NBT_NM_GROUP,
7555 .mhomed = false,
7556 .num_ips = ctx->addresses_best_num,
7557 .ips = ctx->addresses_best,
7558 .apply_expected = true
7560 .defend = {
7561 .timeout = 0,
7563 .replica= {
7564 .type = WREPL_TYPE_GROUP,
7565 .state = WREPL_STATE_TOMBSTONE,
7566 .node = WREPL_NODE_B,
7567 .is_static = false,
7568 .num_ips = ARRAY_SIZE(addresses_B_1),
7569 .ips = addresses_B_1,
7570 .apply_expected = false
7574 * normal group vs. special group section
7577 * group,active vs. sgroup,active with same ip(s), unchecked
7580 .tctx = tctx,
7581 .line = __location__,
7582 .name = _NBT_NAME("_GA_SA_SI_U", 0x00, NULL),
7583 .wins = {
7584 .nb_flags = NBT_NM_GROUP,
7585 .mhomed = false,
7586 .num_ips = ctx->addresses_best_num,
7587 .ips = ctx->addresses_best,
7588 .apply_expected = true
7590 .defend = {
7591 .timeout = 0,
7593 .replica= {
7594 .type = WREPL_TYPE_SGROUP,
7595 .state = WREPL_STATE_ACTIVE,
7596 .node = WREPL_NODE_B,
7597 .is_static = false,
7598 .num_ips = ctx->addresses_best_num,
7599 .ips = ctx->addresses_best,
7600 .apply_expected = false
7604 * group,active vs. sgroup,active with different ip(s), unchecked
7607 .tctx = tctx,
7608 .line = __location__,
7609 .name = _NBT_NAME("_GA_SA_DI_U", 0x00, NULL),
7610 .wins = {
7611 .nb_flags = NBT_NM_GROUP,
7612 .mhomed = false,
7613 .num_ips = ctx->addresses_best_num,
7614 .ips = ctx->addresses_best,
7615 .apply_expected = true
7617 .defend = {
7618 .timeout = 0,
7620 .replica= {
7621 .type = WREPL_TYPE_SGROUP,
7622 .state = WREPL_STATE_ACTIVE,
7623 .node = WREPL_NODE_B,
7624 .is_static = false,
7625 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7626 .ips = addresses_B_3_4,
7627 .apply_expected = false
7631 * group,active vs. sgroup,tombstone with same ip(s), unchecked
7634 .tctx = tctx,
7635 .line = __location__,
7636 .name = _NBT_NAME("_GA_ST_SI_U", 0x00, NULL),
7637 .wins = {
7638 .nb_flags = NBT_NM_GROUP,
7639 .mhomed = false,
7640 .num_ips = ctx->addresses_best_num,
7641 .ips = ctx->addresses_best,
7642 .apply_expected = true
7644 .defend = {
7645 .timeout = 0,
7647 .replica= {
7648 .type = WREPL_TYPE_SGROUP,
7649 .state = WREPL_STATE_TOMBSTONE,
7650 .node = WREPL_NODE_B,
7651 .is_static = false,
7652 .num_ips = ctx->addresses_best_num,
7653 .ips = ctx->addresses_best,
7654 .apply_expected = false
7658 * group,active vs. sgroup,tombstone with different ip(s), unchecked
7661 .tctx = tctx,
7662 .line = __location__,
7663 .name = _NBT_NAME("_GA_ST_DI_U", 0x00, NULL),
7664 .wins = {
7665 .nb_flags = NBT_NM_GROUP,
7666 .mhomed = false,
7667 .num_ips = ctx->addresses_best_num,
7668 .ips = ctx->addresses_best,
7669 .apply_expected = true
7671 .defend = {
7672 .timeout = 0,
7674 .replica= {
7675 .type = WREPL_TYPE_SGROUP,
7676 .state = WREPL_STATE_TOMBSTONE,
7677 .node = WREPL_NODE_B,
7678 .is_static = false,
7679 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7680 .ips = addresses_B_3_4,
7681 .apply_expected = false
7685 * normal group vs. multi homed section
7688 * group,active vs. mhomed,active with same ip(s), unchecked
7691 .tctx = tctx,
7692 .line = __location__,
7693 .name = _NBT_NAME("_GA_MA_SI_U", 0x00, NULL),
7694 .wins = {
7695 .nb_flags = NBT_NM_GROUP,
7696 .mhomed = false,
7697 .num_ips = ctx->addresses_best_num,
7698 .ips = ctx->addresses_best,
7699 .apply_expected = true
7701 .defend = {
7702 .timeout = 0,
7704 .replica= {
7705 .type = WREPL_TYPE_MHOMED,
7706 .state = WREPL_STATE_ACTIVE,
7707 .node = WREPL_NODE_B,
7708 .is_static = false,
7709 .num_ips = ctx->addresses_best_num,
7710 .ips = ctx->addresses_best,
7711 .apply_expected = false
7715 * group,active vs. mhomed,active with different ip(s), unchecked
7718 .tctx = tctx,
7719 .line = __location__,
7720 .name = _NBT_NAME("_GA_MA_DI_U", 0x00, NULL),
7721 .wins = {
7722 .nb_flags = NBT_NM_GROUP,
7723 .mhomed = false,
7724 .num_ips = ctx->addresses_best_num,
7725 .ips = ctx->addresses_best,
7726 .apply_expected = true
7728 .defend = {
7729 .timeout = 0,
7731 .replica= {
7732 .type = WREPL_TYPE_MHOMED,
7733 .state = WREPL_STATE_ACTIVE,
7734 .node = WREPL_NODE_B,
7735 .is_static = false,
7736 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7737 .ips = addresses_B_3_4,
7738 .apply_expected = false
7742 * group,active vs. mhomed,tombstone with same ip(s), unchecked
7745 .tctx = tctx,
7746 .line = __location__,
7747 .name = _NBT_NAME("_GA_MT_SI_U", 0x00, NULL),
7748 .wins = {
7749 .nb_flags = NBT_NM_GROUP,
7750 .mhomed = false,
7751 .num_ips = ctx->addresses_best_num,
7752 .ips = ctx->addresses_best,
7753 .apply_expected = true
7755 .defend = {
7756 .timeout = 0,
7758 .replica= {
7759 .type = WREPL_TYPE_MHOMED,
7760 .state = WREPL_STATE_TOMBSTONE,
7761 .node = WREPL_NODE_B,
7762 .is_static = false,
7763 .num_ips = ctx->addresses_best_num,
7764 .ips = ctx->addresses_best,
7765 .apply_expected = false
7769 * group,active vs. mhomed,tombstone with different ip(s), unchecked
7772 .tctx = tctx,
7773 .line = __location__,
7774 .name = _NBT_NAME("_GA_MT_DI_U", 0x00, NULL),
7775 .wins = {
7776 .nb_flags = NBT_NM_GROUP,
7777 .mhomed = false,
7778 .num_ips = ctx->addresses_best_num,
7779 .ips = ctx->addresses_best,
7780 .apply_expected = true
7782 .defend = {
7783 .timeout = 0,
7785 .replica= {
7786 .type = WREPL_TYPE_MHOMED,
7787 .state = WREPL_STATE_TOMBSTONE,
7788 .node = WREPL_NODE_B,
7789 .is_static = false,
7790 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7791 .ips = addresses_B_3_4,
7792 .apply_expected = false
7796 * special group vs. unique section
7799 * sgroup,active vs. unique,active with same ip(s), unchecked
7802 .tctx = tctx,
7803 .line = __location__,
7804 .name = _NBT_NAME("_SA_UA_SI_U", 0x1C, NULL),
7805 .wins = {
7806 .nb_flags = NBT_NM_GROUP,
7807 .mhomed = false,
7808 .num_ips = ctx->addresses_best_num,
7809 .ips = ctx->addresses_best,
7810 .apply_expected = true
7812 .defend = {
7813 .timeout = 0,
7815 .replica= {
7816 .type = WREPL_TYPE_UNIQUE,
7817 .state = WREPL_STATE_ACTIVE,
7818 .node = WREPL_NODE_B,
7819 .is_static = false,
7820 .num_ips = ctx->addresses_best_num,
7821 .ips = ctx->addresses_best,
7822 .apply_expected = false
7826 * sgroup,active vs. unique,active with different ip(s), unchecked
7829 .tctx = tctx,
7830 .line = __location__,
7831 .name = _NBT_NAME("_SA_UA_DI_U", 0x1C, NULL),
7832 .wins = {
7833 .nb_flags = NBT_NM_GROUP,
7834 .mhomed = false,
7835 .num_ips = ctx->addresses_best_num,
7836 .ips = ctx->addresses_best,
7837 .apply_expected = true
7839 .defend = {
7840 .timeout = 0,
7842 .replica= {
7843 .type = WREPL_TYPE_UNIQUE,
7844 .state = WREPL_STATE_ACTIVE,
7845 .node = WREPL_NODE_B,
7846 .is_static = false,
7847 .num_ips = ARRAY_SIZE(addresses_B_1),
7848 .ips = addresses_B_1,
7849 .apply_expected = false
7853 * sgroup,active vs. unique,tombstone with same ip(s), unchecked
7856 .tctx = tctx,
7857 .line = __location__,
7858 .name = _NBT_NAME("_SA_UT_SI_U", 0x1C, NULL),
7859 .wins = {
7860 .nb_flags = NBT_NM_GROUP,
7861 .mhomed = false,
7862 .num_ips = ctx->addresses_best_num,
7863 .ips = ctx->addresses_best,
7864 .apply_expected = true
7866 .defend = {
7867 .timeout = 0,
7869 .replica= {
7870 .type = WREPL_TYPE_UNIQUE,
7871 .state = WREPL_STATE_TOMBSTONE,
7872 .node = WREPL_NODE_B,
7873 .is_static = false,
7874 .num_ips = ctx->addresses_best_num,
7875 .ips = ctx->addresses_best,
7876 .apply_expected = false
7880 * sgroup,active vs. unique,tombstone with different ip(s), unchecked
7883 .tctx = tctx,
7884 .line = __location__,
7885 .name = _NBT_NAME("_SA_UT_DI_U", 0x1C, NULL),
7886 .wins = {
7887 .nb_flags = NBT_NM_GROUP,
7888 .mhomed = false,
7889 .num_ips = ctx->addresses_best_num,
7890 .ips = ctx->addresses_best,
7891 .apply_expected = true
7893 .defend = {
7894 .timeout = 0,
7896 .replica= {
7897 .type = WREPL_TYPE_UNIQUE,
7898 .state = WREPL_STATE_TOMBSTONE,
7899 .node = WREPL_NODE_B,
7900 .is_static = false,
7901 .num_ips = ARRAY_SIZE(addresses_B_1),
7902 .ips = addresses_B_1,
7903 .apply_expected = false
7907 * special group vs. normal group section
7910 * sgroup,active vs. group,active with same ip(s), unchecked
7913 .tctx = tctx,
7914 .line = __location__,
7915 .name = _NBT_NAME("_SA_GA_SI_U", 0x1C, NULL),
7916 .wins = {
7917 .nb_flags = NBT_NM_GROUP,
7918 .mhomed = false,
7919 .num_ips = ctx->addresses_best_num,
7920 .ips = ctx->addresses_best,
7921 .apply_expected = true
7923 .defend = {
7924 .timeout = 0,
7926 .replica= {
7927 .type = WREPL_TYPE_GROUP,
7928 .state = WREPL_STATE_ACTIVE,
7929 .node = WREPL_NODE_B,
7930 .is_static = false,
7931 .num_ips = ctx->addresses_best_num,
7932 .ips = ctx->addresses_best,
7933 .apply_expected = false
7937 * sgroup,active vs. group,active with different ip(s), unchecked
7940 .tctx = tctx,
7941 .line = __location__,
7942 .name = _NBT_NAME("_SA_GA_DI_U", 0x1C, NULL),
7943 .wins = {
7944 .nb_flags = NBT_NM_GROUP,
7945 .mhomed = false,
7946 .num_ips = ctx->addresses_best_num,
7947 .ips = ctx->addresses_best,
7948 .apply_expected = true
7950 .defend = {
7951 .timeout = 0,
7953 .replica= {
7954 .type = WREPL_TYPE_GROUP,
7955 .state = WREPL_STATE_ACTIVE,
7956 .node = WREPL_NODE_B,
7957 .is_static = false,
7958 .num_ips = ARRAY_SIZE(addresses_B_1),
7959 .ips = addresses_B_1,
7960 .apply_expected = false
7964 * sgroup,active vs. group,tombstone with same ip(s), unchecked
7967 .tctx = tctx,
7968 .line = __location__,
7969 .name = _NBT_NAME("_SA_GT_SI_U", 0x1C, NULL),
7970 .wins = {
7971 .nb_flags = NBT_NM_GROUP,
7972 .mhomed = false,
7973 .num_ips = ctx->addresses_best_num,
7974 .ips = ctx->addresses_best,
7975 .apply_expected = true
7977 .defend = {
7978 .timeout = 0,
7980 .replica= {
7981 .type = WREPL_TYPE_GROUP,
7982 .state = WREPL_STATE_TOMBSTONE,
7983 .node = WREPL_NODE_B,
7984 .is_static = false,
7985 .num_ips = ctx->addresses_best_num,
7986 .ips = ctx->addresses_best,
7987 .apply_expected = false
7991 * sgroup,active vs. group,tombstone with different ip(s), unchecked
7994 .tctx = tctx,
7995 .line = __location__,
7996 .name = _NBT_NAME("_SA_GT_DI_U", 0x1C, NULL),
7997 .wins = {
7998 .nb_flags = NBT_NM_GROUP,
7999 .mhomed = false,
8000 .num_ips = ctx->addresses_best_num,
8001 .ips = ctx->addresses_best,
8002 .apply_expected = true
8004 .defend = {
8005 .timeout = 0,
8007 .replica= {
8008 .type = WREPL_TYPE_GROUP,
8009 .state = WREPL_STATE_TOMBSTONE,
8010 .node = WREPL_NODE_B,
8011 .is_static = false,
8012 .num_ips = ARRAY_SIZE(addresses_B_1),
8013 .ips = addresses_B_1,
8014 .apply_expected = false
8018 * special group vs. multi homed section
8021 * sgroup,active vs. mhomed,active with same ip(s), unchecked
8024 .tctx = tctx,
8025 .line = __location__,
8026 .name = _NBT_NAME("_SA_MA_SI_U", 0x1C, NULL),
8027 .wins = {
8028 .nb_flags = NBT_NM_GROUP,
8029 .mhomed = false,
8030 .num_ips = ctx->addresses_best_num,
8031 .ips = ctx->addresses_best,
8032 .apply_expected = true
8034 .defend = {
8035 .timeout = 0,
8037 .replica= {
8038 .type = WREPL_TYPE_MHOMED,
8039 .state = WREPL_STATE_ACTIVE,
8040 .node = WREPL_NODE_B,
8041 .is_static = false,
8042 .num_ips = ctx->addresses_best_num,
8043 .ips = ctx->addresses_best,
8044 .apply_expected = false
8048 * sgroup,active vs. mhomed,active with different ip(s), unchecked
8051 .tctx = tctx,
8052 .line = __location__,
8053 .name = _NBT_NAME("_SA_MA_DI_U", 0x1C, NULL),
8054 .wins = {
8055 .nb_flags = NBT_NM_GROUP,
8056 .mhomed = false,
8057 .num_ips = ctx->addresses_best_num,
8058 .ips = ctx->addresses_best,
8059 .apply_expected = true
8061 .defend = {
8062 .timeout = 0,
8064 .replica= {
8065 .type = WREPL_TYPE_MHOMED,
8066 .state = WREPL_STATE_ACTIVE,
8067 .node = WREPL_NODE_B,
8068 .is_static = false,
8069 .num_ips = ARRAY_SIZE(addresses_B_1),
8070 .ips = addresses_B_1,
8071 .apply_expected = false
8075 * sgroup,active vs. mhomed,tombstone with same ip(s), unchecked
8078 .tctx = tctx,
8079 .line = __location__,
8080 .name = _NBT_NAME("_SA_MT_SI_U", 0x1C, NULL),
8081 .wins = {
8082 .nb_flags = NBT_NM_GROUP,
8083 .mhomed = false,
8084 .num_ips = ctx->addresses_best_num,
8085 .ips = ctx->addresses_best,
8086 .apply_expected = true
8088 .defend = {
8089 .timeout = 0,
8091 .replica= {
8092 .type = WREPL_TYPE_MHOMED,
8093 .state = WREPL_STATE_TOMBSTONE,
8094 .node = WREPL_NODE_B,
8095 .is_static = false,
8096 .num_ips = ctx->addresses_best_num,
8097 .ips = ctx->addresses_best,
8098 .apply_expected = false
8102 * sgroup,active vs. mhomed,tombstone with different ip(s), unchecked
8105 .tctx = tctx,
8106 .line = __location__,
8107 .name = _NBT_NAME("_SA_MT_DI_U", 0x1C, NULL),
8108 .wins = {
8109 .nb_flags = NBT_NM_GROUP,
8110 .mhomed = false,
8111 .num_ips = ctx->addresses_best_num,
8112 .ips = ctx->addresses_best,
8113 .apply_expected = true
8115 .defend = {
8116 .timeout = 0,
8118 .replica= {
8119 .type = WREPL_TYPE_MHOMED,
8120 .state = WREPL_STATE_TOMBSTONE,
8121 .node = WREPL_NODE_B,
8122 .is_static = false,
8123 .num_ips = ARRAY_SIZE(addresses_B_1),
8124 .ips = addresses_B_1,
8125 .apply_expected = false
8129 * multi homed vs. unique section
8132 * mhomed,active vs. unique,active with same ip(s), unchecked
8135 .tctx = tctx,
8136 .line = __location__,
8137 .name = _NBT_NAME("_MA_UA_SI_U", 0x00, NULL),
8138 .wins = {
8139 .nb_flags = 0,
8140 .mhomed = true,
8141 .num_ips = ctx->addresses_best_num,
8142 .ips = ctx->addresses_best,
8143 .apply_expected = true
8145 .defend = {
8146 .timeout = 0,
8148 .replica= {
8149 .type = WREPL_TYPE_UNIQUE,
8150 .state = WREPL_STATE_ACTIVE,
8151 .node = WREPL_NODE_B,
8152 .is_static = false,
8153 .num_ips = ctx->addresses_best_num,
8154 .ips = ctx->addresses_best,
8155 .apply_expected = true
8159 * mhomed,active vs. unique,active with different ip(s), positive response
8162 .tctx = tctx,
8163 .line = __location__,
8164 .name = _NBT_NAME("_MA_UA_DI_P", 0x00, NULL),
8165 .wins = {
8166 .nb_flags = 0,
8167 .mhomed = true,
8168 .num_ips = ctx->addresses_best_num,
8169 .ips = ctx->addresses_best,
8170 .apply_expected = true
8172 .defend = {
8173 .timeout = 10,
8174 .positive = true,
8176 .replica= {
8177 .type = WREPL_TYPE_UNIQUE,
8178 .state = WREPL_STATE_ACTIVE,
8179 .node = WREPL_NODE_B,
8180 .is_static = false,
8181 .num_ips = ARRAY_SIZE(addresses_B_1),
8182 .ips = addresses_B_1,
8183 .apply_expected = false
8187 * mhomed,active vs. unique,active with different ip(s), positive response other ips
8190 .tctx = tctx,
8191 .line = __location__,
8192 .name = _NBT_NAME("_MA_UA_DI_O", 0x00, NULL),
8193 .wins = {
8194 .nb_flags = 0,
8195 .mhomed = true,
8196 .num_ips = ctx->addresses_best_num,
8197 .ips = ctx->addresses_best,
8198 .apply_expected = true
8200 .defend = {
8201 .timeout = 10,
8202 .positive = true,
8203 .num_ips = ARRAY_SIZE(addresses_A_3_4),
8204 .ips = addresses_A_3_4,
8206 .replica= {
8207 .type = WREPL_TYPE_UNIQUE,
8208 .state = WREPL_STATE_ACTIVE,
8209 .node = WREPL_NODE_B,
8210 .is_static = false,
8211 .num_ips = ARRAY_SIZE(addresses_B_1),
8212 .ips = addresses_B_1,
8213 .apply_expected = false
8217 * mhomed,active vs. unique,active with different ip(s), negative response
8220 .tctx = tctx,
8221 .line = __location__,
8222 .name = _NBT_NAME("_MA_UA_DI_N", 0x00, NULL),
8223 .wins = {
8224 .nb_flags = 0,
8225 .mhomed = true,
8226 .num_ips = ctx->addresses_best_num,
8227 .ips = ctx->addresses_best,
8228 .apply_expected = true
8230 .defend = {
8231 .timeout = 10,
8232 .positive = false,
8234 .replica= {
8235 .type = WREPL_TYPE_UNIQUE,
8236 .state = WREPL_STATE_ACTIVE,
8237 .node = WREPL_NODE_B,
8238 .is_static = false,
8239 .num_ips = ARRAY_SIZE(addresses_B_1),
8240 .ips = addresses_B_1,
8241 .apply_expected = true
8245 * mhomed,active vs. unique,tombstone with same ip(s), unchecked
8248 .tctx = tctx,
8249 .line = __location__,
8250 .name = _NBT_NAME("_MA_UT_SI_U", 0x00, NULL),
8251 .wins = {
8252 .nb_flags = 0,
8253 .mhomed = true,
8254 .num_ips = ctx->addresses_best_num,
8255 .ips = ctx->addresses_best,
8256 .apply_expected = true
8258 .defend = {
8259 .timeout = 0,
8261 .replica= {
8262 .type = WREPL_TYPE_UNIQUE,
8263 .state = WREPL_STATE_TOMBSTONE,
8264 .node = WREPL_NODE_B,
8265 .is_static = false,
8266 .num_ips = ctx->addresses_best_num,
8267 .ips = ctx->addresses_best,
8268 .apply_expected = false
8272 * mhomed,active vs. unique,tombstone with different ip(s), unchecked
8275 .tctx = tctx,
8276 .line = __location__,
8277 .name = _NBT_NAME("_MA_UT_DI_U", 0x00, NULL),
8278 .wins = {
8279 .nb_flags = 0,
8280 .mhomed = true,
8281 .num_ips = ctx->addresses_best_num,
8282 .ips = ctx->addresses_best,
8283 .apply_expected = true
8285 .defend = {
8286 .timeout = 0,
8288 .replica= {
8289 .type = WREPL_TYPE_UNIQUE,
8290 .state = WREPL_STATE_TOMBSTONE,
8291 .node = WREPL_NODE_B,
8292 .is_static = false,
8293 .num_ips = ARRAY_SIZE(addresses_B_1),
8294 .ips = addresses_B_1,
8295 .apply_expected = false
8299 * multi homed vs. normal group section
8302 * mhomed,active vs. group,active with same ip(s), release expected
8305 .tctx = tctx,
8306 .line = __location__,
8307 .name = _NBT_NAME("_MA_GA_SI_R", 0x00, NULL),
8308 .wins = {
8309 .nb_flags = 0,
8310 .mhomed = true,
8311 .num_ips = ctx->addresses_best_num,
8312 .ips = ctx->addresses_best,
8313 .apply_expected = true
8315 .defend = {
8316 .timeout = 10,
8317 .expect_release = true,
8319 .replica= {
8320 .type = WREPL_TYPE_GROUP,
8321 .state = WREPL_STATE_ACTIVE,
8322 .node = WREPL_NODE_B,
8323 .is_static = false,
8324 .num_ips = ctx->addresses_best_num,
8325 .ips = ctx->addresses_best,
8326 .apply_expected = true
8330 * mhomed,active vs. group,active with different ip(s), release expected
8333 .tctx = tctx,
8334 .line = __location__,
8335 .name = _NBT_NAME("_MA_GA_DI_R", 0x00, NULL),
8336 .wins = {
8337 .nb_flags = 0,
8338 .mhomed = true,
8339 .num_ips = ctx->addresses_best_num,
8340 .ips = ctx->addresses_best,
8341 .apply_expected = true
8343 .defend = {
8344 .timeout = 10,
8345 .expect_release = true,
8347 .replica= {
8348 .type = WREPL_TYPE_GROUP,
8349 .state = WREPL_STATE_ACTIVE,
8350 .node = WREPL_NODE_B,
8351 .is_static = false,
8352 .num_ips = ARRAY_SIZE(addresses_B_1),
8353 .ips = addresses_B_1,
8354 .apply_expected = true
8358 * mhomed,active vs. group,tombstone with same ip(s), unchecked
8361 .tctx = tctx,
8362 .line = __location__,
8363 .name = _NBT_NAME("_MA_GT_SI_U", 0x00, NULL),
8364 .wins = {
8365 .nb_flags = 0,
8366 .mhomed = true,
8367 .num_ips = ctx->addresses_best_num,
8368 .ips = ctx->addresses_best,
8369 .apply_expected = true
8371 .defend = {
8372 .timeout = 0,
8374 .replica= {
8375 .type = WREPL_TYPE_GROUP,
8376 .state = WREPL_STATE_TOMBSTONE,
8377 .node = WREPL_NODE_B,
8378 .is_static = false,
8379 .num_ips = ctx->addresses_best_num,
8380 .ips = ctx->addresses_best,
8381 .apply_expected = false
8385 * mhomed,active vs. group,tombstone with different ip(s), unchecked
8388 .tctx = tctx,
8389 .line = __location__,
8390 .name = _NBT_NAME("_MA_GT_DI_U", 0x00, NULL),
8391 .wins = {
8392 .nb_flags = 0,
8393 .mhomed = true,
8394 .num_ips = ctx->addresses_best_num,
8395 .ips = ctx->addresses_best,
8396 .apply_expected = true
8398 .defend = {
8399 .timeout = 0,
8401 .replica= {
8402 .type = WREPL_TYPE_GROUP,
8403 .state = WREPL_STATE_TOMBSTONE,
8404 .node = WREPL_NODE_B,
8405 .is_static = false,
8406 .num_ips = ARRAY_SIZE(addresses_B_1),
8407 .ips = addresses_B_1,
8408 .apply_expected = false
8412 * multi homed vs. special group section
8415 * mhomed,active vs. sgroup,active with same ip(s), release expected
8418 .tctx = tctx,
8419 .line = __location__,
8420 .name = _NBT_NAME("_MA_SA_SI_R", 0x00, NULL),
8421 .wins = {
8422 .nb_flags = 0,
8423 .mhomed = true,
8424 .num_ips = ctx->addresses_best_num,
8425 .ips = ctx->addresses_best,
8426 .apply_expected = true
8428 .defend = {
8429 .timeout = 10,
8430 .expect_release = true,
8432 .replica= {
8433 .type = WREPL_TYPE_SGROUP,
8434 .state = WREPL_STATE_ACTIVE,
8435 .node = WREPL_NODE_B,
8436 .is_static = false,
8437 .num_ips = ctx->addresses_best_num,
8438 .ips = ctx->addresses_best,
8439 .apply_expected = true
8443 * mhomed,active vs. group,active with different ip(s), release expected
8446 .tctx = tctx,
8447 .line = __location__,
8448 .name = _NBT_NAME("_MA_SA_DI_R", 0x00, NULL),
8449 .wins = {
8450 .nb_flags = 0,
8451 .mhomed = true,
8452 .num_ips = ctx->addresses_best_num,
8453 .ips = ctx->addresses_best,
8454 .apply_expected = true
8456 .defend = {
8457 .timeout = 10,
8458 .expect_release = true,
8460 .replica= {
8461 .type = WREPL_TYPE_SGROUP,
8462 .state = WREPL_STATE_ACTIVE,
8463 .node = WREPL_NODE_B,
8464 .is_static = false,
8465 .num_ips = ARRAY_SIZE(addresses_B_1),
8466 .ips = addresses_B_1,
8467 .apply_expected = true
8471 * mhomed,active vs. sgroup,tombstone with same ip(s), unchecked
8474 .tctx = tctx,
8475 .line = __location__,
8476 .name = _NBT_NAME("_MA_ST_SI_U", 0x00, NULL),
8477 .wins = {
8478 .nb_flags = 0,
8479 .mhomed = true,
8480 .num_ips = ctx->addresses_best_num,
8481 .ips = ctx->addresses_best,
8482 .apply_expected = true
8484 .defend = {
8485 .timeout = 0,
8487 .replica= {
8488 .type = WREPL_TYPE_SGROUP,
8489 .state = WREPL_STATE_TOMBSTONE,
8490 .node = WREPL_NODE_B,
8491 .is_static = false,
8492 .num_ips = ctx->addresses_best_num,
8493 .ips = ctx->addresses_best,
8494 .apply_expected = false
8498 * mhomed,active vs. sgroup,tombstone with different ip(s), unchecked
8501 .tctx = tctx,
8502 .line = __location__,
8503 .name = _NBT_NAME("_MA_ST_DI_U", 0x00, NULL),
8504 .wins = {
8505 .nb_flags = 0,
8506 .mhomed = true,
8507 .num_ips = ctx->addresses_best_num,
8508 .ips = ctx->addresses_best,
8509 .apply_expected = true
8511 .defend = {
8512 .timeout = 0,
8514 .replica= {
8515 .type = WREPL_TYPE_SGROUP,
8516 .state = WREPL_STATE_TOMBSTONE,
8517 .node = WREPL_NODE_B,
8518 .is_static = false,
8519 .num_ips = ARRAY_SIZE(addresses_B_1),
8520 .ips = addresses_B_1,
8521 .apply_expected = false
8525 * multi homed vs. multi homed section
8528 * mhomed,active vs. mhomed,active with same ip(s), unchecked
8531 .tctx = tctx,
8532 .line = __location__,
8533 .name = _NBT_NAME("_MA_MA_SI_U", 0x00, NULL),
8534 .wins = {
8535 .nb_flags = 0,
8536 .mhomed = true,
8537 .num_ips = ctx->addresses_best_num,
8538 .ips = ctx->addresses_best,
8539 .apply_expected = true
8541 .defend = {
8542 .timeout = 0,
8544 .replica= {
8545 .type = WREPL_TYPE_MHOMED,
8546 .state = WREPL_STATE_ACTIVE,
8547 .node = WREPL_NODE_B,
8548 .is_static = false,
8549 .num_ips = ctx->addresses_best_num,
8550 .ips = ctx->addresses_best,
8551 .apply_expected = true
8555 * mhomed,active vs. mhomed,active with superset ip(s), unchecked
8558 .tctx = tctx,
8559 .line = __location__,
8560 .name = _NBT_NAME("_MA_MA_SP_U", 0x00, NULL),
8561 .wins = {
8562 .nb_flags = 0,
8563 .mhomed = true,
8564 .num_ips = ctx->addresses_best_num,
8565 .ips = ctx->addresses_best,
8566 .apply_expected = true
8568 .defend = {
8569 .timeout = 0,
8571 .replica= {
8572 .type = WREPL_TYPE_MHOMED,
8573 .state = WREPL_STATE_ACTIVE,
8574 .node = WREPL_NODE_B,
8575 .is_static = false,
8576 .num_ips = ctx->addresses_all_num,
8577 .ips = ctx->addresses_all,
8578 .apply_expected = true
8582 * mhomed,active vs. mhomed,active with different ip(s), positive response
8585 .tctx = tctx,
8586 .line = __location__,
8587 .name = _NBT_NAME("_MA_MA_DI_P", 0x00, NULL),
8588 .wins = {
8589 .nb_flags = 0,
8590 .mhomed = true,
8591 .num_ips = ctx->addresses_best_num,
8592 .ips = ctx->addresses_best,
8593 .apply_expected = true
8595 .defend = {
8596 .timeout = 10,
8597 .positive = true,
8599 .replica= {
8600 .type = WREPL_TYPE_MHOMED,
8601 .state = WREPL_STATE_ACTIVE,
8602 .node = WREPL_NODE_B,
8603 .is_static = false,
8604 .num_ips = ARRAY_SIZE(addresses_B_3_4),
8605 .ips = addresses_B_3_4,
8606 .apply_expected = false
8610 * mhomed,active vs. mhomed,active with different ip(s), positive response other ips
8613 .tctx = tctx,
8614 .line = __location__,
8615 .name = _NBT_NAME("_MA_MA_DI_O", 0x00, NULL),
8616 .wins = {
8617 .nb_flags = 0,
8618 .mhomed = true,
8619 .num_ips = ctx->addresses_best_num,
8620 .ips = ctx->addresses_best,
8621 .apply_expected = true
8623 .defend = {
8624 .timeout = 10,
8625 .positive = true,
8626 .num_ips = ARRAY_SIZE(addresses_A_3_4),
8627 .ips = addresses_A_3_4,
8629 .replica= {
8630 .type = WREPL_TYPE_MHOMED,
8631 .state = WREPL_STATE_ACTIVE,
8632 .node = WREPL_NODE_B,
8633 .is_static = false,
8634 .num_ips = ARRAY_SIZE(addresses_B_3_4),
8635 .ips = addresses_B_3_4,
8636 .apply_expected = false
8640 * mhomed,active vs. mhomed,active with different ip(s), negative response
8643 .tctx = tctx,
8644 .line = __location__,
8645 .name = _NBT_NAME("_MA_MA_DI_N", 0x00, NULL),
8646 .wins = {
8647 .nb_flags = 0,
8648 .mhomed = true,
8649 .num_ips = ctx->addresses_best_num,
8650 .ips = ctx->addresses_best,
8651 .apply_expected = true
8653 .defend = {
8654 .timeout = 10,
8655 .positive = false,
8657 .replica= {
8658 .type = WREPL_TYPE_MHOMED,
8659 .state = WREPL_STATE_ACTIVE,
8660 .node = WREPL_NODE_B,
8661 .is_static = false,
8662 .num_ips = ARRAY_SIZE(addresses_B_3_4),
8663 .ips = addresses_B_3_4,
8664 .apply_expected = true
8668 * mhomed,active vs. mhomed,tombstone with same ip(s), unchecked
8671 .tctx = tctx,
8672 .line = __location__,
8673 .name = _NBT_NAME("_MA_MT_SI_U", 0x00, NULL),
8674 .wins = {
8675 .nb_flags = 0,
8676 .mhomed = true,
8677 .num_ips = ctx->addresses_best_num,
8678 .ips = ctx->addresses_best,
8679 .apply_expected = true
8681 .defend = {
8682 .timeout = 0,
8684 .replica= {
8685 .type = WREPL_TYPE_MHOMED,
8686 .state = WREPL_STATE_TOMBSTONE,
8687 .node = WREPL_NODE_B,
8688 .is_static = false,
8689 .num_ips = ctx->addresses_best_num,
8690 .ips = ctx->addresses_best,
8691 .apply_expected = false
8695 * mhomed,active vs. mhomed,tombstone with different ip(s), unchecked
8698 .tctx = tctx,
8699 .line = __location__,
8700 .name = _NBT_NAME("_MA_MT_DI_U", 0x00, NULL),
8701 .wins = {
8702 .nb_flags = 0,
8703 .mhomed = true,
8704 .num_ips = ctx->addresses_best_num,
8705 .ips = ctx->addresses_best,
8706 .apply_expected = true
8708 .defend = {
8709 .timeout = 0,
8711 .replica= {
8712 .type = WREPL_TYPE_MHOMED,
8713 .state = WREPL_STATE_TOMBSTONE,
8714 .node = WREPL_NODE_B,
8715 .is_static = false,
8716 .num_ips = ARRAY_SIZE(addresses_B_3_4),
8717 .ips = addresses_B_3_4,
8718 .apply_expected = false
8722 * some more multi homed test, including merging
8725 * mhomed,active vs. mhomed,active with superset ip(s), unchecked
8728 .tctx = tctx,
8729 .line = __location__,
8730 .section= "Test Replica vs. owned active: some more MHOMED combinations",
8731 .name = _NBT_NAME("_MA_MA_SP_U", 0x00, NULL),
8732 .comment= "C:MHOMED vs. B:ALL => B:ALL",
8733 .skip = (ctx->addresses_all_num < 3),
8734 .wins = {
8735 .nb_flags = 0,
8736 .mhomed = true,
8737 .num_ips = ctx->addresses_mhomed_num,
8738 .ips = ctx->addresses_mhomed,
8739 .apply_expected = true
8741 .defend = {
8742 .timeout = 0,
8744 .replica= {
8745 .type = WREPL_TYPE_MHOMED,
8746 .state = WREPL_STATE_ACTIVE,
8747 .node = WREPL_NODE_B,
8748 .is_static = false,
8749 .num_ips = ctx->addresses_all_num,
8750 .ips = ctx->addresses_all,
8751 .apply_expected = true
8755 * mhomed,active vs. mhomed,active with same ips, unchecked
8758 .tctx = tctx,
8759 .line = __location__,
8760 .name = _NBT_NAME("_MA_MA_SM_U", 0x00, NULL),
8761 .comment= "C:MHOMED vs. B:MHOMED => B:MHOMED",
8762 .skip = (ctx->addresses_mhomed_num < 2),
8763 .wins = {
8764 .nb_flags = 0,
8765 .mhomed = true,
8766 .num_ips = ctx->addresses_mhomed_num,
8767 .ips = ctx->addresses_mhomed,
8768 .apply_expected = true
8770 .defend = {
8771 .timeout = 0,
8773 .replica= {
8774 .type = WREPL_TYPE_MHOMED,
8775 .state = WREPL_STATE_ACTIVE,
8776 .node = WREPL_NODE_B,
8777 .is_static = false,
8778 .num_ips = ctx->addresses_mhomed_num,
8779 .ips = ctx->addresses_mhomed,
8780 .apply_expected = true
8784 * mhomed,active vs. mhomed,active with subset ip(s), positive response
8787 .tctx = tctx,
8788 .line = __location__,
8789 .name = _NBT_NAME("_MA_MA_SB_P", 0x00, NULL),
8790 .comment= "C:MHOMED vs. B:BEST (C:MHOMED) => B:MHOMED",
8791 .skip = (ctx->addresses_mhomed_num < 2),
8792 .wins = {
8793 .nb_flags = 0,
8794 .mhomed = true,
8795 .num_ips = ctx->addresses_mhomed_num,
8796 .ips = ctx->addresses_mhomed,
8797 .apply_expected = true
8799 .defend = {
8800 .timeout = 10,
8801 .positive = true
8803 .replica= {
8804 .type = WREPL_TYPE_MHOMED,
8805 .state = WREPL_STATE_ACTIVE,
8806 .node = WREPL_NODE_B,
8807 .is_static = false,
8808 .num_ips = ctx->addresses_best_num,
8809 .ips = ctx->addresses_best,
8810 .mhomed_merge = true
8814 * mhomed,active vs. mhomed,active with subset ip(s), positive response, with all addresses
8817 .tctx = tctx,
8818 .line = __location__,
8819 .name = _NBT_NAME("_MA_MA_SB_A", 0x00, NULL),
8820 .comment= "C:MHOMED vs. B:BEST (C:ALL) => B:MHOMED",
8821 .skip = (ctx->addresses_all_num < 3),
8822 .wins = {
8823 .nb_flags = 0,
8824 .mhomed = true,
8825 .num_ips = ctx->addresses_mhomed_num,
8826 .ips = ctx->addresses_mhomed,
8827 .apply_expected = true
8829 .defend = {
8830 .timeout = 10,
8831 .positive = true,
8832 .num_ips = ctx->addresses_all_num,
8833 .ips = ctx->addresses_all,
8835 .replica= {
8836 .type = WREPL_TYPE_MHOMED,
8837 .state = WREPL_STATE_ACTIVE,
8838 .node = WREPL_NODE_B,
8839 .is_static = false,
8840 .num_ips = ctx->addresses_best_num,
8841 .ips = ctx->addresses_best,
8842 .mhomed_merge = true
8846 * mhomed,active vs. mhomed,active with subset ip(s), positive response, with replicas addresses
8847 * TODO: check why the server sends a name release demand for one address?
8848 * the release demand has no effect to the database record...
8851 .tctx = tctx,
8852 .line = __location__,
8853 .name = _NBT_NAME("_MA_MA_SB_PRA", 0x00, NULL),
8854 .comment= "C:MHOMED vs. B:BEST (C:BEST) => C:MHOMED",
8855 .skip = (ctx->addresses_all_num < 2),
8856 .wins = {
8857 .nb_flags = 0,
8858 .mhomed = true,
8859 .num_ips = ctx->addresses_mhomed_num,
8860 .ips = ctx->addresses_mhomed,
8861 .apply_expected = true
8863 .defend = {
8864 .timeout = 10,
8865 .positive = true,
8866 .num_ips = ctx->addresses_best_num,
8867 .ips = ctx->addresses_best,
8868 .late_release = true
8870 .replica= {
8871 .type = WREPL_TYPE_MHOMED,
8872 .state = WREPL_STATE_ACTIVE,
8873 .node = WREPL_NODE_B,
8874 .is_static = false,
8875 .num_ips = ctx->addresses_best_num,
8876 .ips = ctx->addresses_best,
8877 .apply_expected = false
8881 * mhomed,active vs. mhomed,active with subset ip(s), positive response, with other addresses
8884 .tctx = tctx,
8885 .line = __location__,
8886 .name = _NBT_NAME("_MA_MA_SB_O", 0x00, NULL),
8887 .comment= "C:MHOMED vs. B:BEST (B:B_3_4) =>C:MHOMED",
8888 .skip = (ctx->addresses_all_num < 2),
8889 .wins = {
8890 .nb_flags = 0,
8891 .mhomed = true,
8892 .num_ips = ctx->addresses_mhomed_num,
8893 .ips = ctx->addresses_mhomed,
8894 .apply_expected = true
8896 .defend = {
8897 .timeout = 10,
8898 .positive = true,
8899 .num_ips = ARRAY_SIZE(addresses_B_3_4),
8900 .ips = addresses_B_3_4,
8902 .replica= {
8903 .type = WREPL_TYPE_MHOMED,
8904 .state = WREPL_STATE_ACTIVE,
8905 .node = WREPL_NODE_B,
8906 .is_static = false,
8907 .num_ips = ctx->addresses_best_num,
8908 .ips = ctx->addresses_best,
8909 .apply_expected = false
8913 * mhomed,active vs. mhomed,active with subset ip(s), negative response
8916 .tctx = tctx,
8917 .line = __location__,
8918 .name = _NBT_NAME("_MA_MA_SB_N", 0x00, NULL),
8919 .comment= "C:MHOMED vs. B:BEST (NEGATIVE) => B:BEST",
8920 .skip = (ctx->addresses_mhomed_num < 2),
8921 .wins = {
8922 .nb_flags = 0,
8923 .mhomed = true,
8924 .num_ips = ctx->addresses_mhomed_num,
8925 .ips = ctx->addresses_mhomed,
8926 .apply_expected = true
8928 .defend = {
8929 .timeout = 10,
8930 .positive = false
8932 .replica= {
8933 .type = WREPL_TYPE_MHOMED,
8934 .state = WREPL_STATE_ACTIVE,
8935 .node = WREPL_NODE_B,
8936 .is_static = false,
8937 .num_ips = ctx->addresses_best_num,
8938 .ips = ctx->addresses_best,
8939 .apply_expected = true
8943 * some more multi homed and unique test, including merging
8946 * mhomed,active vs. unique,active with subset ip(s), positive response
8949 .tctx = tctx,
8950 .line = __location__,
8951 .section= "Test Replica vs. owned active: some more UNIQUE,MHOMED combinations",
8952 .name = _NBT_NAME("_MA_UA_SB_P", 0x00, NULL),
8953 .comment= "C:MHOMED vs. B:UNIQUE,BEST (C:MHOMED) => B:MHOMED",
8954 .skip = (ctx->addresses_all_num < 2),
8955 .wins = {
8956 .nb_flags = 0,
8957 .mhomed = true,
8958 .num_ips = ctx->addresses_mhomed_num,
8959 .ips = ctx->addresses_mhomed,
8960 .apply_expected = true
8962 .defend = {
8963 .timeout = 10,
8964 .positive = true,
8966 .replica= {
8967 .type = WREPL_TYPE_UNIQUE,
8968 .state = WREPL_STATE_ACTIVE,
8969 .node = WREPL_NODE_B,
8970 .is_static = false,
8971 .num_ips = ctx->addresses_best_num,
8972 .ips = ctx->addresses_best,
8973 .mhomed_merge = true
8977 * unique,active vs. unique,active with different ip(s), positive response, with replicas address
8978 * TODO: check why the server sends a name release demand for one address?
8979 * the release demand has no effect to the database record...
8982 .tctx = tctx,
8983 .line = __location__,
8984 .name = _NBT_NAME("_UA_UA_DI_PRA", 0x00, NULL),
8985 .comment= "C:BEST vs. B:BEST2 (C:BEST2,LR:BEST2) => C:BEST",
8986 .skip = (ctx->addresses_all_num < 2),
8987 .wins = {
8988 .nb_flags = 0,
8989 .mhomed = false,
8990 .num_ips = ctx->addresses_best_num,
8991 .ips = ctx->addresses_best,
8992 .apply_expected = true
8994 .defend = {
8995 .timeout = 10,
8996 .positive = true,
8997 .num_ips = ctx->addresses_best2_num,
8998 .ips = ctx->addresses_best2,
8999 .late_release = true
9001 .replica= {
9002 .type = WREPL_TYPE_UNIQUE,
9003 .state = WREPL_STATE_ACTIVE,
9004 .node = WREPL_NODE_B,
9005 .is_static = false,
9006 .num_ips = ctx->addresses_best2_num,
9007 .ips = ctx->addresses_best2,
9008 .apply_expected = false,
9012 * unique,active vs. unique,active with different ip(s), positive response, with all addresses
9015 .tctx = tctx,
9016 .line = __location__,
9017 .name = _NBT_NAME("_UA_UA_DI_A", 0x00, NULL),
9018 .comment= "C:BEST vs. B:BEST2 (C:ALL) => B:MHOMED",
9019 .skip = (ctx->addresses_all_num < 3),
9020 .wins = {
9021 .nb_flags = 0,
9022 .mhomed = false,
9023 .num_ips = ctx->addresses_best_num,
9024 .ips = ctx->addresses_best,
9025 .apply_expected = true
9027 .defend = {
9028 .timeout = 10,
9029 .positive = true,
9030 .num_ips = ctx->addresses_all_num,
9031 .ips = ctx->addresses_all,
9033 .replica= {
9034 .type = WREPL_TYPE_UNIQUE,
9035 .state = WREPL_STATE_ACTIVE,
9036 .node = WREPL_NODE_B,
9037 .is_static = false,
9038 .num_ips = ctx->addresses_best2_num,
9039 .ips = ctx->addresses_best2,
9040 .mhomed_merge = true,
9044 * unique,active vs. mhomed,active with different ip(s), positive response, with all addresses
9047 .tctx = tctx,
9048 .line = __location__,
9049 .name = _NBT_NAME("_UA_MA_DI_A", 0x00, NULL),
9050 .comment= "C:BEST vs. B:BEST2 (C:ALL) => B:MHOMED",
9051 .skip = (ctx->addresses_all_num < 3),
9052 .wins = {
9053 .nb_flags = 0,
9054 .mhomed = false,
9055 .num_ips = ctx->addresses_best_num,
9056 .ips = ctx->addresses_best,
9057 .apply_expected = true
9059 .defend = {
9060 .timeout = 10,
9061 .positive = true,
9062 .num_ips = ctx->addresses_all_num,
9063 .ips = ctx->addresses_all,
9065 .replica= {
9066 .type = WREPL_TYPE_MHOMED,
9067 .state = WREPL_STATE_ACTIVE,
9068 .node = WREPL_NODE_B,
9069 .is_static = false,
9070 .num_ips = ctx->addresses_best2_num,
9071 .ips = ctx->addresses_best2,
9072 .mhomed_merge = true,
9076 * special group vs. special group merging section
9079 * sgroup,active vs. sgroup,active with different ip(s)
9082 .tctx = tctx,
9083 .line = __location__,
9084 .section= "Test Replica vs. owned active: SGROUP vs. SGROUP tests",
9085 .name = _NBT_NAME("_SA_SA_DI_U", 0x1C, NULL),
9086 .skip = (ctx->addresses_all_num < 3),
9087 .wins = {
9088 .nb_flags = NBT_NM_GROUP,
9089 .mhomed = false,
9090 .num_ips = ctx->addresses_mhomed_num,
9091 .ips = ctx->addresses_mhomed,
9092 .apply_expected = true
9094 .defend = {
9095 .timeout = 0,
9097 .replica= {
9098 .type = WREPL_TYPE_SGROUP,
9099 .state = WREPL_STATE_ACTIVE,
9100 .node = WREPL_NODE_B,
9101 .is_static = false,
9102 .num_ips = ARRAY_SIZE(addresses_B_3_4),
9103 .ips = addresses_B_3_4,
9104 .sgroup_merge = true
9108 * sgroup,active vs. sgroup,active with same ip(s)
9111 .tctx = tctx,
9112 .line = __location__,
9113 .name = _NBT_NAME("_SA_SA_SI_U", 0x1C, NULL),
9114 .skip = (ctx->addresses_all_num < 3),
9115 .wins = {
9116 .nb_flags = NBT_NM_GROUP,
9117 .mhomed = false,
9118 .num_ips = ctx->addresses_mhomed_num,
9119 .ips = ctx->addresses_mhomed,
9120 .apply_expected = true
9122 .defend = {
9123 .timeout = 0,
9125 .replica= {
9126 .type = WREPL_TYPE_SGROUP,
9127 .state = WREPL_STATE_ACTIVE,
9128 .node = WREPL_NODE_B,
9129 .is_static = false,
9130 .num_ips = ctx->addresses_mhomed_num,
9131 .ips = ctx->addresses_mhomed,
9132 .sgroup_merge = true
9136 * sgroup,active vs. sgroup,active with superset ip(s)
9139 .tctx = tctx,
9140 .line = __location__,
9141 .name = _NBT_NAME("_SA_SA_SP_U", 0x1C, NULL),
9142 .skip = (ctx->addresses_all_num < 3),
9143 .wins = {
9144 .nb_flags = NBT_NM_GROUP,
9145 .mhomed = false,
9146 .num_ips = ctx->addresses_mhomed_num,
9147 .ips = ctx->addresses_mhomed,
9148 .apply_expected = true
9150 .defend = {
9151 .timeout = 0,
9153 .replica= {
9154 .type = WREPL_TYPE_SGROUP,
9155 .state = WREPL_STATE_ACTIVE,
9156 .node = WREPL_NODE_B,
9157 .is_static = false,
9158 .num_ips = ctx->addresses_all_num,
9159 .ips = ctx->addresses_all,
9160 .sgroup_merge = true
9164 * sgroup,active vs. sgroup,active with subset ip(s)
9167 .tctx = tctx,
9168 .line = __location__,
9169 .name = _NBT_NAME("_SA_SA_SB_U", 0x1C, NULL),
9170 .skip = (ctx->addresses_all_num < 3),
9171 .wins = {
9172 .nb_flags = NBT_NM_GROUP,
9173 .mhomed = false,
9174 .num_ips = ctx->addresses_mhomed_num,
9175 .ips = ctx->addresses_mhomed,
9176 .apply_expected = true
9178 .defend = {
9179 .timeout = 0,
9181 .replica= {
9182 .type = WREPL_TYPE_SGROUP,
9183 .state = WREPL_STATE_ACTIVE,
9184 .node = WREPL_NODE_B,
9185 .is_static = false,
9186 .num_ips = ctx->addresses_best_num,
9187 .ips = ctx->addresses_best,
9188 .sgroup_merge = true
9192 * sgroup,active vs. sgroup,tombstone with different ip(s)
9195 .tctx = tctx,
9196 .line = __location__,
9197 .name = _NBT_NAME("_SA_ST_DI_U", 0x1C, NULL),
9198 .skip = (ctx->addresses_all_num < 3),
9199 .wins = {
9200 .nb_flags = NBT_NM_GROUP,
9201 .mhomed = false,
9202 .num_ips = ctx->addresses_mhomed_num,
9203 .ips = ctx->addresses_mhomed,
9204 .apply_expected = true
9206 .defend = {
9207 .timeout = 0,
9209 .replica= {
9210 .type = WREPL_TYPE_SGROUP,
9211 .state = WREPL_STATE_TOMBSTONE,
9212 .node = WREPL_NODE_B,
9213 .is_static = false,
9214 .num_ips = ARRAY_SIZE(addresses_B_3_4),
9215 .ips = addresses_B_3_4,
9216 .apply_expected = false
9220 * sgroup,active vs. sgroup,tombstone with same ip(s)
9223 .tctx = tctx,
9224 .line = __location__,
9225 .name = _NBT_NAME("_SA_ST_SI_U", 0x1C, NULL),
9226 .skip = (ctx->addresses_all_num < 3),
9227 .wins = {
9228 .nb_flags = NBT_NM_GROUP,
9229 .mhomed = false,
9230 .num_ips = ctx->addresses_mhomed_num,
9231 .ips = ctx->addresses_mhomed,
9232 .apply_expected = true
9234 .defend = {
9235 .timeout = 0,
9237 .replica= {
9238 .type = WREPL_TYPE_SGROUP,
9239 .state = WREPL_STATE_TOMBSTONE,
9240 .node = WREPL_NODE_B,
9241 .is_static = false,
9242 .num_ips = ctx->addresses_mhomed_num,
9243 .ips = ctx->addresses_mhomed,
9244 .apply_expected = false
9248 * sgroup,active vs. sgroup,tombstone with superset ip(s)
9251 .tctx = tctx,
9252 .line = __location__,
9253 .name = _NBT_NAME("_SA_ST_SP_U", 0x1C, NULL),
9254 .skip = (ctx->addresses_all_num < 3),
9255 .wins = {
9256 .nb_flags = NBT_NM_GROUP,
9257 .mhomed = false,
9258 .num_ips = ctx->addresses_mhomed_num,
9259 .ips = ctx->addresses_mhomed,
9260 .apply_expected = true
9262 .defend = {
9263 .timeout = 0,
9265 .replica= {
9266 .type = WREPL_TYPE_SGROUP,
9267 .state = WREPL_STATE_TOMBSTONE,
9268 .node = WREPL_NODE_B,
9269 .is_static = false,
9270 .num_ips = ctx->addresses_all_num,
9271 .ips = ctx->addresses_all,
9272 .apply_expected = false
9276 * sgroup,active vs. sgroup,tombstone with subset ip(s)
9279 .tctx = tctx,
9280 .line = __location__,
9281 .name = _NBT_NAME("_SA_ST_SB_U", 0x1C, NULL),
9282 .skip = (ctx->addresses_all_num < 3),
9283 .wins = {
9284 .nb_flags = NBT_NM_GROUP,
9285 .mhomed = false,
9286 .num_ips = ctx->addresses_mhomed_num,
9287 .ips = ctx->addresses_mhomed,
9288 .apply_expected = true
9290 .defend = {
9291 .timeout = 0,
9293 .replica= {
9294 .type = WREPL_TYPE_SGROUP,
9295 .state = WREPL_STATE_TOMBSTONE,
9296 .node = WREPL_NODE_B,
9297 .is_static = false,
9298 .num_ips = ctx->addresses_best_num,
9299 .ips = ctx->addresses_best,
9300 .apply_expected = false
9305 if (!ctx->nbtsock_srv) {
9306 torture_comment(tctx, "SKIP: Test Replica records vs. owned active records: not bound to port[%d]\n",
9307 lpcfg_nbt_port(tctx->lp_ctx));
9308 return true;
9311 torture_comment(tctx, "Test Replica records vs. owned active records\n");
9313 for(i=0; ret && i < ARRAY_SIZE(records); i++) {
9314 struct timeval end;
9315 struct test_conflict_owned_active_vs_replica_struct record = records[i];
9316 uint32_t j, count = 1;
9317 const char *action;
9319 if (records[i].wins.mhomed || records[i].name.type == 0x1C) {
9320 count = records[i].wins.num_ips;
9323 if (records[i].section) {
9324 torture_comment(tctx, "%s\n", records[i].section);
9327 if (records[i].skip) {
9328 torture_comment(tctx, "%s => SKIPPED\n", nbt_name_string(ctx, &records[i].name));
9329 continue;
9332 if (records[i].replica.mhomed_merge) {
9333 action = "MHOMED_MERGE";
9334 } else if (records[i].replica.sgroup_merge) {
9335 action = "SGROUP_MERGE";
9336 } else if (records[i].replica.apply_expected) {
9337 action = "REPLACE";
9338 } else {
9339 action = "NOT REPLACE";
9342 torture_comment(tctx, "%s%s%s => %s\n",
9343 nbt_name_string(ctx, &records[i].name),
9344 (records[i].comment?": ":""),
9345 (records[i].comment?records[i].comment:""),
9346 action);
9348 /* Prepare for multi homed registration */
9349 ZERO_STRUCT(records[i].defend);
9350 records[i].defend.timeout = 10;
9351 records[i].defend.positive = true;
9352 nbt_set_incoming_handler(ctx->nbtsock_srv,
9353 test_conflict_owned_active_vs_replica_handler,
9354 &records[i]);
9355 if (ctx->nbtsock_srv2) {
9356 nbt_set_incoming_handler(ctx->nbtsock_srv2,
9357 test_conflict_owned_active_vs_replica_handler,
9358 &records[i]);
9362 * Setup Register
9364 for (j=0; j < count; j++) {
9365 struct nbt_name_request *req;
9367 name_register->in.name = records[i].name;
9368 name_register->in.dest_addr = ctx->address;
9369 name_register->in.dest_port = lpcfg_nbt_port(tctx->lp_ctx);
9370 name_register->in.address = records[i].wins.ips[j].ip;
9371 name_register->in.nb_flags = records[i].wins.nb_flags;
9372 name_register->in.register_demand= false;
9373 name_register->in.broadcast = false;
9374 name_register->in.multi_homed = records[i].wins.mhomed;
9375 name_register->in.ttl = 300000;
9376 name_register->in.timeout = 70;
9377 name_register->in.retries = 0;
9379 req = nbt_name_register_send(ctx->nbtsock, name_register);
9381 /* push the request on the wire */
9382 tevent_loop_once(ctx->nbtsock->event_ctx);
9385 * if we register multiple addresses,
9386 * the server will do name queries to see if the old addresses
9387 * are still alive
9389 if (records[i].wins.mhomed && j > 0) {
9390 end = timeval_current_ofs(records[i].defend.timeout,0);
9391 records[i].defend.ret = true;
9392 while (records[i].defend.timeout > 0) {
9393 tevent_loop_once(ctx->nbtsock_srv->event_ctx);
9394 if (timeval_expired(&end)) break;
9396 ret &= records[i].defend.ret;
9399 status = nbt_name_register_recv(req, ctx, name_register);
9400 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
9401 torture_comment(tctx, "No response from %s for name register\n", ctx->address);
9402 ret = false;
9404 if (!NT_STATUS_IS_OK(status)) {
9405 torture_comment(tctx, "Bad response from %s for name register - %s\n",
9406 ctx->address, nt_errstr(status));
9407 ret = false;
9409 CHECK_VALUE(tctx, name_register->out.rcode, 0);
9410 CHECK_VALUE_STRING(tctx, name_register->out.reply_from, ctx->address);
9411 CHECK_VALUE(tctx, name_register->out.name.type, records[i].name.type);
9412 CHECK_VALUE_STRING(tctx, name_register->out.name.name, records[i].name.name);
9413 CHECK_VALUE_STRING(tctx, name_register->out.name.scope, records[i].name.scope);
9414 CHECK_VALUE_STRING(tctx, name_register->out.reply_addr, records[i].wins.ips[j].ip);
9417 /* Prepare for the current test */
9418 records[i].defend = record.defend;
9419 nbt_set_incoming_handler(ctx->nbtsock_srv,
9420 test_conflict_owned_active_vs_replica_handler,
9421 &records[i]);
9422 if (ctx->nbtsock_srv2) {
9423 nbt_set_incoming_handler(ctx->nbtsock_srv2,
9424 test_conflict_owned_active_vs_replica_handler,
9425 &records[i]);
9429 * Setup Replica
9431 wins_name->name = &records[i].name;
9432 wins_name->flags = WREPL_NAME_FLAGS(records[i].replica.type,
9433 records[i].replica.state,
9434 records[i].replica.node,
9435 records[i].replica.is_static);
9436 wins_name->id = ++ctx->b.max_version;
9437 if (wins_name->flags & 2) {
9438 wins_name->addresses.addresses.num_ips = records[i].replica.num_ips;
9439 wins_name->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
9440 records[i].replica.ips);
9441 } else {
9442 wins_name->addresses.ip = records[i].replica.ips[0].ip;
9444 wins_name->unknown = "255.255.255.255";
9446 ret &= test_wrepl_update_one(tctx, ctx, &ctx->b, wins_name);
9449 * wait for the name query, which is handled in
9450 * test_conflict_owned_active_vs_replica_handler()
9452 end = timeval_current_ofs(records[i].defend.timeout,0);
9453 records[i].defend.ret = true;
9454 while (records[i].defend.timeout > 0) {
9455 tevent_loop_once(ctx->nbtsock_srv->event_ctx);
9456 if (timeval_expired(&end)) break;
9458 ret &= records[i].defend.ret;
9460 if (records[i].defend.late_release) {
9461 records[i].defend = record.defend;
9462 records[i].defend.expect_release = true;
9464 * wait for the name release demand, which is handled in
9465 * test_conflict_owned_active_vs_replica_handler()
9467 end = timeval_current_ofs(records[i].defend.timeout,0);
9468 records[i].defend.ret = true;
9469 while (records[i].defend.timeout > 0) {
9470 tevent_loop_once(ctx->nbtsock_srv->event_ctx);
9471 if (timeval_expired(&end)) break;
9473 ret &= records[i].defend.ret;
9476 if (records[i].replica.mhomed_merge) {
9477 ret &= test_wrepl_mhomed_merged(tctx, ctx, &ctx->c,
9478 records[i].wins.num_ips, records[i].wins.ips,
9479 &ctx->b,
9480 records[i].replica.num_ips, records[i].replica.ips,
9481 wins_name);
9482 } else if (records[i].replica.sgroup_merge) {
9483 ret &= test_wrepl_sgroup_merged(tctx, ctx, NULL,
9484 &ctx->c,
9485 records[i].wins.num_ips, records[i].wins.ips,
9486 &ctx->b,
9487 records[i].replica.num_ips, records[i].replica.ips,
9488 wins_name);
9489 } else {
9490 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->b, wins_name,
9491 records[i].replica.apply_expected);
9494 if (records[i].replica.apply_expected ||
9495 records[i].replica.mhomed_merge) {
9496 wins_name->name = &records[i].name;
9497 wins_name->flags = WREPL_NAME_FLAGS(WREPL_TYPE_UNIQUE,
9498 WREPL_STATE_TOMBSTONE,
9499 WREPL_NODE_B, false);
9500 wins_name->id = ++ctx->b.max_version;
9501 wins_name->addresses.ip = addresses_B_1[0].ip;
9502 wins_name->unknown = "255.255.255.255";
9504 ret &= test_wrepl_update_one(tctx, ctx, &ctx->b, wins_name);
9505 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->b, wins_name, true);
9506 } else {
9507 for (j=0; j < count; j++) {
9508 struct nbt_name_socket *nbtsock = ctx->nbtsock;
9510 if (ctx->myaddr2 && strcmp(records[i].wins.ips[j].ip, ctx->myaddr2->addr) == 0) {
9511 nbtsock = ctx->nbtsock2;
9514 release->in.name = records[i].name;
9515 release->in.dest_addr = ctx->address;
9516 release->in.dest_port = lpcfg_nbt_port(tctx->lp_ctx);
9517 release->in.address = records[i].wins.ips[j].ip;
9518 release->in.nb_flags = records[i].wins.nb_flags;
9519 release->in.broadcast = false;
9520 release->in.timeout = 30;
9521 release->in.retries = 0;
9523 status = nbt_name_release(nbtsock, ctx, release);
9524 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
9525 torture_comment(tctx, "No response from %s for name release\n", ctx->address);
9526 return false;
9528 if (!NT_STATUS_IS_OK(status)) {
9529 torture_comment(tctx, "Bad response from %s for name query - %s\n",
9530 ctx->address, nt_errstr(status));
9531 return false;
9533 CHECK_VALUE(tctx, release->out.rcode, 0);
9536 if (records[i].replica.sgroup_merge) {
9537 /* clean up the SGROUP record */
9538 wins_name->name = &records[i].name;
9539 wins_name->flags = WREPL_NAME_FLAGS(WREPL_TYPE_SGROUP,
9540 WREPL_STATE_ACTIVE,
9541 WREPL_NODE_B, false);
9542 wins_name->id = ++ctx->b.max_version;
9543 wins_name->addresses.addresses.num_ips = 0;
9544 wins_name->addresses.addresses.ips = NULL;
9545 wins_name->unknown = "255.255.255.255";
9546 ret &= test_wrepl_update_one(tctx, ctx, &ctx->b, wins_name);
9548 /* take ownership of the SGROUP record */
9549 wins_name->name = &records[i].name;
9550 wins_name->flags = WREPL_NAME_FLAGS(WREPL_TYPE_SGROUP,
9551 WREPL_STATE_ACTIVE,
9552 WREPL_NODE_B, false);
9553 wins_name->id = ++ctx->b.max_version;
9554 wins_name->addresses.addresses.num_ips = ARRAY_SIZE(addresses_B_1);
9555 wins_name->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
9556 addresses_B_1);
9557 wins_name->unknown = "255.255.255.255";
9558 ret &= test_wrepl_update_one(tctx, ctx, &ctx->b, wins_name);
9559 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->b, wins_name, true);
9561 /* overwrite the SGROUP record with unique,tombstone */
9562 wins_name->name = &records[i].name;
9563 wins_name->flags = WREPL_NAME_FLAGS(WREPL_TYPE_UNIQUE,
9564 WREPL_STATE_TOMBSTONE,
9565 WREPL_NODE_B, false);
9566 wins_name->id = ++ctx->b.max_version;
9567 wins_name->addresses.ip = addresses_A_1[0].ip;
9568 wins_name->unknown = "255.255.255.255";
9569 ret &= test_wrepl_update_one(tctx, ctx, &ctx->b, wins_name);
9570 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->b, wins_name, true);
9574 if (!ret) {
9575 torture_comment(tctx, "conflict handled wrong or record[%u]: %s\n", i, records[i].line);
9576 return ret;
9580 return ret;
9583 #define __NBT_LABEL_CAT1__(a,b) a##b
9584 #define __NBT_LABEL_CAT2__(a,b) __NBT_LABEL_CAT1__(a,b)
9585 #define _NBT_LABEL __NBT_LABEL_CAT2__(_label_, __LINE__)
9587 #define _NBT_ASSERT(v, correct) do { \
9588 bool _ret = true; \
9589 torture_assert_int_equal_goto(rec->tctx, v, correct, \
9590 _ret, _NBT_LABEL, "Invalid int value"); \
9591 _NBT_LABEL: \
9592 if (!_ret) { \
9593 return; \
9595 } while (0)
9597 #define _NBT_ASSERT_STRING(v, correct) do { \
9598 bool _ret = true; \
9599 torture_assert_str_equal_goto(rec->tctx, v, correct, \
9600 _ret, _NBT_LABEL, "Invalid string value"); \
9601 _NBT_LABEL: \
9602 if (!_ret) { \
9603 return; \
9605 } while (0)
9607 static void test_conflict_owned_active_vs_replica_handler_query(struct nbt_name_socket *nbtsock,
9608 struct nbt_name_packet *req_packet,
9609 struct socket_address *src)
9611 struct nbt_name *name;
9612 struct nbt_name_packet *rep_packet;
9613 struct test_conflict_owned_active_vs_replica_struct *rec =
9614 (struct test_conflict_owned_active_vs_replica_struct *)nbtsock->incoming.private_data;
9616 _NBT_ASSERT(req_packet->qdcount, 1);
9617 _NBT_ASSERT(req_packet->questions[0].question_type, NBT_QTYPE_NETBIOS);
9618 _NBT_ASSERT(req_packet->questions[0].question_class, NBT_QCLASS_IP);
9620 name = &req_packet->questions[0].name;
9622 _NBT_ASSERT_STRING(name->name, rec->name.name);
9623 _NBT_ASSERT(name->type, rec->name.type);
9624 _NBT_ASSERT_STRING(name->scope, rec->name.scope);
9626 _NBT_ASSERT(rec->defend.expect_release, false);
9628 rep_packet = talloc_zero(nbtsock, struct nbt_name_packet);
9629 if (rep_packet == NULL) return;
9631 rep_packet->name_trn_id = req_packet->name_trn_id;
9632 rep_packet->ancount = 1;
9634 rep_packet->answers = talloc_array(rep_packet, struct nbt_res_rec, 1);
9635 if (rep_packet->answers == NULL) return;
9637 rep_packet->answers[0].name = *name;
9638 rep_packet->answers[0].rr_class = NBT_QCLASS_IP;
9639 rep_packet->answers[0].ttl = 0;
9641 if (rec->defend.positive) {
9642 uint32_t i, num_ips;
9643 const struct wrepl_ip *ips;
9645 if (rec->defend.num_ips > 0) {
9646 num_ips = rec->defend.num_ips;
9647 ips = rec->defend.ips;
9648 } else {
9649 num_ips = rec->wins.num_ips;
9650 ips = rec->wins.ips;
9653 /* send a positive reply */
9654 rep_packet->operation =
9655 NBT_FLAG_REPLY |
9656 NBT_OPCODE_QUERY |
9657 NBT_FLAG_AUTHORITATIVE |
9658 NBT_FLAG_RECURSION_DESIRED |
9659 NBT_FLAG_RECURSION_AVAIL;
9661 rep_packet->answers[0].rr_type = NBT_QTYPE_NETBIOS;
9663 rep_packet->answers[0].rdata.netbios.length = num_ips*6;
9664 rep_packet->answers[0].rdata.netbios.addresses =
9665 talloc_array(rep_packet->answers, struct nbt_rdata_address, num_ips);
9666 if (rep_packet->answers[0].rdata.netbios.addresses == NULL) return;
9668 for (i=0; i < num_ips; i++) {
9669 struct nbt_rdata_address *addr =
9670 &rep_packet->answers[0].rdata.netbios.addresses[i];
9671 addr->nb_flags = rec->wins.nb_flags;
9672 addr->ipaddr = ips[i].ip;
9674 DEBUG(2,("Sending positive name query reply for %s to %s:%d\n",
9675 nbt_name_string(rep_packet, name), src->addr, src->port));
9676 } else {
9677 /* send a negative reply */
9678 rep_packet->operation =
9679 NBT_FLAG_REPLY |
9680 NBT_OPCODE_QUERY |
9681 NBT_FLAG_AUTHORITATIVE |
9682 NBT_RCODE_NAM;
9684 rep_packet->answers[0].rr_type = NBT_QTYPE_NULL;
9686 ZERO_STRUCT(rep_packet->answers[0].rdata);
9688 DEBUG(2,("Sending negative name query reply for %s to %s:%d\n",
9689 nbt_name_string(rep_packet, name), src->addr, src->port));
9692 nbt_name_reply_send(nbtsock, src, rep_packet);
9693 talloc_free(rep_packet);
9695 /* make sure we push the reply to the wire */
9696 while (nbtsock->send_queue) {
9697 tevent_loop_once(nbtsock->event_ctx);
9699 smb_msleep(1000);
9701 rec->defend.timeout = 0;
9702 rec->defend.ret = true;
9705 static void test_conflict_owned_active_vs_replica_handler_release(
9706 struct nbt_name_socket *nbtsock,
9707 struct nbt_name_packet *req_packet,
9708 struct socket_address *src)
9710 struct nbt_name *name;
9711 struct nbt_name_packet *rep_packet;
9712 struct test_conflict_owned_active_vs_replica_struct *rec =
9713 (struct test_conflict_owned_active_vs_replica_struct *)nbtsock->incoming.private_data;
9715 _NBT_ASSERT(req_packet->qdcount, 1);
9716 _NBT_ASSERT(req_packet->questions[0].question_type, NBT_QTYPE_NETBIOS);
9717 _NBT_ASSERT(req_packet->questions[0].question_class, NBT_QCLASS_IP);
9719 name = &req_packet->questions[0].name;
9721 _NBT_ASSERT_STRING(name->name, rec->name.name);
9722 _NBT_ASSERT(name->type, rec->name.type);
9723 _NBT_ASSERT_STRING(name->scope, rec->name.scope);
9725 _NBT_ASSERT(rec->defend.expect_release, true);
9727 rep_packet = talloc_zero(nbtsock, struct nbt_name_packet);
9728 if (rep_packet == NULL) return;
9730 rep_packet->name_trn_id = req_packet->name_trn_id;
9731 rep_packet->ancount = 1;
9732 rep_packet->operation =
9733 NBT_FLAG_REPLY |
9734 NBT_OPCODE_RELEASE |
9735 NBT_FLAG_AUTHORITATIVE;
9737 rep_packet->answers = talloc_array(rep_packet, struct nbt_res_rec, 1);
9738 if (rep_packet->answers == NULL) return;
9740 rep_packet->answers[0].name = *name;
9741 rep_packet->answers[0].rr_type = NBT_QTYPE_NETBIOS;
9742 rep_packet->answers[0].rr_class = NBT_QCLASS_IP;
9743 rep_packet->answers[0].ttl = req_packet->additional[0].ttl;
9744 rep_packet->answers[0].rdata = req_packet->additional[0].rdata;
9746 DEBUG(2,("Sending name release reply for %s to %s:%d\n",
9747 nbt_name_string(rep_packet, name), src->addr, src->port));
9749 nbt_name_reply_send(nbtsock, src, rep_packet);
9750 talloc_free(rep_packet);
9752 /* make sure we push the reply to the wire */
9753 while (nbtsock->send_queue) {
9754 tevent_loop_once(nbtsock->event_ctx);
9756 smb_msleep(1000);
9758 rec->defend.timeout = 0;
9759 rec->defend.ret = true;
9762 static void test_conflict_owned_active_vs_replica_handler(struct nbt_name_socket *nbtsock,
9763 struct nbt_name_packet *req_packet,
9764 struct socket_address *src)
9766 struct test_conflict_owned_active_vs_replica_struct *rec =
9767 (struct test_conflict_owned_active_vs_replica_struct *)nbtsock->incoming.private_data;
9768 struct nbt_name *name = &req_packet->questions[0].name;
9770 if (req_packet->operation & NBT_FLAG_BROADCAST) {
9771 torture_comment(rec->tctx,
9772 "%s: incoming packet name[%s] flags[0x%08X] from[%s]\n",
9773 __location__,
9774 nbt_name_string(rec->tctx, name),
9775 req_packet->operation,
9776 src->addr);
9777 return;
9780 rec->defend.ret = false;
9782 switch (req_packet->operation & NBT_OPCODE) {
9783 case NBT_OPCODE_QUERY:
9784 test_conflict_owned_active_vs_replica_handler_query(nbtsock, req_packet, src);
9785 break;
9786 case NBT_OPCODE_RELEASE:
9787 test_conflict_owned_active_vs_replica_handler_release(nbtsock, req_packet, src);
9788 break;
9789 default:
9790 torture_comment(rec->tctx,
9791 "%s: unexpected packet name[%s] flags[0x%08X] from[%s]\n",
9792 __location__,
9793 nbt_name_string(rec->tctx, name),
9794 req_packet->operation,
9795 src->addr);
9796 _NBT_ASSERT((req_packet->operation & NBT_OPCODE), NBT_OPCODE_QUERY);
9797 break;
9802 test WINS replication replica conflicts operations
9804 static bool torture_nbt_winsreplication_replica(struct torture_context *tctx)
9806 bool ret = true;
9807 struct test_wrepl_conflict_conn *ctx;
9809 const char *address;
9810 struct nbt_name name;
9812 if (!torture_nbt_get_name(tctx, &name, &address))
9813 return false;
9815 ctx = test_create_conflict_ctx(tctx, address);
9816 if (!ctx) return false;
9818 ret &= test_conflict_same_owner(tctx, ctx);
9819 ret &= test_conflict_different_owner(tctx, ctx);
9821 return ret;
9825 test WINS replication owned conflicts operations
9827 static bool torture_nbt_winsreplication_owned(struct torture_context *tctx)
9829 const char *address;
9830 struct nbt_name name;
9831 bool ret = true;
9832 struct test_wrepl_conflict_conn *ctx;
9834 if (torture_setting_bool(tctx, "quick", false))
9835 torture_skip(tctx,
9836 "skip NBT-WINSREPLICATION-OWNED test in quick test mode\n");
9838 if (!torture_nbt_get_name(tctx, &name, &address))
9839 return false;
9841 ctx = test_create_conflict_ctx(tctx, address);
9842 torture_assert(tctx, ctx != NULL, "Creating context failed");
9844 ret &= test_conflict_owned_released_vs_replica(tctx, ctx);
9845 ret &= test_conflict_owned_active_vs_replica(tctx, ctx);
9847 return ret;
9851 test simple WINS replication operations
9853 struct torture_suite *torture_nbt_winsreplication(TALLOC_CTX *mem_ctx)
9855 struct torture_suite *suite = torture_suite_create(
9856 mem_ctx, "winsreplication");
9857 struct torture_tcase *tcase;
9859 tcase = torture_suite_add_simple_test(suite, "assoc_ctx1",
9860 test_assoc_ctx1);
9861 tcase->tests->dangerous = true;
9863 torture_suite_add_simple_test(suite, "assoc_ctx2", test_assoc_ctx2);
9865 torture_suite_add_simple_test(suite, "wins_replication",
9866 test_wins_replication);
9868 torture_suite_add_simple_test(suite, "replica",
9869 torture_nbt_winsreplication_replica);
9871 torture_suite_add_simple_test(suite, "owned",
9872 torture_nbt_winsreplication_owned);
9874 return suite;