r11186: - get rid of some .extra = True cases
[jra/samba/.git] / source4 / torture / nbt / winsreplication.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    WINS replication testing
5
6    Copyright (C) Andrew Tridgell 2005
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "libcli/nbt/libnbt.h"
25 #include "libcli/wrepl/winsrepl.h"
26
27 #define CHECK_STATUS(status, correct) do { \
28         if (!NT_STATUS_EQUAL(status, correct)) { \
29                 printf("(%s) Incorrect status %s - should be %s\n", \
30                        __location__, nt_errstr(status), nt_errstr(correct)); \
31                 ret = False; \
32                 goto done; \
33         }} while (0)
34
35 #define CHECK_VALUE(v, correct) do { \
36         if ((v) != (correct)) { \
37                 printf("(%s) Incorrect value %s=%d - should be %d\n", \
38                        __location__, #v, v, correct); \
39                 ret = False; \
40                 goto done; \
41         }} while (0)
42
43 #define CHECK_VALUE_UINT64(v, correct) do { \
44         if ((v) != (correct)) { \
45                 printf("(%s) Incorrect value %s=%llu - should be %llu\n", \
46                        __location__, #v, v, correct); \
47                 ret = False; \
48                 goto done; \
49         }} while (0)
50
51 #define CHECK_VALUE_STRING(v, correct) do { \
52         if ( ((!v) && (correct)) || \
53              ((v) && (!correct)) || \
54              ((v) && (correct) && strcmp(v,correct) != 0)) { \
55                 printf("(%s) Incorrect value %s='%s' - should be '%s'\n", \
56                        __location__, #v, v, correct); \
57                 ret = False; \
58                 goto done; \
59         }} while (0)
60
61 #define _NBT_NAME(n,t,s) {\
62         .name   = n,\
63         .type   = t,\
64         .scope  = s\
65 }
66
67 static const char *wrepl_name_type_string(enum wrepl_name_type type)
68 {
69         switch (type) {
70         case WREPL_TYPE_UNIQUE: return "UNIQUE";
71         case WREPL_TYPE_GROUP: return "GROUP";
72         case WREPL_TYPE_SGROUP: return "SGROUP";
73         case WREPL_TYPE_MHOMED: return "MHOMED";
74         }
75         return "UNKNOWN_TYPE";
76 }
77
78 static const char *wrepl_name_state_string(enum wrepl_name_state state)
79 {
80         switch (state) {
81         case WREPL_STATE_ACTIVE: return "ACTIVE";
82         case WREPL_STATE_RELEASED: return "RELEASED";
83         case WREPL_STATE_TOMBSTONE: return "TOMBSTONE";
84         case WREPL_STATE_RESERVED: return "RESERVED";
85         }
86         return "UNKNOWN_STATE";
87 }
88
89 /*
90   test how assoc_ctx's are only usable on the connection
91   they are created on.
92 */
93 static BOOL test_assoc_ctx1(TALLOC_CTX *mem_ctx, const char *address)
94 {
95         BOOL ret = True;
96         struct wrepl_request *req;
97         struct wrepl_socket *wrepl_socket1;
98         struct wrepl_associate associate1;
99         struct wrepl_socket *wrepl_socket2;
100         struct wrepl_associate associate2;
101         struct wrepl_pull_table pull_table;
102         struct wrepl_packet *rep_packet;
103         struct wrepl_associate_stop assoc_stop;
104         NTSTATUS status;
105
106         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
107                 printf("winsrepl: cross connection assoc_ctx usage disabled - enable dangerous tests to use\n");
108                 return True;
109         }
110
111         printf("Test if assoc_ctx is only valid on the conection it was created on\n");
112
113         wrepl_socket1 = wrepl_socket_init(mem_ctx, NULL);
114         wrepl_socket2 = wrepl_socket_init(mem_ctx, NULL);
115
116         printf("Setup 2 wrepl connections\n");
117         status = wrepl_connect(wrepl_socket1, NULL, address);
118         CHECK_STATUS(status, NT_STATUS_OK);
119
120         status = wrepl_connect(wrepl_socket2, NULL, address);
121         CHECK_STATUS(status, NT_STATUS_OK);
122
123         printf("Send a start association request (conn1)\n");
124         status = wrepl_associate(wrepl_socket1, &associate1);
125         CHECK_STATUS(status, NT_STATUS_OK);
126
127         printf("association context (conn1): 0x%x\n", associate1.out.assoc_ctx);
128
129         printf("Send a start association request (conn2)\n");
130         status = wrepl_associate(wrepl_socket2, &associate2);
131         CHECK_STATUS(status, NT_STATUS_OK);
132
133         printf("association context (conn2): 0x%x\n", associate2.out.assoc_ctx);
134
135         printf("Send a replication table query, with assoc 1 (conn2), the anwser should be on conn1\n");
136         pull_table.in.assoc_ctx = associate1.out.assoc_ctx;
137         req = wrepl_pull_table_send(wrepl_socket2, &pull_table);
138         req->send_only = True;
139         status = wrepl_request_recv(req, mem_ctx, &rep_packet);
140         CHECK_STATUS(status, NT_STATUS_OK);
141
142         printf("Send a association request (conn2), to make sure the last request was ignored\n");
143         status = wrepl_associate(wrepl_socket2, &associate2);
144         CHECK_STATUS(status, NT_STATUS_OK);
145
146         printf("Send a replication table query, with invalid assoc (conn1), receive answer from conn2\n");
147         pull_table.in.assoc_ctx = 0;
148         req = wrepl_pull_table_send(wrepl_socket1, &pull_table);
149         status = wrepl_request_recv(req, mem_ctx, &rep_packet);
150         CHECK_STATUS(status, NT_STATUS_OK);
151
152         printf("Send a association request (conn1), to make sure the last request was handled correct\n");
153         status = wrepl_associate(wrepl_socket1, &associate2);
154         CHECK_STATUS(status, NT_STATUS_OK);
155
156         assoc_stop.in.assoc_ctx = associate1.out.assoc_ctx;
157         assoc_stop.in.reason    = 4;
158         printf("Send a association stop request (conn1), reson: %u\n", assoc_stop.in.reason);
159         status = wrepl_associate_stop(wrepl_socket1, &assoc_stop);
160         CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
161
162         assoc_stop.in.assoc_ctx = associate2.out.assoc_ctx;
163         assoc_stop.in.reason    = 0;
164         printf("Send a association stop request (conn2), reson: %u\n", assoc_stop.in.reason);
165         status = wrepl_associate_stop(wrepl_socket2, &assoc_stop);
166         CHECK_STATUS(status, NT_STATUS_OK);
167
168 done:
169         printf("Close 2 wrepl connections\n");
170         talloc_free(wrepl_socket1);
171         talloc_free(wrepl_socket2);
172         return ret;
173 }
174
175 /*
176   test if we always get back the same assoc_ctx
177 */
178 static BOOL test_assoc_ctx2(TALLOC_CTX *mem_ctx, const char *address)
179 {
180         BOOL ret = True;
181         struct wrepl_socket *wrepl_socket;
182         struct wrepl_associate associate;
183         uint32_t assoc_ctx1;
184         NTSTATUS status;
185
186         printf("Test if we always get back the same assoc_ctx\n");
187
188         wrepl_socket = wrepl_socket_init(mem_ctx, NULL);
189         
190         printf("Setup wrepl connections\n");
191         status = wrepl_connect(wrepl_socket, NULL, address);
192         CHECK_STATUS(status, NT_STATUS_OK);
193
194
195         printf("Send 1st start association request\n");
196         status = wrepl_associate(wrepl_socket, &associate);
197         CHECK_STATUS(status, NT_STATUS_OK);
198         assoc_ctx1 = associate.out.assoc_ctx;
199         printf("1st association context: 0x%x\n", associate.out.assoc_ctx);
200
201         printf("Send 2nd start association request\n");
202         status = wrepl_associate(wrepl_socket, &associate);
203         CHECK_VALUE(associate.out.assoc_ctx, assoc_ctx1);
204         CHECK_STATUS(status, NT_STATUS_OK);
205         printf("2nd association context: 0x%x\n", associate.out.assoc_ctx);
206
207         printf("Send 3rd start association request\n");
208         status = wrepl_associate(wrepl_socket, &associate);
209         CHECK_VALUE(associate.out.assoc_ctx, assoc_ctx1);
210         CHECK_STATUS(status, NT_STATUS_OK);
211         printf("3rd association context: 0x%x\n", associate.out.assoc_ctx);
212
213 done:
214         printf("Close wrepl connections\n");
215         talloc_free(wrepl_socket);
216         return ret;
217 }
218
219
220 /*
221   display a replication entry
222 */
223 static void display_entry(TALLOC_CTX *mem_ctx, struct wrepl_name *name)
224 {
225         int i;
226
227         printf("%s\n", nbt_name_string(mem_ctx, &name->name));
228         printf("\tTYPE:%u STATE:%u NODE:%u STATIC:%u VERSION_ID: %llu\n",
229                 name->type, name->state, name->node, name->is_static, name->version_id);
230         printf("\tRAW_FLAGS: 0x%08X OWNER: %-15s\n",
231                 name->raw_flags, name->owner);
232         for (i=0;i<name->num_addresses;i++) {
233                 printf("\tADDR: %-15s OWNER: %-15s\n", 
234                         name->addresses[i].address, name->addresses[i].owner);
235         }
236 }
237
238 /*
239   test a full replication dump from a WINS server
240 */
241 static BOOL test_wins_replication(TALLOC_CTX *mem_ctx, const char *address)
242 {
243         BOOL ret = True;
244         struct wrepl_socket *wrepl_socket;
245         NTSTATUS status;
246         int i, j;
247         struct wrepl_associate associate;
248         struct wrepl_pull_table pull_table;
249         struct wrepl_pull_names pull_names;
250
251         printf("Test one pull replication cycle\n");
252
253         wrepl_socket = wrepl_socket_init(mem_ctx, NULL);
254         
255         printf("Setup wrepl connections\n");
256         status = wrepl_connect(wrepl_socket, NULL, address);
257         CHECK_STATUS(status, NT_STATUS_OK);
258
259         printf("Send a start association request\n");
260
261         status = wrepl_associate(wrepl_socket, &associate);
262         CHECK_STATUS(status, NT_STATUS_OK);
263
264         printf("association context: 0x%x\n", associate.out.assoc_ctx);
265
266         printf("Send a replication table query\n");
267         pull_table.in.assoc_ctx = associate.out.assoc_ctx;
268
269         status = wrepl_pull_table(wrepl_socket, mem_ctx, &pull_table);
270         if (NT_STATUS_EQUAL(NT_STATUS_NETWORK_ACCESS_DENIED,status)) {
271                 struct wrepl_packet packet;
272                 struct wrepl_request *req;
273
274                 ZERO_STRUCT(packet);
275                 packet.opcode                      = WREPL_OPCODE_BITS;
276                 packet.assoc_ctx                   = associate.out.assoc_ctx;
277                 packet.mess_type                   = WREPL_STOP_ASSOCIATION;
278                 packet.message.stop.reason         = 0;
279
280                 req = wrepl_request_send(wrepl_socket, &packet);
281                 talloc_free(req);
282
283                 printf("failed - We are not a valid pull partner for the server\n");
284                 ret = False;
285                 goto done;
286         }
287         CHECK_STATUS(status, NT_STATUS_OK);
288
289         printf("Found %d replication partners\n", pull_table.out.num_partners);
290
291         for (i=0;i<pull_table.out.num_partners;i++) {
292                 struct wrepl_wins_owner *partner = &pull_table.out.partners[i];
293                 printf("%s   max_version=%6llu   min_version=%6llu type=%d\n",
294                        partner->address, 
295                        partner->max_version, 
296                        partner->min_version, 
297                        partner->type);
298
299                 pull_names.in.assoc_ctx = associate.out.assoc_ctx;
300                 pull_names.in.partner = *partner;
301                 
302                 status = wrepl_pull_names(wrepl_socket, mem_ctx, &pull_names);
303                 CHECK_STATUS(status, NT_STATUS_OK);
304
305                 printf("Received %d names\n", pull_names.out.num_names);
306
307                 for (j=0;j<pull_names.out.num_names;j++) {
308                         display_entry(mem_ctx, &pull_names.out.names[j]);
309                 }
310         }
311
312 done:
313         printf("Close wrepl connections\n");
314         talloc_free(wrepl_socket);
315         return ret;
316 }
317
318 struct test_wrepl_conflict_conn {
319         const char *address;
320         struct wrepl_socket *pull;
321         uint32_t pull_assoc;
322
323 #define TEST_OWNER_A_ADDRESS "127.65.65.1"
324 #define TEST_ADDRESS_A_PREFIX "127.0.65"
325 #define TEST_OWNER_B_ADDRESS "127.66.66.1"
326 #define TEST_ADDRESS_B_PREFIX "127.0.66"
327
328         struct wrepl_wins_owner a, b, c;
329 };
330
331 static const struct wrepl_ip addresses_A_1[] = {
332         {
333         .owner  = TEST_OWNER_A_ADDRESS,
334         .ip     = TEST_ADDRESS_A_PREFIX".1"
335         }
336 };
337 static const struct wrepl_ip addresses_A_2[] = {
338         {
339         .owner  = TEST_OWNER_A_ADDRESS,
340         .ip     = TEST_ADDRESS_A_PREFIX".2"
341         }
342 };
343 static const struct wrepl_ip addresses_A_3_4[] = {
344         {
345         .owner  = TEST_OWNER_A_ADDRESS,
346         .ip     = TEST_ADDRESS_A_PREFIX".3"
347         },
348         {
349         .owner  = TEST_OWNER_A_ADDRESS,
350         .ip     = TEST_ADDRESS_A_PREFIX".4"
351         }
352 };
353
354 static const struct wrepl_ip addresses_B_1[] = {
355         {
356         .owner  = TEST_OWNER_B_ADDRESS,
357         .ip     = TEST_ADDRESS_B_PREFIX".1"
358         }
359 };
360 static const struct wrepl_ip addresses_B_2[] = {
361         {
362         .owner  = TEST_OWNER_B_ADDRESS,
363         .ip     = TEST_ADDRESS_B_PREFIX".2"
364         }
365 };
366 static const struct wrepl_ip addresses_B_3_4[] = {
367         {
368         .owner  = TEST_OWNER_B_ADDRESS,
369         .ip     = TEST_ADDRESS_B_PREFIX".3"
370         },
371         {
372         .owner  = TEST_OWNER_B_ADDRESS,
373         .ip     = TEST_ADDRESS_B_PREFIX".4"
374         }
375 };
376
377 static struct test_wrepl_conflict_conn *test_create_conflict_ctx(TALLOC_CTX *mem_ctx,
378                                                                  const char *address)
379 {
380         struct test_wrepl_conflict_conn *ctx;
381         struct wrepl_associate associate;
382         struct wrepl_pull_table pull_table;
383         NTSTATUS status;
384         uint32_t i;
385
386         ctx = talloc_zero(mem_ctx, struct test_wrepl_conflict_conn);
387         if (!ctx) return NULL;
388
389         ctx->address    = address;
390         ctx->pull       = wrepl_socket_init(ctx, NULL);
391         if (!ctx->pull) return NULL;
392
393         printf("Setup wrepl conflict pull connection\n");
394         status = wrepl_connect(ctx->pull, NULL, ctx->address);
395         if (!NT_STATUS_IS_OK(status)) return NULL;
396
397         status = wrepl_associate(ctx->pull, &associate);
398         if (!NT_STATUS_IS_OK(status)) return NULL;
399
400         ctx->pull_assoc = associate.out.assoc_ctx;
401
402         ctx->a.address          = TEST_OWNER_A_ADDRESS;
403         ctx->a.max_version      = 0;
404         ctx->a.min_version      = 0;
405         ctx->a.type             = 1;
406
407         ctx->b.address          = TEST_OWNER_B_ADDRESS;
408         ctx->b.max_version      = 0;
409         ctx->b.min_version      = 0;
410         ctx->b.type             = 1;
411
412         ctx->c.address          = address;
413         ctx->c.max_version      = 0;
414         ctx->c.min_version      = 0;
415         ctx->c.type             = 1;
416
417         pull_table.in.assoc_ctx = ctx->pull_assoc;
418         status = wrepl_pull_table(ctx->pull, ctx->pull, &pull_table);
419         if (!NT_STATUS_IS_OK(status)) return NULL;
420
421         for (i=0; i < pull_table.out.num_partners; i++) {
422                 if (strcmp(TEST_OWNER_A_ADDRESS,pull_table.out.partners[i].address)==0) {
423                         ctx->a.max_version      = pull_table.out.partners[i].max_version;
424                         ctx->a.min_version      = pull_table.out.partners[i].min_version;
425                 }
426                 if (strcmp(TEST_OWNER_B_ADDRESS,pull_table.out.partners[i].address)==0) {
427                         ctx->b.max_version      = pull_table.out.partners[i].max_version;
428                         ctx->b.min_version      = pull_table.out.partners[i].min_version;
429                 }
430                 if (strcmp(address,pull_table.out.partners[i].address)==0) {
431                         ctx->c.max_version      = pull_table.out.partners[i].max_version;
432                         ctx->c.min_version      = pull_table.out.partners[i].min_version;
433                 }
434         }
435
436         talloc_free(pull_table.out.partners);
437
438         return ctx;
439 }
440
441 static BOOL test_wrepl_update_one(struct test_wrepl_conflict_conn *ctx,
442                                   const struct wrepl_wins_owner *owner,
443                                   const struct wrepl_wins_name *name)
444 {
445         BOOL ret = True;
446         struct wrepl_socket *wrepl_socket;
447         struct wrepl_associate associate;
448         struct wrepl_packet update_packet, repl_send;
449         struct wrepl_table *update;
450         struct wrepl_wins_owner wrepl_wins_owners[1];
451         struct wrepl_packet *repl_recv;
452         struct wrepl_wins_owner *send_request;
453         struct wrepl_send_reply *send_reply;
454         struct wrepl_wins_name wrepl_wins_names[1];
455         uint32_t assoc_ctx;
456         NTSTATUS status;
457
458         wrepl_socket = wrepl_socket_init(ctx, NULL);
459
460         status = wrepl_connect(wrepl_socket, NULL, ctx->address);
461         CHECK_STATUS(status, NT_STATUS_OK);
462
463         status = wrepl_associate(wrepl_socket, &associate);
464         CHECK_STATUS(status, NT_STATUS_OK);
465         assoc_ctx = associate.out.assoc_ctx;
466
467         /* now send a WREPL_REPL_UPDATE message */
468         ZERO_STRUCT(update_packet);
469         update_packet.opcode                    = WREPL_OPCODE_BITS;
470         update_packet.assoc_ctx                 = assoc_ctx;
471         update_packet.mess_type                 = WREPL_REPLICATION;
472         update_packet.message.replication.command       = WREPL_REPL_UPDATE;
473         update  = &update_packet.message.replication.info.table;
474
475         update->partner_count   = ARRAY_SIZE(wrepl_wins_owners);
476         update->partners        = wrepl_wins_owners;
477         update->initiator       = "0.0.0.0";
478
479         wrepl_wins_owners[0]    = *owner;
480
481         status = wrepl_request(wrepl_socket, wrepl_socket,
482                                &update_packet, &repl_recv);
483         CHECK_STATUS(status, NT_STATUS_OK);
484         CHECK_VALUE(repl_recv->mess_type, WREPL_REPLICATION);
485         CHECK_VALUE(repl_recv->message.replication.command, WREPL_REPL_SEND_REQUEST);
486         send_request = &repl_recv->message.replication.info.owner;
487
488         ZERO_STRUCT(repl_send);
489         repl_send.opcode                        = WREPL_OPCODE_BITS;
490         repl_send.assoc_ctx                     = assoc_ctx;
491         repl_send.mess_type                     = WREPL_REPLICATION;
492         repl_send.message.replication.command   = WREPL_REPL_SEND_REPLY;
493         send_reply = &repl_send.message.replication.info.reply;
494
495         send_reply->num_names   = ARRAY_SIZE(wrepl_wins_names);
496         send_reply->names       = wrepl_wins_names;
497
498         wrepl_wins_names[0]     = *name;
499
500         status = wrepl_request(wrepl_socket, wrepl_socket,
501                                &repl_send, &repl_recv);
502         CHECK_STATUS(status, NT_STATUS_OK);
503         CHECK_VALUE(repl_recv->mess_type, WREPL_STOP_ASSOCIATION);
504         CHECK_VALUE(repl_recv->message.stop.reason, 0);
505
506 done:
507         talloc_free(wrepl_socket);
508         return ret;
509 }
510
511 static BOOL test_wrepl_is_applied(struct test_wrepl_conflict_conn *ctx,
512                                   const struct wrepl_wins_owner *owner,
513                                   const struct wrepl_wins_name *name,
514                                   BOOL expected)
515 {
516         BOOL ret = True;
517         NTSTATUS status;
518         struct wrepl_pull_names pull_names;
519         struct wrepl_name *names;
520
521         pull_names.in.assoc_ctx = ctx->pull_assoc;
522         pull_names.in.partner   = *owner;
523         pull_names.in.partner.min_version = pull_names.in.partner.max_version;
524                 
525         status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
526         CHECK_STATUS(status, NT_STATUS_OK);
527         CHECK_VALUE(pull_names.out.num_names, (expected?1:0));
528
529         names = pull_names.out.names;
530
531         if (expected) {
532                 uint32_t flags = WREPL_NAME_FLAGS(names[0].type,
533                                                   names[0].state,
534                                                   names[0].node,
535                                                   names[0].is_static);
536                 CHECK_VALUE(names[0].name.type, name->name->type);
537                 CHECK_VALUE_STRING(names[0].name.name, name->name->name);
538                 CHECK_VALUE_STRING(names[0].name.scope, name->name->scope);
539                 CHECK_VALUE(flags, name->flags);
540                 CHECK_VALUE_UINT64(names[0].version_id, name->id);
541
542                 if (flags & 2) {
543                         CHECK_VALUE(names[0].num_addresses,
544                                     name->addresses.addresses.num_ips);
545                 } else {
546                         CHECK_VALUE(names[0].num_addresses, 1);
547                         CHECK_VALUE_STRING(names[0].addresses[0].address,
548                                            name->addresses.ip);
549                 }
550         }
551 done:
552         talloc_free(pull_names.out.names);
553         return ret;
554 }
555
556 static BOOL test_wrepl_is_merged(struct test_wrepl_conflict_conn *ctx,
557                                  const struct wrepl_wins_name *name1,
558                                  const struct wrepl_wins_name *name2)
559 {
560         return True;
561 #if 0
562         BOOL ret = True;
563         NTSTATUS status;
564         struct wrepl_pull_names pull_names;
565         struct wrepl_name *names;
566         uint32_t num_ips;
567
568         pull_names.in.assoc_ctx = ctx->pull_assoc;
569         pull_names.in.partner   = ctx->c;
570         pull_names.in.partner.min_version = ctx->c.max_version-1;
571
572         status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
573         CHECK_STATUS(status, NT_STATUS_OK);
574         CHECK_VALUE(pull_names.out.num_names, 1);
575
576         names = pull_names.out.names;
577
578         num_ips = name1->addresses.addresses.num_ips + name2->addresses.addresses.num_ips;
579
580         CHECK_VALUE(names[0].name.type, name1->name->type);
581         CHECK_VALUE_STRING(names[0].name.name, name1->name->name);
582         CHECK_VALUE_STRING(names[0].name.scope, name1->name->scope);
583         CHECK_VALUE(names[0].type, WREPL_TYPE_SGROUP);
584         CHECK_VALUE(names[0].state, (num_ips>0?WREPL_STATE_ACTIVE:WREPL_STATE_RELEASED));
585         CHECK_VALUE_UINT64(names[0].version_id, ctx->c.max_version);
586
587         CHECK_VALUE(names[0].num_addresses,
588                     name1->addresses.addresses.num_ips+
589                     name2->addresses.addresses.num_ips);
590 done:
591         talloc_free(pull_names.out.names);
592         return ret;
593 #endif
594 }
595
596 static BOOL test_conflict_same_owner(struct test_wrepl_conflict_conn *ctx)
597 {
598         BOOL ret = True;
599         struct nbt_name name;
600         struct wrepl_wins_name wins_name1;
601         struct wrepl_wins_name wins_name2;
602         struct wrepl_wins_name *wins_name_tmp;
603         struct wrepl_wins_name *wins_name_last;
604         struct wrepl_wins_name *wins_name_cur;
605         uint32_t i,j;
606         uint8_t types[] = { 0x00, 0x1C };
607         struct {
608                 enum wrepl_name_type type;
609                 enum wrepl_name_state state;
610                 enum wrepl_name_node node;
611                 BOOL is_static;
612                 uint32_t num_ips;
613                 const struct wrepl_ip *ips;
614         } records[] = {
615                 {
616                 .type           = WREPL_TYPE_GROUP,
617                 .state          = WREPL_STATE_ACTIVE,
618                 .node           = WREPL_NODE_B,
619                 .is_static      = False,
620                 .num_ips        = ARRAY_SIZE(addresses_A_1),
621                 .ips            = addresses_A_1,
622                 },{
623                 .type           = WREPL_TYPE_UNIQUE,
624                 .state          = WREPL_STATE_ACTIVE,
625                 .node           = WREPL_NODE_B,
626                 .is_static      = False,
627                 .num_ips        = ARRAY_SIZE(addresses_A_1),
628                 .ips            = addresses_A_1,
629                 },{
630                 .type           = WREPL_TYPE_UNIQUE,
631                 .state          = WREPL_STATE_ACTIVE,
632                 .node           = WREPL_NODE_B,
633                 .is_static      = False,
634                 .num_ips        = ARRAY_SIZE(addresses_A_2),
635                 .ips            = addresses_A_2,
636                 },{
637                 .type           = WREPL_TYPE_UNIQUE,
638                 .state          = WREPL_STATE_ACTIVE,
639                 .node           = WREPL_NODE_B,
640                 .is_static      = True,
641                 .num_ips        = ARRAY_SIZE(addresses_A_1),
642                 .ips            = addresses_A_1,
643                 },{
644                 .type           = WREPL_TYPE_UNIQUE,
645                 .state          = WREPL_STATE_ACTIVE,
646                 .node           = WREPL_NODE_B,
647                 .is_static      = False,
648                 .num_ips        = ARRAY_SIZE(addresses_A_2),
649                 .ips            = addresses_A_2,
650                 },{
651                 .type           = WREPL_TYPE_SGROUP,
652                 .state          = WREPL_STATE_TOMBSTONE,
653                 .node           = WREPL_NODE_B,
654                 .is_static      = False,
655                 .num_ips        = ARRAY_SIZE(addresses_A_2),
656                 .ips            = addresses_A_2,
657                 },{
658                 .type           = WREPL_TYPE_MHOMED,
659                 .state          = WREPL_STATE_TOMBSTONE,
660                 .node           = WREPL_NODE_B,
661                 .is_static      = False,
662                 .num_ips        = ARRAY_SIZE(addresses_A_1),
663                 .ips            = addresses_A_1,
664                 },{
665                 .type           = WREPL_TYPE_MHOMED,
666                 .state          = WREPL_STATE_RELEASED,
667                 .node           = WREPL_NODE_B,
668                 .is_static      = False,
669                 .num_ips        = ARRAY_SIZE(addresses_A_2),
670                 .ips            = addresses_A_2,
671                 },{
672                 .type           = WREPL_TYPE_SGROUP,
673                 .state          = WREPL_STATE_ACTIVE,
674                 .node           = WREPL_NODE_B,
675                 .is_static      = False,
676                 .num_ips        = ARRAY_SIZE(addresses_A_1),
677                 .ips            = addresses_A_1,
678                 },{
679                 /* the last one should always be a unique,tomstone record! */
680                 .type           = WREPL_TYPE_UNIQUE,
681                 .state          = WREPL_STATE_TOMBSTONE,
682                 .node           = WREPL_NODE_B,
683                 .is_static      = False,
684                 .num_ips        = ARRAY_SIZE(addresses_A_1),
685                 .ips            = addresses_A_1,
686                 }
687         };
688
689         if (!ctx) return False;
690
691         name.name       = "_SAME_OWNER_A";
692         name.type       = 0;
693         name.scope      = NULL;
694
695         wins_name_tmp   = NULL;
696         wins_name_last  = &wins_name2;
697         wins_name_cur   = &wins_name1;
698
699         for (j=0; ret && j < ARRAY_SIZE(types); j++) {
700                 name.type = types[j];
701                 printf("Test Replica Conflicts with same owner[%s] for %s\n",
702                         nbt_name_string(ctx, &name), ctx->a.address);
703
704                 for(i=0; ret && i < ARRAY_SIZE(records); i++) {
705                         wins_name_tmp   = wins_name_last;
706                         wins_name_last  = wins_name_cur;
707                         wins_name_cur   = wins_name_tmp;
708
709                         if (i > 0) {
710                                 printf("%s,%s%s vs. %s,%s%s with %s ip(s) => %s\n",
711                                         wrepl_name_type_string(records[i-1].type),
712                                         wrepl_name_state_string(records[i-1].state),
713                                         (records[i-1].is_static?",static":""),
714                                         wrepl_name_type_string(records[i].type),
715                                         wrepl_name_state_string(records[i].state),
716                                         (records[i].is_static?",static":""),
717                                         (records[i-1].ips==records[i].ips?"same":"different"),
718                                         "REPLACE");
719                         }
720
721                         wins_name_cur->name     = &name;
722                         wins_name_cur->flags    = WREPL_NAME_FLAGS(records[i].type,
723                                                                    records[i].state,
724                                                                    records[i].node,
725                                                                    records[i].is_static);
726                         wins_name_cur->id       = ++ctx->a.max_version;
727                         if (wins_name_cur->flags & 2) {
728                                 wins_name_cur->addresses.addresses.num_ips = records[i].num_ips;
729                                 wins_name_cur->addresses.addresses.ips     = discard_const(records[i].ips);
730                         } else {
731                                 wins_name_cur->addresses.ip = records[i].ips[0].ip;
732                         }
733                         wins_name_cur->unknown  = "255.255.255.255";
734
735                         ret &= test_wrepl_update_one(ctx, &ctx->a,wins_name_cur);
736                         if (records[i].state == WREPL_STATE_RELEASED) {
737                                 ret &= test_wrepl_is_applied(ctx, &ctx->a, wins_name_last, False);
738                                 ret &= test_wrepl_is_applied(ctx, &ctx->a, wins_name_cur, False);
739                         } else {
740                                 ret &= test_wrepl_is_applied(ctx, &ctx->a, wins_name_cur, True);
741                         }
742
743                         /* the first one is a cleanup run */
744                         if (!ret && i == 0) ret = True;
745
746                         if (!ret) {
747                                 printf("conflict handled wrong or record[%u]: %s\n", i, __location__);
748                                 return ret;
749                         }
750                 }
751         }
752         return ret;
753 }
754
755 static BOOL test_conflict_different_owner(struct test_wrepl_conflict_conn *ctx)
756 {
757         BOOL ret = True;
758         struct wrepl_wins_name wins_name1;
759         struct wrepl_wins_name wins_name2;
760         struct wrepl_wins_name *wins_name_r1;
761         struct wrepl_wins_name *wins_name_r2;
762         uint32_t i;
763         struct {
764                 const char *line; /* just better debugging */
765                 struct nbt_name name;
766                 BOOL extra; /* not the worst case, this is an extra test */
767                 BOOL cleanup;
768                 struct {
769                         struct wrepl_wins_owner *owner;
770                         enum wrepl_name_type type;
771                         enum wrepl_name_state state;
772                         enum wrepl_name_node node;
773                         BOOL is_static;
774                         uint32_t num_ips;
775                         const struct wrepl_ip *ips;
776                         BOOL apply_expected;
777                         BOOL merge_expected;
778                 } r1, r2;
779         } records[] = {
780         /* 
781          * NOTE: the first record and the last applied one
782          *       needs to be from the same owner,
783          *       to not conflict in the next smbtorture run!!!
784          */
785         {
786                 .line   = __location__,
787                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
788                 .cleanup= True,
789                 .r1     = {
790                         .owner          = &ctx->b,
791                         .type           = WREPL_TYPE_UNIQUE,
792                         .state          = WREPL_STATE_TOMBSTONE,
793                         .node           = WREPL_NODE_B,
794                         .is_static      = False,
795                         .num_ips        = ARRAY_SIZE(addresses_B_1),
796                         .ips            = addresses_B_1,
797                         .apply_expected = True /* ignored */
798                 },
799                 .r2     = {
800                         .owner          = &ctx->a,
801                         .type           = WREPL_TYPE_UNIQUE,
802                         .state          = WREPL_STATE_TOMBSTONE,
803                         .node           = WREPL_NODE_B,
804                         .is_static      = False,
805                         .num_ips        = ARRAY_SIZE(addresses_A_1),
806                         .ips            = addresses_A_1,
807                         .apply_expected = True /* ignored */
808                 }
809         },
810
811 /*
812  * unique vs unique section
813  */
814         /* 
815          * unique,active vs. unique,active
816          * => should be replaced
817          */
818         {
819                 .line   = __location__,
820                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
821                 .r1     = {
822                         .owner          = &ctx->a,
823                         .type           = WREPL_TYPE_UNIQUE,
824                         .state          = WREPL_STATE_ACTIVE,
825                         .node           = WREPL_NODE_B,
826                         .is_static      = False,
827                         .num_ips        = ARRAY_SIZE(addresses_A_1),
828                         .ips            = addresses_A_1,
829                         .apply_expected = True
830                 },
831                 .r2     = {
832                         .owner          = &ctx->b,
833                         .type           = WREPL_TYPE_UNIQUE,
834                         .state          = WREPL_STATE_ACTIVE,
835                         .node           = WREPL_NODE_B,
836                         .is_static      = False,
837                         .num_ips        = ARRAY_SIZE(addresses_B_1),
838                         .ips            = addresses_B_1,
839                         .apply_expected = True
840                 }
841         },
842
843         /* 
844          * unique,active vs. unique,tombstone
845          * => should NOT be replaced
846          */
847         {
848                 .line   = __location__,
849                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
850                 .r1     = {
851                         .owner          = &ctx->b,
852                         .type           = WREPL_TYPE_UNIQUE,
853                         .state          = WREPL_STATE_ACTIVE,
854                         .node           = WREPL_NODE_B,
855                         .is_static      = False,
856                         .num_ips        = ARRAY_SIZE(addresses_B_1),
857                         .ips            = addresses_B_1,
858                         .apply_expected = True
859                 },
860                 .r2     = {
861                         .owner          = &ctx->a,
862                         .type           = WREPL_TYPE_UNIQUE,
863                         .state          = WREPL_STATE_TOMBSTONE,
864                         .node           = WREPL_NODE_B,
865                         .is_static      = False,
866                         .num_ips        = ARRAY_SIZE(addresses_B_1),
867                         .ips            = addresses_B_1,
868                         .apply_expected = False
869                 }
870         },
871
872         /* 
873          * unique,released vs. unique,active
874          * => should be replaced
875          */
876         {
877                 .line   = __location__,
878                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
879                 .r1     = {
880                         .owner          = &ctx->b,
881                         .type           = WREPL_TYPE_UNIQUE,
882                         .state          = WREPL_STATE_RELEASED,
883                         .node           = WREPL_NODE_B,
884                         .is_static      = False,
885                         .num_ips        = ARRAY_SIZE(addresses_B_1),
886                         .ips            = addresses_B_1,
887                         .apply_expected = False
888                 },
889                 .r2     = {
890                         .owner          = &ctx->a,
891                         .type           = WREPL_TYPE_UNIQUE,
892                         .state          = WREPL_STATE_ACTIVE,
893                         .node           = WREPL_NODE_B,
894                         .is_static      = False,
895                         .num_ips        = ARRAY_SIZE(addresses_A_1),
896                         .ips            = addresses_A_1,
897                         .apply_expected = True
898                 }
899         },
900
901         /* 
902          * unique,released vs. unique,tombstone
903          * => should be replaced
904          */
905         {
906                 .line   = __location__,
907                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
908                 .r1     = {
909                         .owner          = &ctx->a,
910                         .type           = WREPL_TYPE_UNIQUE,
911                         .state          = WREPL_STATE_RELEASED,
912                         .node           = WREPL_NODE_B,
913                         .is_static      = False,
914                         .num_ips        = ARRAY_SIZE(addresses_A_1),
915                         .ips            = addresses_A_1,
916                         .apply_expected = False
917                 },
918                 .r2     = {
919                         .owner          = &ctx->b,
920                         .type           = WREPL_TYPE_UNIQUE,
921                         .state          = WREPL_STATE_TOMBSTONE,
922                         .node           = WREPL_NODE_B,
923                         .is_static      = False,
924                         .num_ips        = ARRAY_SIZE(addresses_B_1),
925                         .ips            = addresses_B_1,
926                         .apply_expected = True
927                 }
928         },
929
930         /* 
931          * unique,tombstone vs. unique,active
932          * => should be replaced
933          */
934         {
935                 .line   = __location__,
936                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
937                 .r1     = {
938                         .owner          = &ctx->b,
939                         .type           = WREPL_TYPE_UNIQUE,
940                         .state          = WREPL_STATE_TOMBSTONE,
941                         .node           = WREPL_NODE_B,
942                         .is_static      = False,
943                         .num_ips        = ARRAY_SIZE(addresses_B_1),
944                         .ips            = addresses_B_1,
945                         .apply_expected = True
946                 },
947                 .r2     = {
948                         .owner          = &ctx->a,
949                         .type           = WREPL_TYPE_UNIQUE,
950                         .state          = WREPL_STATE_ACTIVE,
951                         .node           = WREPL_NODE_B,
952                         .is_static      = False,
953                         .num_ips        = ARRAY_SIZE(addresses_A_1),
954                         .ips            = addresses_A_1,
955                         .apply_expected = True
956                 }
957         },
958
959         /* 
960          * unique,tombstone vs. unique,tombstone
961          * => should be replaced
962          */
963         {
964                 .line   = __location__,
965                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
966                 .r1     = {
967                         .owner          = &ctx->a,
968                         .type           = WREPL_TYPE_UNIQUE,
969                         .state          = WREPL_STATE_TOMBSTONE,
970                         .node           = WREPL_NODE_B,
971                         .is_static      = False,
972                         .num_ips        = ARRAY_SIZE(addresses_A_1),
973                         .ips            = addresses_A_1,
974                         .apply_expected = True
975                 },
976                 .r2     = {
977                         .owner          = &ctx->b,
978                         .type           = WREPL_TYPE_UNIQUE,
979                         .state          = WREPL_STATE_TOMBSTONE,
980                         .node           = WREPL_NODE_B,
981                         .is_static      = False,
982                         .num_ips        = ARRAY_SIZE(addresses_B_1),
983                         .ips            = addresses_B_1,
984                         .apply_expected = True
985                 }
986         },
987
988
989 /*
990  * unique vs normal groups section,
991  */
992         /* 
993          * unique,active vs. group,active
994          * => should be replaced
995          */
996         {
997                 .line   = __location__,
998                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
999                 .r1     = {
1000                         .owner          = &ctx->b,
1001                         .type           = WREPL_TYPE_UNIQUE,
1002                         .state          = WREPL_STATE_ACTIVE,
1003                         .node           = WREPL_NODE_B,
1004                         .is_static      = False,
1005                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1006                         .ips            = addresses_B_1,
1007                         .apply_expected = True
1008                 },
1009                 .r2     = {
1010                         .owner          = &ctx->a,
1011                         .type           = WREPL_TYPE_GROUP,
1012                         .state          = WREPL_STATE_ACTIVE,
1013                         .node           = WREPL_NODE_B,
1014                         .is_static      = False,
1015                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1016                         .ips            = addresses_A_1,
1017                         .apply_expected = True
1018                 }
1019         },
1020
1021         /* 
1022          * unique,active vs. group,tombstone
1023          * => should NOT be replaced
1024          */
1025         {
1026                 .line   = __location__,
1027                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1028                 .r1     = {
1029                         .owner          = &ctx->a,
1030                         .type           = WREPL_TYPE_UNIQUE,
1031                         .state          = WREPL_STATE_ACTIVE,
1032                         .node           = WREPL_NODE_B,
1033                         .is_static      = False,
1034                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1035                         .ips            = addresses_A_1,
1036                         .apply_expected = True
1037                 },
1038                 .r2     = {
1039                         .owner          = &ctx->b,
1040                         .type           = WREPL_TYPE_GROUP,
1041                         .state          = WREPL_STATE_TOMBSTONE,
1042                         .node           = WREPL_NODE_B,
1043                         .is_static      = False,
1044                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1045                         .ips            = addresses_A_1,
1046                         .apply_expected = False
1047                 }
1048         },
1049
1050         /* 
1051          * unique,released vs. group,active
1052          * => should be replaced
1053          */
1054         {
1055                 .line   = __location__,
1056                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1057                 .r1     = {
1058                         .owner          = &ctx->a,
1059                         .type           = WREPL_TYPE_UNIQUE,
1060                         .state          = WREPL_STATE_RELEASED,
1061                         .node           = WREPL_NODE_B,
1062                         .is_static      = False,
1063                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1064                         .ips            = addresses_A_1,
1065                         .apply_expected = False
1066                 },
1067                 .r2     = {
1068                         .owner          = &ctx->b,
1069                         .type           = WREPL_TYPE_GROUP,
1070                         .state          = WREPL_STATE_ACTIVE,
1071                         .node           = WREPL_NODE_B,
1072                         .is_static      = False,
1073                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1074                         .ips            = addresses_B_1,
1075                         .apply_expected = True
1076                 }
1077         },
1078
1079         /* 
1080          * unique,released vs. group,tombstone
1081          * => should be replaced
1082          */
1083         {
1084                 .line   = __location__,
1085                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1086                 .r1     = {
1087                         .owner          = &ctx->b,
1088                         .type           = WREPL_TYPE_UNIQUE,
1089                         .state          = WREPL_STATE_RELEASED,
1090                         .node           = WREPL_NODE_B,
1091                         .is_static      = False,
1092                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1093                         .ips            = addresses_B_1,
1094                         .apply_expected = False
1095                 },
1096                 .r2     = {
1097                         .owner          = &ctx->a,
1098                         .type           = WREPL_TYPE_GROUP,
1099                         .state          = WREPL_STATE_TOMBSTONE,
1100                         .node           = WREPL_NODE_B,
1101                         .is_static      = False,
1102                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1103                         .ips            = addresses_A_1,
1104                         .apply_expected = True
1105                 }
1106         },
1107
1108         /* 
1109          * unique,tombstone vs. group,active
1110          * => should be replaced
1111          */
1112         {
1113                 .line   = __location__,
1114                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1115                 .r1     = {
1116                         .owner          = &ctx->a,
1117                         .type           = WREPL_TYPE_UNIQUE,
1118                         .state          = WREPL_STATE_TOMBSTONE,
1119                         .node           = WREPL_NODE_B,
1120                         .is_static      = False,
1121                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1122                         .ips            = addresses_A_1,
1123                         .apply_expected = True
1124                 },
1125                 .r2     = {
1126                         .owner          = &ctx->b,
1127                         .type           = WREPL_TYPE_GROUP,
1128                         .state          = WREPL_STATE_ACTIVE,
1129                         .node           = WREPL_NODE_B,
1130                         .is_static      = False,
1131                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1132                         .ips            = addresses_B_1,
1133                         .apply_expected = True
1134                 }
1135         },
1136
1137         /* 
1138          * unique,tombstone vs. group,tombstone
1139          * => should be replaced
1140          */
1141         {
1142                 .line   = __location__,
1143                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1144                 .r1     = {
1145                         .owner          = &ctx->b,
1146                         .type           = WREPL_TYPE_UNIQUE,
1147                         .state          = WREPL_STATE_TOMBSTONE,
1148                         .node           = WREPL_NODE_B,
1149                         .is_static      = False,
1150                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1151                         .ips            = addresses_B_1,
1152                         .apply_expected = True
1153                 },
1154                 .r2     = {
1155                         .owner          = &ctx->a,
1156                         .type           = WREPL_TYPE_GROUP,
1157                         .state          = WREPL_STATE_TOMBSTONE,
1158                         .node           = WREPL_NODE_B,
1159                         .is_static      = False,
1160                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1161                         .ips            = addresses_A_1,
1162                         .apply_expected = True
1163                 }
1164         },
1165
1166 /*
1167  * unique vs special groups section,
1168  */
1169         /* 
1170          * unique,active vs. sgroup,active
1171          * => should NOT be replaced
1172          */
1173         {
1174                 .line   = __location__,
1175                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1176                 .r1     = {
1177                         .owner          = &ctx->a,
1178                         .type           = WREPL_TYPE_UNIQUE,
1179                         .state          = WREPL_STATE_ACTIVE,
1180                         .node           = WREPL_NODE_B,
1181                         .is_static      = False,
1182                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1183                         .ips            = addresses_A_1,
1184                         .apply_expected = True
1185                 },
1186                 .r2     = {
1187                         .owner          = &ctx->b,
1188                         .type           = WREPL_TYPE_SGROUP,
1189                         .state          = WREPL_STATE_ACTIVE,
1190                         .node           = WREPL_NODE_B,
1191                         .is_static      = False,
1192                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1193                         .ips            = addresses_A_1,
1194                         .apply_expected = False
1195                 }
1196         },
1197
1198         /* 
1199          * unique,active vs. sgroup,tombstone
1200          * => should NOT be replaced
1201          */
1202         {
1203                 .line   = __location__,
1204                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1205                 .r1     = {
1206                         .owner          = &ctx->a,
1207                         .type           = WREPL_TYPE_UNIQUE,
1208                         .state          = WREPL_STATE_ACTIVE,
1209                         .node           = WREPL_NODE_B,
1210                         .is_static      = False,
1211                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1212                         .ips            = addresses_A_1,
1213                         .apply_expected = True
1214                 },
1215                 .r2     = {
1216                         .owner          = &ctx->b,
1217                         .type           = WREPL_TYPE_SGROUP,
1218                         .state          = WREPL_STATE_TOMBSTONE,
1219                         .node           = WREPL_NODE_B,
1220                         .is_static      = False,
1221                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1222                         .ips            = addresses_A_1,
1223                         .apply_expected = False
1224                 }
1225         },
1226
1227         /* 
1228          * unique,released vs. sgroup,active
1229          * => should be replaced
1230          */
1231         {
1232                 .line   = __location__,
1233                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1234                 .r1     = {
1235                         .owner          = &ctx->a,
1236                         .type           = WREPL_TYPE_UNIQUE,
1237                         .state          = WREPL_STATE_RELEASED,
1238                         .node           = WREPL_NODE_B,
1239                         .is_static      = False,
1240                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1241                         .ips            = addresses_A_1,
1242                         .apply_expected = False
1243                 },
1244                 .r2     = {
1245                         .owner          = &ctx->b,
1246                         .type           = WREPL_TYPE_SGROUP,
1247                         .state          = WREPL_STATE_ACTIVE,
1248                         .node           = WREPL_NODE_B,
1249                         .is_static      = False,
1250                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1251                         .ips            = addresses_B_3_4,
1252                         .apply_expected = True
1253                 }
1254         },
1255
1256         /* 
1257          * unique,released vs. sgroup,tombstone
1258          * => should be replaced
1259          */
1260         {
1261                 .line   = __location__,
1262                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1263                 .r1     = {
1264                         .owner          = &ctx->b,
1265                         .type           = WREPL_TYPE_UNIQUE,
1266                         .state          = WREPL_STATE_RELEASED,
1267                         .node           = WREPL_NODE_B,
1268                         .is_static      = False,
1269                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1270                         .ips            = addresses_B_1,
1271                         .apply_expected = False
1272                 },
1273                 .r2     = {
1274                         .owner          = &ctx->a,
1275                         .type           = WREPL_TYPE_SGROUP,
1276                         .state          = WREPL_STATE_TOMBSTONE,
1277                         .node           = WREPL_NODE_B,
1278                         .is_static      = False,
1279                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
1280                         .ips            = addresses_A_3_4,
1281                         .apply_expected = True
1282                 }
1283         },
1284
1285         /* 
1286          * unique,tombstone vs. sgroup,active
1287          * => should be replaced
1288          */
1289         {
1290                 .line   = __location__,
1291                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1292                 .r1     = {
1293                         .owner          = &ctx->a,
1294                         .type           = WREPL_TYPE_UNIQUE,
1295                         .state          = WREPL_STATE_TOMBSTONE,
1296                         .node           = WREPL_NODE_B,
1297                         .is_static      = False,
1298                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1299                         .ips            = addresses_A_1,
1300                         .apply_expected = True
1301                 },
1302                 .r2     = {
1303                         .owner          = &ctx->b,
1304                         .type           = WREPL_TYPE_SGROUP,
1305                         .state          = WREPL_STATE_ACTIVE,
1306                         .node           = WREPL_NODE_B,
1307                         .is_static      = False,
1308                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1309                         .ips            = addresses_B_3_4,
1310                         .apply_expected = True
1311                 }
1312         },
1313
1314         /* 
1315          * unique,tombstone vs. sgroup,tombstone
1316          * => should be replaced
1317          */
1318         {
1319                 .line   = __location__,
1320                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1321                 .r1     = {
1322                         .owner          = &ctx->b,
1323                         .type           = WREPL_TYPE_UNIQUE,
1324                         .state          = WREPL_STATE_TOMBSTONE,
1325                         .node           = WREPL_NODE_B,
1326                         .is_static      = False,
1327                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1328                         .ips            = addresses_B_1,
1329                         .apply_expected = True
1330                 },
1331                 .r2     = {
1332                         .owner          = &ctx->a,
1333                         .type           = WREPL_TYPE_SGROUP,
1334                         .state          = WREPL_STATE_TOMBSTONE,
1335                         .node           = WREPL_NODE_B,
1336                         .is_static      = False,
1337                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
1338                         .ips            = addresses_A_3_4,
1339                         .apply_expected = True
1340                 }
1341         },
1342
1343 /*
1344  * unique vs multi homed section,
1345  */
1346         /* 
1347          * unique,active vs. mhomed,active
1348          * => should be replaced
1349          */
1350         {
1351                 .line   = __location__,
1352                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1353                 .r1     = {
1354                         .owner          = &ctx->a,
1355                         .type           = WREPL_TYPE_UNIQUE,
1356                         .state          = WREPL_STATE_ACTIVE,
1357                         .node           = WREPL_NODE_B,
1358                         .is_static      = False,
1359                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1360                         .ips            = addresses_A_1,
1361                         .apply_expected = True
1362                 },
1363                 .r2     = {
1364                         .owner          = &ctx->b,
1365                         .type           = WREPL_TYPE_MHOMED,
1366                         .state          = WREPL_STATE_ACTIVE,
1367                         .node           = WREPL_NODE_B,
1368                         .is_static      = False,
1369                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1370                         .ips            = addresses_B_3_4,
1371                         .apply_expected = True
1372                 }
1373         },
1374
1375         /* 
1376          * unique,active vs. mhomed,tombstone
1377          * => should NOT be replaced
1378          */
1379         {
1380                 .line   = __location__,
1381                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1382                 .r1     = {
1383                         .owner          = &ctx->b,
1384                         .type           = WREPL_TYPE_UNIQUE,
1385                         .state          = WREPL_STATE_ACTIVE,
1386                         .node           = WREPL_NODE_B,
1387                         .is_static      = False,
1388                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1389                         .ips            = addresses_B_3_4,
1390                         .apply_expected = True
1391                 },
1392                 .r2     = {
1393                         .owner          = &ctx->a,
1394                         .type           = WREPL_TYPE_MHOMED,
1395                         .state          = WREPL_STATE_TOMBSTONE,
1396                         .node           = WREPL_NODE_B,
1397                         .is_static      = False,
1398                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1399                         .ips            = addresses_B_3_4,
1400                         .apply_expected = False
1401                 }
1402         },
1403
1404         /* 
1405          * unique,released vs. mhomed,active
1406          * => should be replaced
1407          */
1408         {
1409                 .line   = __location__,
1410                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1411                 .r1     = {
1412                         .owner          = &ctx->b,
1413                         .type           = WREPL_TYPE_UNIQUE,
1414                         .state          = WREPL_STATE_RELEASED,
1415                         .node           = WREPL_NODE_B,
1416                         .is_static      = False,
1417                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1418                         .ips            = addresses_B_1,
1419                         .apply_expected = False
1420                 },
1421                 .r2     = {
1422                         .owner          = &ctx->a,
1423                         .type           = WREPL_TYPE_MHOMED,
1424                         .state          = WREPL_STATE_ACTIVE,
1425                         .node           = WREPL_NODE_B,
1426                         .is_static      = False,
1427                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
1428                         .ips            = addresses_A_3_4,
1429                         .apply_expected = True
1430                 }
1431         },
1432
1433         /* 
1434          * unique,released vs. mhomed,tombstone
1435          * => should be replaced
1436          */
1437         {
1438                 .line   = __location__,
1439                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1440                 .r1     = {
1441                         .owner          = &ctx->a,
1442                         .type           = WREPL_TYPE_UNIQUE,
1443                         .state          = WREPL_STATE_RELEASED,
1444                         .node           = WREPL_NODE_B,
1445                         .is_static      = False,
1446                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1447                         .ips            = addresses_A_1,
1448                         .apply_expected = False
1449                 },
1450                 .r2     = {
1451                         .owner          = &ctx->b,
1452                         .type           = WREPL_TYPE_MHOMED,
1453                         .state          = WREPL_STATE_TOMBSTONE,
1454                         .node           = WREPL_NODE_B,
1455                         .is_static      = False,
1456                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1457                         .ips            = addresses_B_3_4,
1458                         .apply_expected = True
1459                 }
1460         },
1461
1462         /* 
1463          * unique,tombstone vs. mhomed,active
1464          * => should be replaced
1465          */
1466         {
1467                 .line   = __location__,
1468                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1469                 .r1     = {
1470                         .owner          = &ctx->b,
1471                         .type           = WREPL_TYPE_UNIQUE,
1472                         .state          = WREPL_STATE_TOMBSTONE,
1473                         .node           = WREPL_NODE_B,
1474                         .is_static      = False,
1475                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1476                         .ips            = addresses_B_1,
1477                         .apply_expected = True
1478                 },
1479                 .r2     = {
1480                         .owner          = &ctx->a,
1481                         .type           = WREPL_TYPE_MHOMED,
1482                         .state          = WREPL_STATE_ACTIVE,
1483                         .node           = WREPL_NODE_B,
1484                         .is_static      = False,
1485                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
1486                         .ips            = addresses_A_3_4,
1487                         .apply_expected = True
1488                 }
1489         },
1490
1491         /* 
1492          * unique,tombstone vs. mhomed,tombstone
1493          * => should be replaced
1494          */
1495         {
1496                 .line   = __location__,
1497                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1498                 .r1     = {
1499                         .owner          = &ctx->a,
1500                         .type           = WREPL_TYPE_UNIQUE,
1501                         .state          = WREPL_STATE_TOMBSTONE,
1502                         .node           = WREPL_NODE_B,
1503                         .is_static      = False,
1504                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1505                         .ips            = addresses_A_1,
1506                         .apply_expected = True
1507                 },
1508                 .r2     = {
1509                         .owner          = &ctx->b,
1510                         .type           = WREPL_TYPE_MHOMED,
1511                         .state          = WREPL_STATE_TOMBSTONE,
1512                         .node           = WREPL_NODE_B,
1513                         .is_static      = False,
1514                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1515                         .ips            = addresses_B_3_4,
1516                         .apply_expected = True
1517                 }
1518         },
1519
1520 /*
1521  * normal groups vs unique section,
1522  */
1523         /* 
1524          * group,active vs. unique,active
1525          * => should NOT be replaced
1526          */
1527         {
1528                 .line   = __location__,
1529                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1530                 .r1     = {
1531                         .owner          = &ctx->a,
1532                         .type           = WREPL_TYPE_GROUP,
1533                         .state          = WREPL_STATE_ACTIVE,
1534                         .node           = WREPL_NODE_B,
1535                         .is_static      = False,
1536                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1537                         .ips            = addresses_A_1,
1538                         .apply_expected = True
1539                 },
1540                 .r2     = {
1541                         .owner          = &ctx->b,
1542                         .type           = WREPL_TYPE_UNIQUE,
1543                         .state          = WREPL_STATE_ACTIVE,
1544                         .node           = WREPL_NODE_B,
1545                         .is_static      = False,
1546                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1547                         .ips            = addresses_A_1,
1548                         .apply_expected = False
1549                 }
1550         },
1551
1552         /* 
1553          * group,active vs. unique,tombstone
1554          * => should NOT be replaced
1555          */
1556         {
1557                 .line   = __location__,
1558                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1559                 .r1     = {
1560                         .owner          = &ctx->a,
1561                         .type           = WREPL_TYPE_GROUP,
1562                         .state          = WREPL_STATE_ACTIVE,
1563                         .node           = WREPL_NODE_B,
1564                         .is_static      = False,
1565                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1566                         .ips            = addresses_A_1,
1567                         .apply_expected = True
1568                 },
1569                 .r2     = {
1570                         .owner          = &ctx->b,
1571                         .type           = WREPL_TYPE_UNIQUE,
1572                         .state          = WREPL_STATE_TOMBSTONE,
1573                         .node           = WREPL_NODE_B,
1574                         .is_static      = False,
1575                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1576                         .ips            = addresses_A_1,
1577                         .apply_expected = False
1578                 }
1579         },
1580
1581         /* 
1582          * group,released vs. unique,active
1583          * => should NOT be replaced
1584          */
1585         {
1586                 .line   = __location__,
1587                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1588                 .r1     = {
1589                         .owner          = &ctx->a,
1590                         .type           = WREPL_TYPE_GROUP,
1591                         .state          = WREPL_STATE_RELEASED,
1592                         .node           = WREPL_NODE_B,
1593                         .is_static      = False,
1594                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1595                         .ips            = addresses_A_1,
1596                         .apply_expected = False
1597                 },
1598                 .r2     = {
1599                         .owner          = &ctx->b,
1600                         .type           = WREPL_TYPE_UNIQUE,
1601                         .state          = WREPL_STATE_ACTIVE,
1602                         .node           = WREPL_NODE_B,
1603                         .is_static      = False,
1604                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1605                         .ips            = addresses_A_1,
1606                         .apply_expected = False
1607                 }
1608         },
1609
1610         /* 
1611          * group,released vs. unique,tombstone
1612          * => should NOT be replaced
1613          */
1614         {
1615                 .line   = __location__,
1616                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1617                 .r1     = {
1618                         .owner          = &ctx->a,
1619                         .type           = WREPL_TYPE_GROUP,
1620                         .state          = WREPL_STATE_RELEASED,
1621                         .node           = WREPL_NODE_B,
1622                         .is_static      = False,
1623                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1624                         .ips            = addresses_A_1,
1625                         .apply_expected = False
1626                 },
1627                 .r2     = {
1628                         .owner          = &ctx->b,
1629                         .type           = WREPL_TYPE_UNIQUE,
1630                         .state          = WREPL_STATE_TOMBSTONE,
1631                         .node           = WREPL_NODE_B,
1632                         .is_static      = False,
1633                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1634                         .ips            = addresses_A_1,
1635                         .apply_expected = False
1636                 }
1637         },
1638
1639         /* 
1640          * group,tombstone vs. unique,active
1641          * => should NOT be replaced
1642          */
1643         {
1644                 .line   = __location__,
1645                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1646                 .r1     = {
1647                         .owner          = &ctx->a,
1648                         .type           = WREPL_TYPE_GROUP,
1649                         .state          = WREPL_STATE_TOMBSTONE,
1650                         .node           = WREPL_NODE_B,
1651                         .is_static      = False,
1652                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1653                         .ips            = addresses_A_1,
1654                         .apply_expected = True
1655                 },
1656                 .r2     = {
1657                         .owner          = &ctx->b,
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 = False
1665                 }
1666         },
1667
1668         /* 
1669          * group,tombstone vs. unique,tombstone
1670          * => should NOT be replaced
1671          */
1672         {
1673                 .line   = __location__,
1674                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1675                 .r1     = {
1676                         .owner          = &ctx->a,
1677                         .type           = WREPL_TYPE_GROUP,
1678                         .state          = WREPL_STATE_TOMBSTONE,
1679                         .node           = WREPL_NODE_B,
1680                         .is_static      = False,
1681                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1682                         .ips            = addresses_A_1,
1683                         .apply_expected = True
1684                 },
1685                 .r2     = {
1686                         .owner          = &ctx->b,
1687                         .type           = WREPL_TYPE_UNIQUE,
1688                         .state          = WREPL_STATE_TOMBSTONE,
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 = False
1694                 }
1695         },
1696
1697 /*
1698  * normal groups vs normal groups section,
1699  */
1700         /* 
1701          * group,active vs. group,active
1702          * => should NOT be replaced
1703          */
1704         {
1705                 .line   = __location__,
1706                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1707                 .r1     = {
1708                         .owner          = &ctx->a,
1709                         .type           = WREPL_TYPE_GROUP,
1710                         .state          = WREPL_STATE_ACTIVE,
1711                         .node           = WREPL_NODE_B,
1712                         .is_static      = False,
1713                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1714                         .ips            = addresses_A_1,
1715                         .apply_expected = True
1716                 },
1717                 .r2     = {
1718                         .owner          = &ctx->b,
1719                         .type           = WREPL_TYPE_GROUP,
1720                         .state          = WREPL_STATE_ACTIVE,
1721                         .node           = WREPL_NODE_B,
1722                         .is_static      = False,
1723                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1724                         .ips            = addresses_A_1,
1725                         .apply_expected = False
1726                 }
1727         },
1728
1729         /* 
1730          * group,active vs. group,tombstone
1731          * => should NOT be replaced
1732          */
1733         {
1734                 .line   = __location__,
1735                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1736                 .r1     = {
1737                         .owner          = &ctx->a,
1738                         .type           = WREPL_TYPE_GROUP,
1739                         .state          = WREPL_STATE_ACTIVE,
1740                         .node           = WREPL_NODE_B,
1741                         .is_static      = False,
1742                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1743                         .ips            = addresses_A_1,
1744                         .apply_expected = True
1745                 },
1746                 .r2     = {
1747                         .owner          = &ctx->b,
1748                         .type           = WREPL_TYPE_GROUP,
1749                         .state          = WREPL_STATE_TOMBSTONE,
1750                         .node           = WREPL_NODE_B,
1751                         .is_static      = False,
1752                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1753                         .ips            = addresses_A_1,
1754                         .apply_expected = False
1755                 }
1756         },
1757
1758         /* 
1759          * group,released vs. group,active
1760          * => should be replaced
1761          */
1762         {
1763                 .line   = __location__,
1764                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1765                 .r1     = {
1766                         .owner          = &ctx->a,
1767                         .type           = WREPL_TYPE_GROUP,
1768                         .state          = WREPL_STATE_RELEASED,
1769                         .node           = WREPL_NODE_B,
1770                         .is_static      = False,
1771                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1772                         .ips            = addresses_A_1,
1773                         .apply_expected = False
1774                 },
1775                 .r2     = {
1776                         .owner          = &ctx->b,
1777                         .type           = WREPL_TYPE_GROUP,
1778                         .state          = WREPL_STATE_ACTIVE,
1779                         .node           = WREPL_NODE_B,
1780                         .is_static      = False,
1781                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1782                         .ips            = addresses_B_1,
1783                         .apply_expected = True
1784                 }
1785         },
1786
1787         /* 
1788          * group,released vs. group,tombstone
1789          * => should be replaced
1790          */
1791         {
1792                 .line   = __location__,
1793                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1794                 .r1     = {
1795                         .owner          = &ctx->a,
1796                         .type           = WREPL_TYPE_GROUP,
1797                         .state          = WREPL_STATE_RELEASED,
1798                         .node           = WREPL_NODE_B,
1799                         .is_static      = False,
1800                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1801                         .ips            = addresses_A_1,
1802                         .apply_expected = False
1803                 },
1804                 .r2     = {
1805                         .owner          = &ctx->b,
1806                         .type           = WREPL_TYPE_GROUP,
1807                         .state          = WREPL_STATE_TOMBSTONE,
1808                         .node           = WREPL_NODE_B,
1809                         .is_static      = False,
1810                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1811                         .ips            = addresses_B_1,
1812                         .apply_expected = True
1813                 }
1814         },
1815
1816         /* 
1817          * group,tombstone vs. group,active
1818          * => should be replaced
1819          */
1820         {
1821                 .line   = __location__,
1822                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1823                 .r1     = {
1824                         .owner          = &ctx->b,
1825                         .type           = WREPL_TYPE_GROUP,
1826                         .state          = WREPL_STATE_TOMBSTONE,
1827                         .node           = WREPL_NODE_B,
1828                         .is_static      = False,
1829                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1830                         .ips            = addresses_B_1,
1831                         .apply_expected = True
1832                 },
1833                 .r2     = {
1834                         .owner          = &ctx->a,
1835                         .type           = WREPL_TYPE_GROUP,
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
1842                 }
1843         },
1844
1845         /* 
1846          * group,tombstone vs. group,tombstone
1847          * => should be replaced
1848          */
1849         {
1850                 .line   = __location__,
1851                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1852                 .r1     = {
1853                         .owner          = &ctx->a,
1854                         .type           = WREPL_TYPE_GROUP,
1855                         .state          = WREPL_STATE_TOMBSTONE,
1856                         .node           = WREPL_NODE_B,
1857                         .is_static      = False,
1858                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1859                         .ips            = addresses_A_1,
1860                         .apply_expected = True
1861                 },
1862                 .r2     = {
1863                         .owner          = &ctx->b,
1864                         .type           = WREPL_TYPE_GROUP,
1865                         .state          = WREPL_STATE_TOMBSTONE,
1866                         .node           = WREPL_NODE_B,
1867                         .is_static      = False,
1868                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1869                         .ips            = addresses_B_1,
1870                         .apply_expected = True
1871                 }
1872         },
1873
1874 /*
1875  * normal groups vs special groups section,
1876  */
1877         /* 
1878          * group,active vs. sgroup,active
1879          * => should NOT be replaced
1880          */
1881         {
1882                 .line   = __location__,
1883                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1884                 .r1     = {
1885                         .owner          = &ctx->b,
1886                         .type           = WREPL_TYPE_GROUP,
1887                         .state          = WREPL_STATE_ACTIVE,
1888                         .node           = WREPL_NODE_B,
1889                         .is_static      = False,
1890                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1891                         .ips            = addresses_B_1,
1892                         .apply_expected = True
1893                 },
1894                 .r2     = {
1895                         .owner          = &ctx->a,
1896                         .type           = WREPL_TYPE_SGROUP,
1897                         .state          = WREPL_STATE_ACTIVE,
1898                         .node           = WREPL_NODE_B,
1899                         .is_static      = False,
1900                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1901                         .ips            = addresses_B_1,
1902                         .apply_expected = False
1903                 }
1904         },
1905
1906         /* 
1907          * group,active vs. sgroup,tombstone
1908          * => should NOT be replaced
1909          */
1910         {
1911                 .line   = __location__,
1912                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1913                 .r1     = {
1914                         .owner          = &ctx->b,
1915                         .type           = WREPL_TYPE_GROUP,
1916                         .state          = WREPL_STATE_ACTIVE,
1917                         .node           = WREPL_NODE_B,
1918                         .is_static      = False,
1919                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1920                         .ips            = addresses_B_1,
1921                         .apply_expected = True
1922                 },
1923                 .r2     = {
1924                         .owner          = &ctx->a,
1925                         .type           = WREPL_TYPE_SGROUP,
1926                         .state          = WREPL_STATE_TOMBSTONE,
1927                         .node           = WREPL_NODE_B,
1928                         .is_static      = False,
1929                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1930                         .ips            = addresses_B_1,
1931                         .apply_expected = False
1932                 }
1933         },
1934
1935         /* 
1936          * group,released vs. sgroup,active
1937          * => should be replaced
1938          */
1939         {
1940                 .line   = __location__,
1941                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1942                 .r1     = {
1943                         .owner          = &ctx->a,
1944                         .type           = WREPL_TYPE_GROUP,
1945                         .state          = WREPL_STATE_RELEASED,
1946                         .node           = WREPL_NODE_B,
1947                         .is_static      = False,
1948                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1949                         .ips            = addresses_A_1,
1950                         .apply_expected = False
1951                 },
1952                 .r2     = {
1953                         .owner          = &ctx->b,
1954                         .type           = WREPL_TYPE_SGROUP,
1955                         .state          = WREPL_STATE_ACTIVE,
1956                         .node           = WREPL_NODE_B,
1957                         .is_static      = False,
1958                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1959                         .ips            = addresses_B_1,
1960                         .apply_expected = True
1961                 }
1962         },
1963
1964         /* 
1965          * group,released vs. sgroup,tombstone
1966          * => should NOT be replaced
1967          */
1968         {
1969                 .line   = __location__,
1970                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1971                 .r1     = {
1972                         .owner          = &ctx->b,
1973                         .type           = WREPL_TYPE_GROUP,
1974                         .state          = WREPL_STATE_RELEASED,
1975                         .node           = WREPL_NODE_B,
1976                         .is_static      = False,
1977                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1978                         .ips            = addresses_B_1,
1979                         .apply_expected = False
1980                 },
1981                 .r2     = {
1982                         .owner          = &ctx->a,
1983                         .type           = WREPL_TYPE_SGROUP,
1984                         .state          = WREPL_STATE_TOMBSTONE,
1985                         .node           = WREPL_NODE_B,
1986                         .is_static      = False,
1987                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1988                         .ips            = addresses_B_1,
1989                         .apply_expected = False
1990                 }
1991         },
1992
1993         /* 
1994          * group,tombstone vs. sgroup,active
1995          * => should be replaced
1996          */
1997         {
1998                 .line   = __location__,
1999                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2000                 .r1     = {
2001                         .owner          = &ctx->b,
2002                         .type           = WREPL_TYPE_GROUP,
2003                         .state          = WREPL_STATE_TOMBSTONE,
2004                         .node           = WREPL_NODE_B,
2005                         .is_static      = False,
2006                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2007                         .ips            = addresses_B_1,
2008                         .apply_expected = True
2009                 },
2010                 .r2     = {
2011                         .owner          = &ctx->a,
2012                         .type           = WREPL_TYPE_SGROUP,
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
2019                 }
2020         },
2021
2022         /* 
2023          * group,tombstone vs. sgroup,tombstone
2024          * => should be replaced
2025          */
2026         {
2027                 .line   = __location__,
2028                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2029                 .r1     = {
2030                         .owner          = &ctx->a,
2031                         .type           = WREPL_TYPE_GROUP,
2032                         .state          = WREPL_STATE_TOMBSTONE,
2033                         .node           = WREPL_NODE_B,
2034                         .is_static      = False,
2035                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2036                         .ips            = addresses_A_1,
2037                         .apply_expected = True
2038                 },
2039                 .r2     = {
2040                         .owner          = &ctx->b,
2041                         .type           = WREPL_TYPE_SGROUP,
2042                         .state          = WREPL_STATE_TOMBSTONE,
2043                         .node           = WREPL_NODE_B,
2044                         .is_static      = False,
2045                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2046                         .ips            = addresses_B_1,
2047                         .apply_expected = True
2048                 }
2049         },
2050
2051 /*
2052  * normal groups vs multi homed section,
2053  */
2054         /* 
2055          * group,active vs. mhomed,active
2056          * => should NOT be replaced
2057          */
2058         {
2059                 .line   = __location__,
2060                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2061                 .r1     = {
2062                         .owner          = &ctx->b,
2063                         .type           = WREPL_TYPE_GROUP,
2064                         .state          = WREPL_STATE_ACTIVE,
2065                         .node           = WREPL_NODE_B,
2066                         .is_static      = False,
2067                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2068                         .ips            = addresses_B_1,
2069                         .apply_expected = True
2070                 },
2071                 .r2     = {
2072                         .owner          = &ctx->a,
2073                         .type           = WREPL_TYPE_MHOMED,
2074                         .state          = WREPL_STATE_ACTIVE,
2075                         .node           = WREPL_NODE_B,
2076                         .is_static      = False,
2077                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2078                         .ips            = addresses_B_1,
2079                         .apply_expected = False
2080                 }
2081         },
2082
2083         /* 
2084          * group,active vs. mhomed,tombstone
2085          * => should NOT be replaced
2086          */
2087         {
2088                 .line   = __location__,
2089                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2090                 .r1     = {
2091                         .owner          = &ctx->b,
2092                         .type           = WREPL_TYPE_GROUP,
2093                         .state          = WREPL_STATE_ACTIVE,
2094                         .node           = WREPL_NODE_B,
2095                         .is_static      = False,
2096                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2097                         .ips            = addresses_B_1,
2098                         .apply_expected = True
2099                 },
2100                 .r2     = {
2101                         .owner          = &ctx->a,
2102                         .type           = WREPL_TYPE_MHOMED,
2103                         .state          = WREPL_STATE_TOMBSTONE,
2104                         .node           = WREPL_NODE_B,
2105                         .is_static      = False,
2106                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2107                         .ips            = addresses_B_1,
2108                         .apply_expected = False
2109                 }
2110         },
2111
2112         /* 
2113          * group,released vs. mhomed,active
2114          * => should NOT be replaced
2115          */
2116         {
2117                 .line   = __location__,
2118                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2119                 .r1     = {
2120                         .owner          = &ctx->b,
2121                         .type           = WREPL_TYPE_GROUP,
2122                         .state          = WREPL_STATE_RELEASED,
2123                         .node           = WREPL_NODE_B,
2124                         .is_static      = False,
2125                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2126                         .ips            = addresses_B_1,
2127                         .apply_expected = False
2128                 },
2129                 .r2     = {
2130                         .owner          = &ctx->a,
2131                         .type           = WREPL_TYPE_MHOMED,
2132                         .state          = WREPL_STATE_ACTIVE,
2133                         .node           = WREPL_NODE_B,
2134                         .is_static      = False,
2135                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2136                         .ips            = addresses_B_1,
2137                         .apply_expected = False
2138                 }
2139         },
2140
2141         /* 
2142          * group,released vs. mhomed,tombstone
2143          * => should NOT be replaced
2144          */
2145         {
2146                 .line   = __location__,
2147                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2148                 .r1     = {
2149                         .owner          = &ctx->b,
2150                         .type           = WREPL_TYPE_GROUP,
2151                         .state          = WREPL_STATE_RELEASED,
2152                         .node           = WREPL_NODE_B,
2153                         .is_static      = False,
2154                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2155                         .ips            = addresses_B_1,
2156                         .apply_expected = False
2157                 },
2158                 .r2     = {
2159                         .owner          = &ctx->a,
2160                         .type           = WREPL_TYPE_MHOMED,
2161                         .state          = WREPL_STATE_TOMBSTONE,
2162                         .node           = WREPL_NODE_B,
2163                         .is_static      = False,
2164                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2165                         .ips            = addresses_B_1,
2166                         .apply_expected = False
2167                 }
2168         },
2169
2170         /* 
2171          * group,tombstone vs. mhomed,active
2172          * => should be replaced
2173          */
2174         {
2175                 .line   = __location__,
2176                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2177                 .r1     = {
2178                         .owner          = &ctx->b,
2179                         .type           = WREPL_TYPE_GROUP,
2180                         .state          = WREPL_STATE_TOMBSTONE,
2181                         .node           = WREPL_NODE_B,
2182                         .is_static      = False,
2183                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2184                         .ips            = addresses_B_1,
2185                         .apply_expected = True
2186                 },
2187                 .r2     = {
2188                         .owner          = &ctx->a,
2189                         .type           = WREPL_TYPE_MHOMED,
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
2196                 }
2197         },
2198
2199         /* 
2200          * group,tombstone vs. mhomed,tombstone
2201          * => should be replaced
2202          */
2203         {
2204                 .line   = __location__,
2205                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2206                 .r1     = {
2207                         .owner          = &ctx->a,
2208                         .type           = WREPL_TYPE_GROUP,
2209                         .state          = WREPL_STATE_TOMBSTONE,
2210                         .node           = WREPL_NODE_B,
2211                         .is_static      = False,
2212                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2213                         .ips            = addresses_A_1,
2214                         .apply_expected = True
2215                 },
2216                 .r2     = {
2217                         .owner          = &ctx->b,
2218                         .type           = WREPL_TYPE_MHOMED,
2219                         .state          = WREPL_STATE_TOMBSTONE,
2220                         .node           = WREPL_NODE_B,
2221                         .is_static      = False,
2222                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2223                         .ips            = addresses_B_1,
2224                         .apply_expected = True
2225                 }
2226         },
2227
2228 /*
2229  * special groups vs unique section,
2230  */
2231         /* 
2232          * sgroup,active vs. unique,active
2233          * => should NOT be replaced
2234          */
2235         {
2236                 .line   = __location__,
2237                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2238                 .r1     = {
2239                         .owner          = &ctx->b,
2240                         .type           = WREPL_TYPE_SGROUP,
2241                         .state          = WREPL_STATE_ACTIVE,
2242                         .node           = WREPL_NODE_B,
2243                         .is_static      = False,
2244                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2245                         .ips            = addresses_B_1,
2246                         .apply_expected = True
2247                 },
2248                 .r2     = {
2249                         .owner          = &ctx->a,
2250                         .type           = WREPL_TYPE_UNIQUE,
2251                         .state          = WREPL_STATE_ACTIVE,
2252                         .node           = WREPL_NODE_B,
2253                         .is_static      = False,
2254                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2255                         .ips            = addresses_B_1,
2256                         .apply_expected = False
2257                 }
2258         },
2259
2260         /* 
2261          * sgroup,active vs. unique,tombstone
2262          * => should NOT be replaced
2263          */
2264         {
2265                 .line   = __location__,
2266                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2267                 .r1     = {
2268                         .owner          = &ctx->b,
2269                         .type           = WREPL_TYPE_SGROUP,
2270                         .state          = WREPL_STATE_ACTIVE,
2271                         .node           = WREPL_NODE_B,
2272                         .is_static      = False,
2273                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2274                         .ips            = addresses_B_1,
2275                         .apply_expected = True
2276                 },
2277                 .r2     = {
2278                         .owner          = &ctx->a,
2279                         .type           = WREPL_TYPE_UNIQUE,
2280                         .state          = WREPL_STATE_TOMBSTONE,
2281                         .node           = WREPL_NODE_B,
2282                         .is_static      = False,
2283                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2284                         .ips            = addresses_B_1,
2285                         .apply_expected = False
2286                 }
2287         },
2288
2289         /* 
2290          * sgroup,released vs. unique,active
2291          * => should be replaced
2292          */
2293         {
2294                 .line   = __location__,
2295                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2296                 .r1     = {
2297                         .owner          = &ctx->b,
2298                         .type           = WREPL_TYPE_SGROUP,
2299                         .state          = WREPL_STATE_RELEASED,
2300                         .node           = WREPL_NODE_B,
2301                         .is_static      = False,
2302                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2303                         .ips            = addresses_B_1,
2304                         .apply_expected = False
2305                 },
2306                 .r2     = {
2307                         .owner          = &ctx->a,
2308                         .type           = WREPL_TYPE_UNIQUE,
2309                         .state          = WREPL_STATE_ACTIVE,
2310                         .node           = WREPL_NODE_B,
2311                         .is_static      = False,
2312                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2313                         .ips            = addresses_A_1,
2314                         .apply_expected = True
2315                 }
2316         },
2317
2318         /* 
2319          * sgroup,released vs. unique,tombstone
2320          * => should be replaced
2321          */
2322         {
2323                 .line   = __location__,
2324                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2325                 .r1     = {
2326                         .owner          = &ctx->a,
2327                         .type           = WREPL_TYPE_SGROUP,
2328                         .state          = WREPL_STATE_RELEASED,
2329                         .node           = WREPL_NODE_B,
2330                         .is_static      = False,
2331                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2332                         .ips            = addresses_A_1,
2333                         .apply_expected = False
2334                 },
2335                 .r2     = {
2336                         .owner          = &ctx->b,
2337                         .type           = WREPL_TYPE_UNIQUE,
2338                         .state          = WREPL_STATE_TOMBSTONE,
2339                         .node           = WREPL_NODE_B,
2340                         .is_static      = False,
2341                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2342                         .ips            = addresses_B_1,
2343                         .apply_expected = True
2344                 }
2345         },
2346
2347         /* 
2348          * sgroup,tombstone vs. unique,active
2349          * => should be replaced
2350          */
2351         {
2352                 .line   = __location__,
2353                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2354                 .r1     = {
2355                         .owner          = &ctx->a,
2356                         .type           = WREPL_TYPE_SGROUP,
2357                         .state          = WREPL_STATE_TOMBSTONE,
2358                         .node           = WREPL_NODE_B,
2359                         .is_static      = False,
2360                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2361                         .ips            = addresses_A_1,
2362                         .apply_expected = True
2363                 },
2364                 .r2     = {
2365                         .owner          = &ctx->b,
2366                         .type           = WREPL_TYPE_UNIQUE,
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
2373                 }
2374         },
2375
2376         /* 
2377          * sgroup,tombstone vs. unique,tombstone
2378          * => should be replaced
2379          */
2380         {
2381                 .line   = __location__,
2382                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2383                 .r1     = {
2384                         .owner          = &ctx->b,
2385                         .type           = WREPL_TYPE_SGROUP,
2386                         .state          = WREPL_STATE_TOMBSTONE,
2387                         .node           = WREPL_NODE_B,
2388                         .is_static      = False,
2389                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2390                         .ips            = addresses_B_1,
2391                         .apply_expected = True
2392                 },
2393                 .r2     = {
2394                         .owner          = &ctx->a,
2395                         .type           = WREPL_TYPE_UNIQUE,
2396                         .state          = WREPL_STATE_TOMBSTONE,
2397                         .node           = WREPL_NODE_B,
2398                         .is_static      = False,
2399                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2400                         .ips            = addresses_A_1,
2401                         .apply_expected = True
2402                 }
2403         },
2404
2405 /*
2406  * special groups vs normal group section,
2407  */
2408         /* 
2409          * sgroup,active vs. group,active
2410          * => should NOT be replaced
2411          */
2412         {
2413                 .line   = __location__,
2414                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2415                 .r1     = {
2416                         .owner          = &ctx->a,
2417                         .type           = WREPL_TYPE_SGROUP,
2418                         .state          = WREPL_STATE_ACTIVE,
2419                         .node           = WREPL_NODE_B,
2420                         .is_static      = False,
2421                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2422                         .ips            = addresses_A_1,
2423                         .apply_expected = True
2424                 },
2425                 .r2     = {
2426                         .owner          = &ctx->b,
2427                         .type           = WREPL_TYPE_GROUP,
2428                         .state          = WREPL_STATE_ACTIVE,
2429                         .node           = WREPL_NODE_B,
2430                         .is_static      = False,
2431                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2432                         .ips            = addresses_A_1,
2433                         .apply_expected = False
2434                 }
2435         },
2436
2437         /* 
2438          * sgroup,active vs. group,tombstone
2439          * => should NOT be replaced
2440          */
2441         {
2442                 .line   = __location__,
2443                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2444                 .r1     = {
2445                         .owner          = &ctx->a,
2446                         .type           = WREPL_TYPE_SGROUP,
2447                         .state          = WREPL_STATE_ACTIVE,
2448                         .node           = WREPL_NODE_B,
2449                         .is_static      = False,
2450                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2451                         .ips            = addresses_A_1,
2452                         .apply_expected = True
2453                 },
2454                 .r2     = {
2455                         .owner          = &ctx->b,
2456                         .type           = WREPL_TYPE_GROUP,
2457                         .state          = WREPL_STATE_TOMBSTONE,
2458                         .node           = WREPL_NODE_B,
2459                         .is_static      = False,
2460                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2461                         .ips            = addresses_A_1,
2462                         .apply_expected = False
2463                 }
2464         },
2465
2466         /* 
2467          * sgroup,released vs. group,active
2468          * => should be replaced
2469          */
2470         {
2471                 .line   = __location__,
2472                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2473                 .r1     = {
2474                         .owner          = &ctx->a,
2475                         .type           = WREPL_TYPE_SGROUP,
2476                         .state          = WREPL_STATE_RELEASED,
2477                         .node           = WREPL_NODE_B,
2478                         .is_static      = False,
2479                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2480                         .ips            = addresses_A_1,
2481                         .apply_expected = False
2482                 },
2483                 .r2     = {
2484                         .owner          = &ctx->b,
2485                         .type           = WREPL_TYPE_GROUP,
2486                         .state          = WREPL_STATE_ACTIVE,
2487                         .node           = WREPL_NODE_B,
2488                         .is_static      = False,
2489                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2490                         .ips            = addresses_B_1,
2491                         .apply_expected = True
2492                 }
2493         },
2494
2495         /* 
2496          * sgroup,released vs. group,tombstone
2497          * => should be replaced
2498          */
2499         {
2500                 .line   = __location__,
2501                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2502                 .r1     = {
2503                         .owner          = &ctx->b,
2504                         .type           = WREPL_TYPE_SGROUP,
2505                         .state          = WREPL_STATE_RELEASED,
2506                         .node           = WREPL_NODE_B,
2507                         .is_static      = False,
2508                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2509                         .ips            = addresses_B_1,
2510                         .apply_expected = False
2511                 },
2512                 .r2     = {
2513                         .owner          = &ctx->a,
2514                         .type           = WREPL_TYPE_GROUP,
2515                         .state          = WREPL_STATE_TOMBSTONE,
2516                         .node           = WREPL_NODE_B,
2517                         .is_static      = False,
2518                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2519                         .ips            = addresses_A_1,
2520                         .apply_expected = True
2521                 }
2522         },
2523
2524         /* 
2525          * sgroup,tombstone vs. group,active
2526          * => should NOT be replaced
2527          */
2528         {
2529                 .line   = __location__,
2530                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2531                 .r1     = {
2532                         .owner          = &ctx->a,
2533                         .type           = WREPL_TYPE_SGROUP,
2534                         .state          = WREPL_STATE_TOMBSTONE,
2535                         .node           = WREPL_NODE_B,
2536                         .is_static      = False,
2537                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2538                         .ips            = addresses_A_1,
2539                         .apply_expected = True
2540                 },
2541                 .r2     = {
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
2550                 }
2551         },
2552
2553         /* 
2554          * sgroup,tombstone vs. group,tombstone
2555          * => should NOT be replaced
2556          */
2557         {
2558                 .line   = __location__,
2559                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2560                 .r1     = {
2561                         .owner          = &ctx->b,
2562                         .type           = WREPL_TYPE_SGROUP,
2563                         .state          = WREPL_STATE_TOMBSTONE,
2564                         .node           = WREPL_NODE_B,
2565                         .is_static      = False,
2566                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2567                         .ips            = addresses_B_1,
2568                         .apply_expected = True
2569                 },
2570                 .r2     = {
2571                         .owner          = &ctx->a,
2572                         .type           = WREPL_TYPE_GROUP,
2573                         .state          = WREPL_STATE_TOMBSTONE,
2574                         .node           = WREPL_NODE_B,
2575                         .is_static      = False,
2576                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2577                         .ips            = addresses_A_1,
2578                         .apply_expected = True
2579                 }
2580         },
2581
2582 /*
2583  * special groups vs multi homed section,
2584  */
2585         /* 
2586          * sgroup,active vs. mhomed,active
2587          * => should NOT be replaced
2588          */
2589         {
2590                 .line   = __location__,
2591                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2592                 .r1     = {
2593                         .owner          = &ctx->a,
2594                         .type           = WREPL_TYPE_SGROUP,
2595                         .state          = WREPL_STATE_ACTIVE,
2596                         .node           = WREPL_NODE_B,
2597                         .is_static      = False,
2598                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2599                         .ips            = addresses_A_1,
2600                         .apply_expected = True
2601                 },
2602                 .r2     = {
2603                         .owner          = &ctx->b,
2604                         .type           = WREPL_TYPE_MHOMED,
2605                         .state          = WREPL_STATE_ACTIVE,
2606                         .node           = WREPL_NODE_B,
2607                         .is_static      = False,
2608                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2609                         .ips            = addresses_A_1,
2610                         .apply_expected = False
2611                 }
2612         },
2613
2614         /* 
2615          * sgroup,active vs. mhomed,tombstone
2616          * => should NOT be replaced
2617          */
2618         {
2619                 .line   = __location__,
2620                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2621                 .r1     = {
2622                         .owner          = &ctx->a,
2623                         .type           = WREPL_TYPE_SGROUP,
2624                         .state          = WREPL_STATE_ACTIVE,
2625                         .node           = WREPL_NODE_B,
2626                         .is_static      = False,
2627                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2628                         .ips            = addresses_A_1,
2629                         .apply_expected = True
2630                 },
2631                 .r2     = {
2632                         .owner          = &ctx->b,
2633                         .type           = WREPL_TYPE_MHOMED,
2634                         .state          = WREPL_STATE_TOMBSTONE,
2635                         .node           = WREPL_NODE_B,
2636                         .is_static      = False,
2637                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2638                         .ips            = addresses_A_1,
2639                         .apply_expected = False
2640                 }
2641         },
2642
2643         /* 
2644          * sgroup,released vs. mhomed,active
2645          * => should be replaced
2646          */
2647         {
2648                 .line   = __location__,
2649                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2650                 .r1     = {
2651                         .owner          = &ctx->a,
2652                         .type           = WREPL_TYPE_SGROUP,
2653                         .state          = WREPL_STATE_RELEASED,
2654                         .node           = WREPL_NODE_B,
2655                         .is_static      = False,
2656                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2657                         .ips            = addresses_A_1,
2658                         .apply_expected = False
2659                 },
2660                 .r2     = {
2661                         .owner          = &ctx->b,
2662                         .type           = WREPL_TYPE_MHOMED,
2663                         .state          = WREPL_STATE_ACTIVE,
2664                         .node           = WREPL_NODE_B,
2665                         .is_static      = False,
2666                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2667                         .ips            = addresses_B_1,
2668                         .apply_expected = True
2669                 }
2670         },
2671
2672         /* 
2673          * sgroup,released vs. mhomed,tombstone
2674          * => should be replaced
2675          */
2676         {
2677                 .line   = __location__,
2678                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2679                 .r1     = {
2680                         .owner          = &ctx->b,
2681                         .type           = WREPL_TYPE_SGROUP,
2682                         .state          = WREPL_STATE_RELEASED,
2683                         .node           = WREPL_NODE_B,
2684                         .is_static      = False,
2685                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2686                         .ips            = addresses_B_1,
2687                         .apply_expected = False
2688                 },
2689                 .r2     = {
2690                         .owner          = &ctx->a,
2691                         .type           = WREPL_TYPE_MHOMED,
2692                         .state          = WREPL_STATE_TOMBSTONE,
2693                         .node           = WREPL_NODE_B,
2694                         .is_static      = False,
2695                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2696                         .ips            = addresses_A_1,
2697                         .apply_expected = True
2698                 }
2699         },
2700
2701         /* 
2702          * sgroup,tombstone vs. mhomed,active
2703          * => should be replaced
2704          */
2705         {
2706                 .line   = __location__,
2707                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2708                 .r1     = {
2709                         .owner          = &ctx->a,
2710                         .type           = WREPL_TYPE_SGROUP,
2711                         .state          = WREPL_STATE_TOMBSTONE,
2712                         .node           = WREPL_NODE_B,
2713                         .is_static      = False,
2714                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2715                         .ips            = addresses_A_1,
2716                         .apply_expected = True
2717                 },
2718                 .r2     = {
2719                         .owner          = &ctx->b,
2720                         .type           = WREPL_TYPE_MHOMED,
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
2727                 }
2728         },
2729
2730         /* 
2731          * sgroup,tombstone vs. mhomed,tombstone
2732          * => should be replaced
2733          */
2734         {
2735                 .line   = __location__,
2736                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2737                 .r1     = {
2738                         .owner          = &ctx->b,
2739                         .type           = WREPL_TYPE_SGROUP,
2740                         .state          = WREPL_STATE_TOMBSTONE,
2741                         .node           = WREPL_NODE_B,
2742                         .is_static      = False,
2743                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2744                         .ips            = addresses_B_1,
2745                         .apply_expected = True
2746                 },
2747                 .r2     = {
2748                         .owner          = &ctx->a,
2749                         .type           = WREPL_TYPE_MHOMED,
2750                         .state          = WREPL_STATE_TOMBSTONE,
2751                         .node           = WREPL_NODE_B,
2752                         .is_static      = False,
2753                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2754                         .ips            = addresses_A_1,
2755                         .apply_expected = True
2756                 }
2757         },
2758
2759 /*
2760  * multi homed vs. unique section,
2761  */
2762         /* 
2763          * mhomed,active vs. unique,active
2764          * => should be replaced
2765          */
2766         {
2767                 .line   = __location__,
2768                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2769                 .r1     = {
2770                         .owner          = &ctx->a,
2771                         .type           = WREPL_TYPE_MHOMED,
2772                         .state          = WREPL_STATE_ACTIVE,
2773                         .node           = WREPL_NODE_B,
2774                         .is_static      = False,
2775                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
2776                         .ips            = addresses_A_3_4,
2777                         .apply_expected = True
2778                 },
2779                 .r2     = {
2780                         .owner          = &ctx->b,
2781                         .type           = WREPL_TYPE_UNIQUE,
2782                         .state          = WREPL_STATE_ACTIVE,
2783                         .node           = WREPL_NODE_B,
2784                         .is_static      = False,
2785                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2786                         .ips            = addresses_B_1,
2787                         .apply_expected = True
2788                 }
2789         },
2790
2791         /* 
2792          * mhomed,active vs. unique,tombstone
2793          * => should NOT be replaced
2794          */
2795         {
2796                 .line   = __location__,
2797                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2798                 .r1     = {
2799                         .owner          = &ctx->b,
2800                         .type           = WREPL_TYPE_MHOMED,
2801                         .state          = WREPL_STATE_ACTIVE,
2802                         .node           = WREPL_NODE_B,
2803                         .is_static      = False,
2804                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2805                         .ips            = addresses_B_1,
2806                         .apply_expected = True
2807                 },
2808                 .r2     = {
2809                         .owner          = &ctx->a,
2810                         .type           = WREPL_TYPE_UNIQUE,
2811                         .state          = WREPL_STATE_TOMBSTONE,
2812                         .node           = WREPL_NODE_B,
2813                         .is_static      = False,
2814                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2815                         .ips            = addresses_B_1,
2816                         .apply_expected = False
2817                 }
2818         },
2819
2820         /* 
2821          * mhomed,released vs. unique,active
2822          * => should be replaced
2823          */
2824         {
2825                 .line   = __location__,
2826                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2827                 .r1     = {
2828                         .owner          = &ctx->a,
2829                         .type           = WREPL_TYPE_MHOMED,
2830                         .state          = WREPL_STATE_RELEASED,
2831                         .node           = WREPL_NODE_B,
2832                         .is_static      = False,
2833                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2834                         .ips            = addresses_A_1,
2835                         .apply_expected = False
2836                 },
2837                 .r2     = {
2838                         .owner          = &ctx->b,
2839                         .type           = WREPL_TYPE_UNIQUE,
2840                         .state          = WREPL_STATE_ACTIVE,
2841                         .node           = WREPL_NODE_B,
2842                         .is_static      = False,
2843                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2844                         .ips            = addresses_B_1,
2845                         .apply_expected = True
2846                 }
2847         },
2848
2849         /* 
2850          * mhomed,released vs. uinique,tombstone
2851          * => should be replaced
2852          */
2853         {
2854                 .line   = __location__,
2855                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2856                 .r1     = {
2857                         .owner          = &ctx->b,
2858                         .type           = WREPL_TYPE_MHOMED,
2859                         .state          = WREPL_STATE_RELEASED,
2860                         .node           = WREPL_NODE_B,
2861                         .is_static      = False,
2862                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2863                         .ips            = addresses_B_1,
2864                         .apply_expected = False
2865                 },
2866                 .r2     = {
2867                         .owner          = &ctx->a,
2868                         .type           = WREPL_TYPE_UNIQUE,
2869                         .state          = WREPL_STATE_TOMBSTONE,
2870                         .node           = WREPL_NODE_B,
2871                         .is_static      = False,
2872                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2873                         .ips            = addresses_A_1,
2874                         .apply_expected = True
2875                 }
2876         },
2877
2878         /* 
2879          * mhomed,tombstone vs. unique,active
2880          * => should be replaced
2881          */
2882         {
2883                 .line   = __location__,
2884                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2885                 .r1     = {
2886                         .owner          = &ctx->a,
2887                         .type           = WREPL_TYPE_MHOMED,
2888                         .state          = WREPL_STATE_TOMBSTONE,
2889                         .node           = WREPL_NODE_B,
2890                         .is_static      = False,
2891                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2892                         .ips            = addresses_A_1,
2893                         .apply_expected = True
2894                 },
2895                 .r2     = {
2896                         .owner          = &ctx->b,
2897                         .type           = WREPL_TYPE_UNIQUE,
2898                         .state          = WREPL_STATE_ACTIVE,
2899                         .node           = WREPL_NODE_B,
2900                         .is_static      = False,
2901                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2902                         .ips            = addresses_B_1,
2903                         .apply_expected = True
2904                 }
2905         },
2906
2907         /* 
2908          * mhomed,tombstone vs. uinique,tombstone
2909          * => should be replaced
2910          */
2911         {
2912                 .line   = __location__,
2913                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2914                 .r1     = {
2915                         .owner          = &ctx->b,
2916                         .type           = WREPL_TYPE_MHOMED,
2917                         .state          = WREPL_STATE_TOMBSTONE,
2918                         .node           = WREPL_NODE_B,
2919                         .is_static      = False,
2920                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2921                         .ips            = addresses_B_1,
2922                         .apply_expected = True
2923                 },
2924                 .r2     = {
2925                         .owner          = &ctx->a,
2926                         .type           = WREPL_TYPE_UNIQUE,
2927                         .state          = WREPL_STATE_TOMBSTONE,
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
2933                 }
2934         },
2935
2936 /*
2937  * multi homed vs. normal group section,
2938  */
2939         /* 
2940          * mhomed,active vs. group,active
2941          * => should be replaced
2942          */
2943         {
2944                 .line   = __location__,
2945                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2946                 .r1     = {
2947                         .owner          = &ctx->a,
2948                         .type           = WREPL_TYPE_MHOMED,
2949                         .state          = WREPL_STATE_ACTIVE,
2950                         .node           = WREPL_NODE_B,
2951                         .is_static      = False,
2952                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2953                         .ips            = addresses_A_1,
2954                         .apply_expected = True
2955                 },
2956                 .r2     = {
2957                         .owner          = &ctx->b,
2958                         .type           = WREPL_TYPE_GROUP,
2959                         .state          = WREPL_STATE_ACTIVE,
2960                         .node           = WREPL_NODE_B,
2961                         .is_static      = False,
2962                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2963                         .ips            = addresses_B_1,
2964                         .apply_expected = True
2965                 }
2966         },
2967
2968         /* 
2969          * mhomed,active vs. group,tombstone
2970          * => should NOT be replaced
2971          */
2972         {
2973                 .line   = __location__,
2974                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2975                 .r1     = {
2976                         .owner          = &ctx->b,
2977                         .type           = WREPL_TYPE_MHOMED,
2978                         .state          = WREPL_STATE_ACTIVE,
2979                         .node           = WREPL_NODE_B,
2980                         .is_static      = False,
2981                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2982                         .ips            = addresses_B_1,
2983                         .apply_expected = True
2984                 },
2985                 .r2     = {
2986                         .owner          = &ctx->a,
2987                         .type           = WREPL_TYPE_GROUP,
2988                         .state          = WREPL_STATE_TOMBSTONE,
2989                         .node           = WREPL_NODE_B,
2990                         .is_static      = False,
2991                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2992                         .ips            = addresses_B_1,
2993                         .apply_expected = False
2994                 }
2995         },
2996
2997         /* 
2998          * mhomed,released vs. group,active
2999          * => should be replaced
3000          */
3001         {
3002                 .line   = __location__,
3003                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3004                 .r1     = {
3005                         .owner          = &ctx->b,
3006                         .type           = WREPL_TYPE_MHOMED,
3007                         .state          = WREPL_STATE_RELEASED,
3008                         .node           = WREPL_NODE_B,
3009                         .is_static      = False,
3010                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3011                         .ips            = addresses_B_1,
3012                         .apply_expected = False
3013                 },
3014                 .r2     = {
3015                         .owner          = &ctx->a,
3016                         .type           = WREPL_TYPE_GROUP,
3017                         .state          = WREPL_STATE_ACTIVE,
3018                         .node           = WREPL_NODE_B,
3019                         .is_static      = False,
3020                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3021                         .ips            = addresses_A_1,
3022                         .apply_expected = True
3023                 }
3024         },
3025
3026         /* 
3027          * mhomed,released vs. group,tombstone
3028          * => should be replaced
3029          */
3030         {
3031                 .line   = __location__,
3032                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3033                 .r1     = {
3034                         .owner          = &ctx->a,
3035                         .type           = WREPL_TYPE_MHOMED,
3036                         .state          = WREPL_STATE_RELEASED,
3037                         .node           = WREPL_NODE_B,
3038                         .is_static      = False,
3039                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3040                         .ips            = addresses_A_1,
3041                         .apply_expected = False
3042                 },
3043                 .r2     = {
3044                         .owner          = &ctx->b,
3045                         .type           = WREPL_TYPE_GROUP,
3046                         .state          = WREPL_STATE_TOMBSTONE,
3047                         .node           = WREPL_NODE_B,
3048                         .is_static      = False,
3049                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3050                         .ips            = addresses_B_1,
3051                         .apply_expected = True
3052                 }
3053         },
3054
3055         /* 
3056          * mhomed,tombstone vs. group,active
3057          * => should be replaced
3058          */
3059         {
3060                 .line   = __location__,
3061                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3062                 .r1     = {
3063                         .owner          = &ctx->b,
3064                         .type           = WREPL_TYPE_MHOMED,
3065                         .state          = WREPL_STATE_TOMBSTONE,
3066                         .node           = WREPL_NODE_B,
3067                         .is_static      = False,
3068                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3069                         .ips            = addresses_B_1,
3070                         .apply_expected = True
3071                 },
3072                 .r2     = {
3073                         .owner          = &ctx->a,
3074                         .type           = WREPL_TYPE_GROUP,
3075                         .state          = WREPL_STATE_ACTIVE,
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 = True
3081                 }
3082         },
3083
3084         /* 
3085          * mhomed,tombstone vs. group,tombstone
3086          * => should be replaced
3087          */
3088         {
3089                 .line   = __location__,
3090                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3091                 .r1     = {
3092                         .owner          = &ctx->a,
3093                         .type           = WREPL_TYPE_MHOMED,
3094                         .state          = WREPL_STATE_TOMBSTONE,
3095                         .node           = WREPL_NODE_B,
3096                         .is_static      = False,
3097                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3098                         .ips            = addresses_A_1,
3099                         .apply_expected = True
3100                 },
3101                 .r2     = {
3102                         .owner          = &ctx->b,
3103                         .type           = WREPL_TYPE_GROUP,
3104                         .state          = WREPL_STATE_TOMBSTONE,
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 = True
3110                 }
3111         },
3112
3113 /*
3114  * multi homed vs. special group section,
3115  */
3116         /* 
3117          * mhomed,active vs. sgroup,active
3118          * => should NOT be replaced
3119          */
3120         {
3121                 .line   = __location__,
3122                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3123                 .r1     = {
3124                         .owner          = &ctx->a,
3125                         .type           = WREPL_TYPE_MHOMED,
3126                         .state          = WREPL_STATE_ACTIVE,
3127                         .node           = WREPL_NODE_B,
3128                         .is_static      = False,
3129                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3130                         .ips            = addresses_A_1,
3131                         .apply_expected = True
3132                 },
3133                 .r2     = {
3134                         .owner          = &ctx->b,
3135                         .type           = WREPL_TYPE_SGROUP,
3136                         .state          = WREPL_STATE_ACTIVE,
3137                         .node           = WREPL_NODE_B,
3138                         .is_static      = False,
3139                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3140                         .ips            = addresses_A_1,
3141                         .apply_expected = False
3142                 }
3143         },
3144
3145         /* 
3146          * mhomed,active vs. sgroup,tombstone
3147          * => should NOT be replaced
3148          */
3149         {
3150                 .line   = __location__,
3151                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3152                 .r1     = {
3153                         .owner          = &ctx->a,
3154                         .type           = WREPL_TYPE_MHOMED,
3155                         .state          = WREPL_STATE_ACTIVE,
3156                         .node           = WREPL_NODE_B,
3157                         .is_static      = False,
3158                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3159                         .ips            = addresses_A_1,
3160                         .apply_expected = True
3161                 },
3162                 .r2     = {
3163                         .owner          = &ctx->b,
3164                         .type           = WREPL_TYPE_SGROUP,
3165                         .state          = WREPL_STATE_TOMBSTONE,
3166                         .node           = WREPL_NODE_B,
3167                         .is_static      = False,
3168                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3169                         .ips            = addresses_A_1,
3170                         .apply_expected = False
3171                 }
3172         },
3173
3174         /* 
3175          * mhomed,released vs. sgroup,active
3176          * => should be replaced
3177          */
3178         {
3179                 .line   = __location__,
3180                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3181                 .r1     = {
3182                         .owner          = &ctx->a,
3183                         .type           = WREPL_TYPE_MHOMED,
3184                         .state          = WREPL_STATE_RELEASED,
3185                         .node           = WREPL_NODE_B,
3186                         .is_static      = False,
3187                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3188                         .ips            = addresses_A_1,
3189                         .apply_expected = False
3190                 },
3191                 .r2     = {
3192                         .owner          = &ctx->b,
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_B_1),
3198                         .ips            = addresses_B_1,
3199                         .apply_expected = True
3200                 }
3201         },
3202
3203         /* 
3204          * mhomed,released vs. sgroup,tombstone
3205          * => should be replaced
3206          */
3207         {
3208                 .line   = __location__,
3209                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3210                 .r1     = {
3211                         .owner          = &ctx->b,
3212                         .type           = WREPL_TYPE_MHOMED,
3213                         .state          = WREPL_STATE_RELEASED,
3214                         .node           = WREPL_NODE_B,
3215                         .is_static      = False,
3216                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3217                         .ips            = addresses_B_1,
3218                         .apply_expected = False
3219                 },
3220                 .r2     = {
3221                         .owner          = &ctx->a,
3222                         .type           = WREPL_TYPE_SGROUP,
3223                         .state          = WREPL_STATE_TOMBSTONE,
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
3229                 }
3230         },
3231
3232         /* 
3233          * mhomed,tombstone vs. sgroup,active
3234          * => should be replaced
3235          */
3236         {
3237                 .line   = __location__,
3238                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3239                 .r1     = {
3240                         .owner          = &ctx->a,
3241                         .type           = WREPL_TYPE_MHOMED,
3242                         .state          = WREPL_STATE_TOMBSTONE,
3243                         .node           = WREPL_NODE_B,
3244                         .is_static      = False,
3245                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3246                         .ips            = addresses_A_1,
3247                         .apply_expected = True
3248                 },
3249                 .r2     = {
3250                         .owner          = &ctx->b,
3251                         .type           = WREPL_TYPE_SGROUP,
3252                         .state          = WREPL_STATE_ACTIVE,
3253                         .node           = WREPL_NODE_B,
3254                         .is_static      = False,
3255                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3256                         .ips            = addresses_B_1,
3257                         .apply_expected = True
3258                 }
3259         },
3260
3261         /* 
3262          * mhomed,tombstone vs. sgroup,tombstone
3263          * => should be replaced
3264          */
3265         {
3266                 .line   = __location__,
3267                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3268                 .r1     = {
3269                         .owner          = &ctx->b,
3270                         .type           = WREPL_TYPE_MHOMED,
3271                         .state          = WREPL_STATE_TOMBSTONE,
3272                         .node           = WREPL_NODE_B,
3273                         .is_static      = False,
3274                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3275                         .ips            = addresses_B_1,
3276                         .apply_expected = True
3277                 },
3278                 .r2     = {
3279                         .owner          = &ctx->a,
3280                         .type           = WREPL_TYPE_SGROUP,
3281                         .state          = WREPL_STATE_TOMBSTONE,
3282                         .node           = WREPL_NODE_B,
3283                         .is_static      = False,
3284                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3285                         .ips            = addresses_A_1,
3286                         .apply_expected = True
3287                 }
3288         },
3289
3290
3291 #if 0
3292 /*
3293  * special group vs special group section,
3294  */
3295         /* 
3296          * sgroup,active vs. sgroup,active
3297          * => should be merged
3298          */
3299         {
3300                 .line   = __location__,
3301                 .name   = _NBT_NAME("_DIFF_OWNER_SG", 0x00, NULL),
3302                 .extra  = True,
3303                 .r1     = {
3304                         .owner          = &ctx->a,
3305                         .type           = WREPL_TYPE_SGROUP,
3306                         .state          = WREPL_STATE_ACTIVE,
3307                         .node           = WREPL_NODE_B,
3308                         .is_static      = False,
3309                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
3310                         .ips            = addresses_A_3_4,
3311                         .apply_expected = True,
3312                 },
3313                 .r2     = {
3314                         .owner          = &ctx->b,
3315                         .type           = WREPL_TYPE_SGROUP,
3316                         .state          = WREPL_STATE_ACTIVE,
3317                         .node           = WREPL_NODE_B,
3318                         .is_static      = False,
3319                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
3320                         .ips            = addresses_B_3_4,
3321                         .apply_expected = False,
3322                         .merge_expected = True
3323                 }
3324         },
3325         {
3326                 .line   = __location__,
3327                 .name   = _NBT_NAME("_DIFF_OWNER_SG", 0x00, NULL),
3328                 .cleanup= True,
3329                 .r1     = {
3330                         .owner          = &ctx->a,
3331                         .type           = WREPL_TYPE_SGROUP,
3332                         .state          = WREPL_STATE_ACTIVE,
3333                         .node           = WREPL_NODE_B,
3334                         .is_static      = False,
3335                         .num_ips        = 0,
3336                         .ips            = NULL,
3337                         .apply_expected = False
3338                 },
3339                 .r2     = {
3340                         .owner          = &ctx->b,
3341                         .type           = WREPL_TYPE_SGROUP,
3342                         .state          = WREPL_STATE_ACTIVE,
3343                         .node           = WREPL_NODE_B,
3344                         .is_static      = False,
3345                         .num_ips        = 0,
3346                         .ips            = NULL,
3347                         .apply_expected = False,
3348                         .merge_expected = False
3349                 }
3350         },
3351         {
3352                 .line   = __location__,
3353                 .name   = _NBT_NAME("_DIFF_OWNER_SG", 0x00, NULL),
3354                 .cleanup= True,
3355                 .r1     = {
3356                         .owner          = &ctx->a,
3357                         .type           = WREPL_TYPE_SGROUP,
3358                         .state          = WREPL_STATE_ACTIVE,
3359                         .node           = WREPL_NODE_B,
3360                         .is_static      = False,
3361                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3362                         .ips            = addresses_A_1,
3363                         .apply_expected = True
3364                 },
3365                 .r2     = {
3366                         .owner          = &ctx->a,
3367                         .type           = WREPL_TYPE_UNIQUE,
3368                         .state          = WREPL_STATE_TOMBSTONE,
3369                         .node           = WREPL_NODE_B,
3370                         .is_static      = False,
3371                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3372                         .ips            = addresses_A_1,
3373                         .apply_expected = True
3374                 }
3375         },
3376 #endif
3377         /* 
3378          * This should be the last record in this array,
3379          * we need to make sure the we leave a tombstoned unique entry
3380          * owned by OWNER_A
3381          */
3382         {
3383                 .line   = __location__,
3384                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3385                 .cleanup= True,
3386                 .r1     = {
3387                         .owner          = &ctx->a,
3388                         .type           = WREPL_TYPE_UNIQUE,
3389                         .state          = WREPL_STATE_TOMBSTONE,
3390                         .node           = WREPL_NODE_B,
3391                         .is_static      = False,
3392                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3393                         .ips            = addresses_A_1,
3394                         .apply_expected = True
3395                 },
3396                 .r2     = {
3397                         .owner          = &ctx->a,
3398                         .type           = WREPL_TYPE_UNIQUE,
3399                         .state          = WREPL_STATE_TOMBSTONE,
3400                         .node           = WREPL_NODE_B,
3401                         .is_static      = False,
3402                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3403                         .ips            = addresses_A_1,
3404                         .apply_expected = True
3405                 }
3406         }}; /* do not add entries here, this should be the last record! */
3407
3408         if (!ctx) return False;
3409
3410         wins_name_r1    = &wins_name1;
3411         wins_name_r2    = &wins_name2;
3412
3413         printf("Test Replica Conflicts with different owners\n");
3414
3415         for(i=0; ret && i < ARRAY_SIZE(records); i++) {
3416         
3417                 if (!records[i].extra && !records[i].cleanup) {
3418                         /* we should test the worst cases */
3419                         if (records[i].r2.apply_expected && records[i].r1.ips==records[i].r2.ips) {
3420                                 printf("(%s) Programmer error, invalid record[%u]: %s\n",
3421                                         __location__, i, records[i].line);
3422                                 return False;
3423                         } else if (!records[i].r2.apply_expected && records[i].r1.ips!=records[i].r2.ips) {
3424                                 printf("(%s) Programmer error, invalid record[%u]: %s\n",
3425                                         __location__, i, records[i].line);
3426                                 return False;
3427                         }
3428                 }
3429
3430                 if (!records[i].cleanup) {
3431                         const char *expected;
3432                         const char *ips;
3433
3434                         if (records[i].r2.merge_expected) {
3435                                 expected = "MERGE";
3436                         } else if (records[i].r2.apply_expected) {
3437                                 expected = "REPLACE";
3438                         } else {
3439                                 expected = "NOT REPLACE";
3440                         }
3441
3442                         if (!records[i].r1.ips && !records[i].r2.ips) {
3443                                 ips = "no";
3444                         } else if (records[i].r1.ips==records[i].r2.ips) {
3445                                 ips = "same";
3446                         } else {
3447                                 ips = "different";
3448                         }
3449
3450                         printf("%s,%s%s vs. %s,%s%s with %s ip(s) => %s\n",
3451                                 wrepl_name_type_string(records[i].r1.type),
3452                                 wrepl_name_state_string(records[i].r1.state),
3453                                 (records[i].r1.is_static?",static":""),
3454                                 wrepl_name_type_string(records[i].r2.type),
3455                                 wrepl_name_state_string(records[i].r2.state),
3456                                 (records[i].r2.is_static?",static":""),
3457                                 ips, expected);
3458                 }
3459
3460                 /*
3461                  * Setup R1
3462                  */
3463                 wins_name_r1->name      = &records[i].name;
3464                 wins_name_r1->flags     = WREPL_NAME_FLAGS(records[i].r1.type,
3465                                                            records[i].r1.state,
3466                                                            records[i].r1.node,
3467                                                            records[i].r1.is_static);
3468                 wins_name_r1->id        = ++records[i].r1.owner->max_version;
3469                 if (wins_name_r1->flags & 2) {
3470                         wins_name_r1->addresses.addresses.num_ips = records[i].r1.num_ips;
3471                         wins_name_r1->addresses.addresses.ips     = discard_const(records[i].r1.ips);
3472                 } else {
3473                         wins_name_r1->addresses.ip = records[i].r1.ips[0].ip;
3474                 }
3475                 wins_name_r1->unknown   = "255.255.255.255";
3476
3477                 /* now apply R1 */
3478                 ret &= test_wrepl_update_one(ctx, records[i].r1.owner, wins_name_r1);
3479                 ret &= test_wrepl_is_applied(ctx, records[i].r1.owner,
3480                                              wins_name_r1, records[i].r1.apply_expected);
3481
3482                 /*
3483                  * Setup R2
3484                  */
3485                 wins_name_r2->name      = &records[i].name;
3486                 wins_name_r2->flags     = WREPL_NAME_FLAGS(records[i].r2.type,
3487                                                            records[i].r2.state,
3488                                                            records[i].r2.node,
3489                                                            records[i].r2.is_static);
3490                 wins_name_r2->id        = ++records[i].r2.owner->max_version;
3491                 if (wins_name_r2->flags & 2) {
3492                         wins_name_r2->addresses.addresses.num_ips = records[i].r2.num_ips;
3493                         wins_name_r2->addresses.addresses.ips     = discard_const(records[i].r2.ips);
3494                 } else {
3495                         wins_name_r2->addresses.ip = records[i].r2.ips[0].ip;
3496                 }
3497                 wins_name_r2->unknown   = "255.255.255.255";
3498
3499                 /* now apply R2 */
3500                 ret &= test_wrepl_update_one(ctx, records[i].r2.owner, wins_name_r2);
3501                 if (records[i].r1.state == WREPL_STATE_RELEASED) {
3502                         ret &= test_wrepl_is_applied(ctx, records[i].r1.owner,
3503                                                      wins_name_r1, False);
3504                 } else if (records[i].r2.merge_expected) {
3505                         ret &= test_wrepl_is_merged(ctx, wins_name_r1, wins_name_r2);           
3506                 } else if (records[i].r1.owner != records[i].r2.owner) {
3507                         BOOL _expected;
3508                         _expected = (records[i].r1.apply_expected && !records[i].r2.apply_expected);
3509                         ret &= test_wrepl_is_applied(ctx, records[i].r1.owner,
3510                                                      wins_name_r1, _expected);
3511                 }
3512                 if (records[i].r2.state == WREPL_STATE_RELEASED) {
3513                         ret &= test_wrepl_is_applied(ctx, records[i].r2.owner,
3514                                                      wins_name_r2, False);
3515                 } else if (!records[i].r2.merge_expected) {
3516                         ret &= test_wrepl_is_applied(ctx, records[i].r2.owner,
3517                                                      wins_name_r2, records[i].r2.apply_expected);
3518                 }
3519
3520                 /* the first one is a cleanup run */
3521                 if (!ret && i == 0) ret = True;
3522
3523                 if (!ret) {
3524                         printf("conflict handled wrong or record[%u]: %s\n", i, records[i].line);
3525                         return ret;
3526                 }
3527         }
3528
3529         return ret;
3530 }
3531
3532 /*
3533   test WINS replication operations
3534 */
3535 BOOL torture_nbt_winsreplication_quick(void)
3536 {
3537         const char *address;
3538         struct nbt_name name;
3539         TALLOC_CTX *mem_ctx = talloc_new(NULL);
3540         NTSTATUS status;
3541         BOOL ret = True;
3542
3543         make_nbt_name_server(&name, lp_parm_string(-1, "torture", "host"));
3544
3545         /* do an initial name resolution to find its IP */
3546         status = resolve_name(&name, mem_ctx, &address, NULL);
3547         if (!NT_STATUS_IS_OK(status)) {
3548                 printf("Failed to resolve %s - %s\n",
3549                        name.name, nt_errstr(status));
3550                 talloc_free(mem_ctx);
3551                 return False;
3552         }
3553
3554         ret &= test_assoc_ctx1(mem_ctx, address);
3555         ret &= test_assoc_ctx2(mem_ctx, address);
3556
3557         talloc_free(mem_ctx);
3558
3559         return ret;
3560 }
3561
3562 /*
3563   test WINS replication operations
3564 */
3565 BOOL torture_nbt_winsreplication(void)
3566 {
3567         const char *address;
3568         struct nbt_name name;
3569         TALLOC_CTX *mem_ctx = talloc_new(NULL);
3570         NTSTATUS status;
3571         BOOL ret = True;
3572         struct test_wrepl_conflict_conn *ctx;
3573
3574         make_nbt_name_server(&name, lp_parm_string(-1, "torture", "host"));
3575
3576         /* do an initial name resolution to find its IP */
3577         status = resolve_name(&name, mem_ctx, &address, NULL);
3578         if (!NT_STATUS_IS_OK(status)) {
3579                 printf("Failed to resolve %s - %s\n",
3580                        name.name, nt_errstr(status));
3581                 talloc_free(mem_ctx);
3582                 return False;
3583         }
3584
3585         ret &= test_assoc_ctx1(mem_ctx, address);
3586         ret &= test_assoc_ctx2(mem_ctx, address);
3587
3588         ret &= test_wins_replication(mem_ctx, address);
3589
3590         ctx = test_create_conflict_ctx(mem_ctx, address);
3591
3592         ret &= test_conflict_same_owner(ctx);
3593         ret &= test_conflict_different_owner(ctx);
3594
3595         talloc_free(mem_ctx);
3596
3597         return ret;
3598 }