r11177: move unique vs * and normal group vs * into this form
[bbaumbach/samba-autobuild/.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                 .extra  = True,
851                 .r1     = {
852                         .owner          = &ctx->b,
853                         .type           = WREPL_TYPE_UNIQUE,
854                         .state          = WREPL_STATE_ACTIVE,
855                         .node           = WREPL_NODE_B,
856                         .is_static      = False,
857                         .num_ips        = ARRAY_SIZE(addresses_B_1),
858                         .ips            = addresses_B_1,
859                         .apply_expected = True
860                 },
861                 .r2     = {
862                         .owner          = &ctx->a,
863                         .type           = WREPL_TYPE_UNIQUE,
864                         .state          = WREPL_STATE_TOMBSTONE,
865                         .node           = WREPL_NODE_B,
866                         .is_static      = False,
867                         .num_ips        = ARRAY_SIZE(addresses_A_1),
868                         .ips            = addresses_A_1,
869                         .apply_expected = False
870                 }
871         },
872
873         /* 
874          * unique,released vs. unique,active
875          * => should be replaced
876          */
877         {
878                 .line   = __location__,
879                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
880                 .r1     = {
881                         .owner          = &ctx->b,
882                         .type           = WREPL_TYPE_UNIQUE,
883                         .state          = WREPL_STATE_RELEASED,
884                         .node           = WREPL_NODE_B,
885                         .is_static      = False,
886                         .num_ips        = ARRAY_SIZE(addresses_B_1),
887                         .ips            = addresses_B_1,
888                         .apply_expected = False
889                 },
890                 .r2     = {
891                         .owner          = &ctx->a,
892                         .type           = WREPL_TYPE_UNIQUE,
893                         .state          = WREPL_STATE_ACTIVE,
894                         .node           = WREPL_NODE_B,
895                         .is_static      = False,
896                         .num_ips        = ARRAY_SIZE(addresses_A_1),
897                         .ips            = addresses_A_1,
898                         .apply_expected = True
899                 }
900         },
901
902         /* 
903          * unique,released vs. unique,tombstone
904          * => should be replaced
905          */
906         {
907                 .line   = __location__,
908                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
909                 .r1     = {
910                         .owner          = &ctx->a,
911                         .type           = WREPL_TYPE_UNIQUE,
912                         .state          = WREPL_STATE_RELEASED,
913                         .node           = WREPL_NODE_B,
914                         .is_static      = False,
915                         .num_ips        = ARRAY_SIZE(addresses_A_1),
916                         .ips            = addresses_A_1,
917                         .apply_expected = False
918                 },
919                 .r2     = {
920                         .owner          = &ctx->b,
921                         .type           = WREPL_TYPE_UNIQUE,
922                         .state          = WREPL_STATE_TOMBSTONE,
923                         .node           = WREPL_NODE_B,
924                         .is_static      = False,
925                         .num_ips        = ARRAY_SIZE(addresses_B_1),
926                         .ips            = addresses_B_1,
927                         .apply_expected = True
928                 }
929         },
930
931         /* 
932          * unique,tombstone vs. unique,active
933          * => should be replaced
934          */
935         {
936                 .line   = __location__,
937                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
938                 .r1     = {
939                         .owner          = &ctx->b,
940                         .type           = WREPL_TYPE_UNIQUE,
941                         .state          = WREPL_STATE_TOMBSTONE,
942                         .node           = WREPL_NODE_B,
943                         .is_static      = False,
944                         .num_ips        = ARRAY_SIZE(addresses_B_1),
945                         .ips            = addresses_B_1,
946                         .apply_expected = True
947                 },
948                 .r2     = {
949                         .owner          = &ctx->a,
950                         .type           = WREPL_TYPE_UNIQUE,
951                         .state          = WREPL_STATE_ACTIVE,
952                         .node           = WREPL_NODE_B,
953                         .is_static      = False,
954                         .num_ips        = ARRAY_SIZE(addresses_A_1),
955                         .ips            = addresses_A_1,
956                         .apply_expected = True
957                 }
958         },
959
960         /* 
961          * unique,tombstone vs. unique,tombstone
962          * => should be replaced
963          */
964         {
965                 .line   = __location__,
966                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
967                 .r1     = {
968                         .owner          = &ctx->a,
969                         .type           = WREPL_TYPE_UNIQUE,
970                         .state          = WREPL_STATE_TOMBSTONE,
971                         .node           = WREPL_NODE_B,
972                         .is_static      = False,
973                         .num_ips        = ARRAY_SIZE(addresses_A_1),
974                         .ips            = addresses_A_1,
975                         .apply_expected = True
976                 },
977                 .r2     = {
978                         .owner          = &ctx->b,
979                         .type           = WREPL_TYPE_UNIQUE,
980                         .state          = WREPL_STATE_TOMBSTONE,
981                         .node           = WREPL_NODE_B,
982                         .is_static      = False,
983                         .num_ips        = ARRAY_SIZE(addresses_B_1),
984                         .ips            = addresses_B_1,
985                         .apply_expected = True
986                 }
987         },
988
989
990 /*
991  * unique vs normal groups section,
992  */
993         /* 
994          * unique,active vs. group,active
995          * => should be replaced
996          */
997         {
998                 .line   = __location__,
999                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1000                 .r1     = {
1001                         .owner          = &ctx->b,
1002                         .type           = WREPL_TYPE_UNIQUE,
1003                         .state          = WREPL_STATE_ACTIVE,
1004                         .node           = WREPL_NODE_B,
1005                         .is_static      = False,
1006                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1007                         .ips            = addresses_B_1,
1008                         .apply_expected = True
1009                 },
1010                 .r2     = {
1011                         .owner          = &ctx->a,
1012                         .type           = WREPL_TYPE_GROUP,
1013                         .state          = WREPL_STATE_ACTIVE,
1014                         .node           = WREPL_NODE_B,
1015                         .is_static      = False,
1016                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1017                         .ips            = addresses_A_1,
1018                         .apply_expected = True
1019                 }
1020         },
1021
1022         /* 
1023          * unique,active vs. group,tombstone
1024          * => should NOT be replaced
1025          */
1026         {
1027                 .line   = __location__,
1028                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1029                 .r1     = {
1030                         .owner          = &ctx->a,
1031                         .type           = WREPL_TYPE_UNIQUE,
1032                         .state          = WREPL_STATE_ACTIVE,
1033                         .node           = WREPL_NODE_B,
1034                         .is_static      = False,
1035                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1036                         .ips            = addresses_A_1,
1037                         .apply_expected = True
1038                 },
1039                 .r2     = {
1040                         .owner          = &ctx->b,
1041                         .type           = WREPL_TYPE_GROUP,
1042                         .state          = WREPL_STATE_TOMBSTONE,
1043                         .node           = WREPL_NODE_B,
1044                         .is_static      = False,
1045                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1046                         .ips            = addresses_A_1,
1047                         .apply_expected = False
1048                 }
1049         },
1050
1051         /* 
1052          * unique,released vs. group,active
1053          * => should be replaced
1054          */
1055         {
1056                 .line   = __location__,
1057                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1058                 .r1     = {
1059                         .owner          = &ctx->a,
1060                         .type           = WREPL_TYPE_UNIQUE,
1061                         .state          = WREPL_STATE_RELEASED,
1062                         .node           = WREPL_NODE_B,
1063                         .is_static      = False,
1064                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1065                         .ips            = addresses_A_1,
1066                         .apply_expected = False
1067                 },
1068                 .r2     = {
1069                         .owner          = &ctx->b,
1070                         .type           = WREPL_TYPE_GROUP,
1071                         .state          = WREPL_STATE_ACTIVE,
1072                         .node           = WREPL_NODE_B,
1073                         .is_static      = False,
1074                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1075                         .ips            = addresses_B_1,
1076                         .apply_expected = True
1077                 }
1078         },
1079
1080         /* 
1081          * unique,released vs. group,tombstone
1082          * => should be replaced
1083          */
1084         {
1085                 .line   = __location__,
1086                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1087                 .r1     = {
1088                         .owner          = &ctx->b,
1089                         .type           = WREPL_TYPE_UNIQUE,
1090                         .state          = WREPL_STATE_RELEASED,
1091                         .node           = WREPL_NODE_B,
1092                         .is_static      = False,
1093                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1094                         .ips            = addresses_B_1,
1095                         .apply_expected = False
1096                 },
1097                 .r2     = {
1098                         .owner          = &ctx->a,
1099                         .type           = WREPL_TYPE_GROUP,
1100                         .state          = WREPL_STATE_TOMBSTONE,
1101                         .node           = WREPL_NODE_B,
1102                         .is_static      = False,
1103                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1104                         .ips            = addresses_A_1,
1105                         .apply_expected = True
1106                 }
1107         },
1108
1109         /* 
1110          * unique,tombstone vs. group,active
1111          * => should be replaced
1112          */
1113         {
1114                 .line   = __location__,
1115                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1116                 .r1     = {
1117                         .owner          = &ctx->a,
1118                         .type           = WREPL_TYPE_UNIQUE,
1119                         .state          = WREPL_STATE_TOMBSTONE,
1120                         .node           = WREPL_NODE_B,
1121                         .is_static      = False,
1122                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1123                         .ips            = addresses_A_1,
1124                         .apply_expected = True
1125                 },
1126                 .r2     = {
1127                         .owner          = &ctx->b,
1128                         .type           = WREPL_TYPE_GROUP,
1129                         .state          = WREPL_STATE_ACTIVE,
1130                         .node           = WREPL_NODE_B,
1131                         .is_static      = False,
1132                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1133                         .ips            = addresses_B_1,
1134                         .apply_expected = True
1135                 }
1136         },
1137
1138         /* 
1139          * unique,tombstone vs. group,tombstone
1140          * => should be replaced
1141          */
1142         {
1143                 .line   = __location__,
1144                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1145                 .r1     = {
1146                         .owner          = &ctx->b,
1147                         .type           = WREPL_TYPE_UNIQUE,
1148                         .state          = WREPL_STATE_TOMBSTONE,
1149                         .node           = WREPL_NODE_B,
1150                         .is_static      = False,
1151                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1152                         .ips            = addresses_B_1,
1153                         .apply_expected = True
1154                 },
1155                 .r2     = {
1156                         .owner          = &ctx->a,
1157                         .type           = WREPL_TYPE_GROUP,
1158                         .state          = WREPL_STATE_TOMBSTONE,
1159                         .node           = WREPL_NODE_B,
1160                         .is_static      = False,
1161                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1162                         .ips            = addresses_A_1,
1163                         .apply_expected = True
1164                 }
1165         },
1166
1167 /*
1168  * unique vs special groups section,
1169  */
1170         /* 
1171          * unique,active vs. sgroup,active
1172          * => should NOT be replaced
1173          */
1174         {
1175                 .line   = __location__,
1176                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1177                 .r1     = {
1178                         .owner          = &ctx->a,
1179                         .type           = WREPL_TYPE_UNIQUE,
1180                         .state          = WREPL_STATE_ACTIVE,
1181                         .node           = WREPL_NODE_B,
1182                         .is_static      = False,
1183                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1184                         .ips            = addresses_A_1,
1185                         .apply_expected = True
1186                 },
1187                 .r2     = {
1188                         .owner          = &ctx->b,
1189                         .type           = WREPL_TYPE_SGROUP,
1190                         .state          = WREPL_STATE_ACTIVE,
1191                         .node           = WREPL_NODE_B,
1192                         .is_static      = False,
1193                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1194                         .ips            = addresses_A_1,
1195                         .apply_expected = False
1196                 }
1197         },
1198
1199         /* 
1200          * unique,active vs. sgroup,tombstone
1201          * => should NOT be replaced
1202          */
1203         {
1204                 .line   = __location__,
1205                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1206                 .r1     = {
1207                         .owner          = &ctx->a,
1208                         .type           = WREPL_TYPE_UNIQUE,
1209                         .state          = WREPL_STATE_ACTIVE,
1210                         .node           = WREPL_NODE_B,
1211                         .is_static      = False,
1212                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1213                         .ips            = addresses_A_1,
1214                         .apply_expected = True
1215                 },
1216                 .r2     = {
1217                         .owner          = &ctx->b,
1218                         .type           = WREPL_TYPE_SGROUP,
1219                         .state          = WREPL_STATE_TOMBSTONE,
1220                         .node           = WREPL_NODE_B,
1221                         .is_static      = False,
1222                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1223                         .ips            = addresses_A_1,
1224                         .apply_expected = False
1225                 }
1226         },
1227
1228         /* 
1229          * unique,released vs. sgroup,active
1230          * => should be replaced
1231          */
1232         {
1233                 .line   = __location__,
1234                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1235                 .r1     = {
1236                         .owner          = &ctx->a,
1237                         .type           = WREPL_TYPE_UNIQUE,
1238                         .state          = WREPL_STATE_RELEASED,
1239                         .node           = WREPL_NODE_B,
1240                         .is_static      = False,
1241                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1242                         .ips            = addresses_A_1,
1243                         .apply_expected = False
1244                 },
1245                 .r2     = {
1246                         .owner          = &ctx->b,
1247                         .type           = WREPL_TYPE_SGROUP,
1248                         .state          = WREPL_STATE_ACTIVE,
1249                         .node           = WREPL_NODE_B,
1250                         .is_static      = False,
1251                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1252                         .ips            = addresses_B_3_4,
1253                         .apply_expected = True
1254                 }
1255         },
1256
1257         /* 
1258          * unique,released vs. sgroup,tombstone
1259          * => should be replaced
1260          */
1261         {
1262                 .line   = __location__,
1263                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1264                 .r1     = {
1265                         .owner          = &ctx->b,
1266                         .type           = WREPL_TYPE_UNIQUE,
1267                         .state          = WREPL_STATE_RELEASED,
1268                         .node           = WREPL_NODE_B,
1269                         .is_static      = False,
1270                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1271                         .ips            = addresses_B_1,
1272                         .apply_expected = False
1273                 },
1274                 .r2     = {
1275                         .owner          = &ctx->a,
1276                         .type           = WREPL_TYPE_SGROUP,
1277                         .state          = WREPL_STATE_TOMBSTONE,
1278                         .node           = WREPL_NODE_B,
1279                         .is_static      = False,
1280                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
1281                         .ips            = addresses_A_3_4,
1282                         .apply_expected = True
1283                 }
1284         },
1285
1286         /* 
1287          * unique,tombstone vs. sgroup,active
1288          * => should be replaced
1289          */
1290         {
1291                 .line   = __location__,
1292                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1293                 .r1     = {
1294                         .owner          = &ctx->a,
1295                         .type           = WREPL_TYPE_UNIQUE,
1296                         .state          = WREPL_STATE_TOMBSTONE,
1297                         .node           = WREPL_NODE_B,
1298                         .is_static      = False,
1299                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1300                         .ips            = addresses_A_1,
1301                         .apply_expected = True
1302                 },
1303                 .r2     = {
1304                         .owner          = &ctx->b,
1305                         .type           = WREPL_TYPE_SGROUP,
1306                         .state          = WREPL_STATE_ACTIVE,
1307                         .node           = WREPL_NODE_B,
1308                         .is_static      = False,
1309                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1310                         .ips            = addresses_B_3_4,
1311                         .apply_expected = True
1312                 }
1313         },
1314
1315         /* 
1316          * unique,tombstone vs. sgroup,tombstone
1317          * => should be replaced
1318          */
1319         {
1320                 .line   = __location__,
1321                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1322                 .r1     = {
1323                         .owner          = &ctx->b,
1324                         .type           = WREPL_TYPE_UNIQUE,
1325                         .state          = WREPL_STATE_TOMBSTONE,
1326                         .node           = WREPL_NODE_B,
1327                         .is_static      = False,
1328                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1329                         .ips            = addresses_B_1,
1330                         .apply_expected = True
1331                 },
1332                 .r2     = {
1333                         .owner          = &ctx->a,
1334                         .type           = WREPL_TYPE_SGROUP,
1335                         .state          = WREPL_STATE_TOMBSTONE,
1336                         .node           = WREPL_NODE_B,
1337                         .is_static      = False,
1338                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
1339                         .ips            = addresses_A_3_4,
1340                         .apply_expected = True
1341                 }
1342         },
1343
1344 /*
1345  * unique vs multi homed section,
1346  */
1347         /* 
1348          * unique,active vs. mhomed,active
1349          * => should be replaced
1350          */
1351         {
1352                 .line   = __location__,
1353                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1354                 .r1     = {
1355                         .owner          = &ctx->a,
1356                         .type           = WREPL_TYPE_UNIQUE,
1357                         .state          = WREPL_STATE_ACTIVE,
1358                         .node           = WREPL_NODE_B,
1359                         .is_static      = False,
1360                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1361                         .ips            = addresses_A_1,
1362                         .apply_expected = True
1363                 },
1364                 .r2     = {
1365                         .owner          = &ctx->b,
1366                         .type           = WREPL_TYPE_MHOMED,
1367                         .state          = WREPL_STATE_ACTIVE,
1368                         .node           = WREPL_NODE_B,
1369                         .is_static      = False,
1370                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1371                         .ips            = addresses_B_3_4,
1372                         .apply_expected = True
1373                 }
1374         },
1375
1376         /* 
1377          * unique,active vs. mhomed,tombstone
1378          * => should NOT be replaced
1379          */
1380         {
1381                 .line   = __location__,
1382                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1383                 .r1     = {
1384                         .owner          = &ctx->b,
1385                         .type           = WREPL_TYPE_UNIQUE,
1386                         .state          = WREPL_STATE_ACTIVE,
1387                         .node           = WREPL_NODE_B,
1388                         .is_static      = False,
1389                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1390                         .ips            = addresses_B_3_4,
1391                         .apply_expected = True
1392                 },
1393                 .r2     = {
1394                         .owner          = &ctx->a,
1395                         .type           = WREPL_TYPE_MHOMED,
1396                         .state          = WREPL_STATE_TOMBSTONE,
1397                         .node           = WREPL_NODE_B,
1398                         .is_static      = False,
1399                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1400                         .ips            = addresses_B_3_4,
1401                         .apply_expected = False
1402                 }
1403         },
1404
1405         /* 
1406          * unique,released vs. mhomed,active
1407          * => should be replaced
1408          */
1409         {
1410                 .line   = __location__,
1411                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1412                 .r1     = {
1413                         .owner          = &ctx->b,
1414                         .type           = WREPL_TYPE_UNIQUE,
1415                         .state          = WREPL_STATE_RELEASED,
1416                         .node           = WREPL_NODE_B,
1417                         .is_static      = False,
1418                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1419                         .ips            = addresses_B_1,
1420                         .apply_expected = False
1421                 },
1422                 .r2     = {
1423                         .owner          = &ctx->a,
1424                         .type           = WREPL_TYPE_MHOMED,
1425                         .state          = WREPL_STATE_ACTIVE,
1426                         .node           = WREPL_NODE_B,
1427                         .is_static      = False,
1428                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
1429                         .ips            = addresses_A_3_4,
1430                         .apply_expected = True
1431                 }
1432         },
1433
1434         /* 
1435          * unique,released vs. mhomed,tombstone
1436          * => should be replaced
1437          */
1438         {
1439                 .line   = __location__,
1440                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1441                 .r1     = {
1442                         .owner          = &ctx->a,
1443                         .type           = WREPL_TYPE_UNIQUE,
1444                         .state          = WREPL_STATE_RELEASED,
1445                         .node           = WREPL_NODE_B,
1446                         .is_static      = False,
1447                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1448                         .ips            = addresses_A_1,
1449                         .apply_expected = False
1450                 },
1451                 .r2     = {
1452                         .owner          = &ctx->b,
1453                         .type           = WREPL_TYPE_MHOMED,
1454                         .state          = WREPL_STATE_TOMBSTONE,
1455                         .node           = WREPL_NODE_B,
1456                         .is_static      = False,
1457                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1458                         .ips            = addresses_B_3_4,
1459                         .apply_expected = True
1460                 }
1461         },
1462
1463         /* 
1464          * unique,tombstone vs. mhomed,active
1465          * => should be replaced
1466          */
1467         {
1468                 .line   = __location__,
1469                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1470                 .r1     = {
1471                         .owner          = &ctx->b,
1472                         .type           = WREPL_TYPE_UNIQUE,
1473                         .state          = WREPL_STATE_TOMBSTONE,
1474                         .node           = WREPL_NODE_B,
1475                         .is_static      = False,
1476                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1477                         .ips            = addresses_B_1,
1478                         .apply_expected = True
1479                 },
1480                 .r2     = {
1481                         .owner          = &ctx->a,
1482                         .type           = WREPL_TYPE_MHOMED,
1483                         .state          = WREPL_STATE_ACTIVE,
1484                         .node           = WREPL_NODE_B,
1485                         .is_static      = False,
1486                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
1487                         .ips            = addresses_A_3_4,
1488                         .apply_expected = True
1489                 }
1490         },
1491
1492         /* 
1493          * unique,tombstone vs. mhomed,tombstone
1494          * => should be replaced
1495          */
1496         {
1497                 .line   = __location__,
1498                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1499                 .r1     = {
1500                         .owner          = &ctx->a,
1501                         .type           = WREPL_TYPE_UNIQUE,
1502                         .state          = WREPL_STATE_TOMBSTONE,
1503                         .node           = WREPL_NODE_B,
1504                         .is_static      = False,
1505                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1506                         .ips            = addresses_A_1,
1507                         .apply_expected = True
1508                 },
1509                 .r2     = {
1510                         .owner          = &ctx->b,
1511                         .type           = WREPL_TYPE_MHOMED,
1512                         .state          = WREPL_STATE_TOMBSTONE,
1513                         .node           = WREPL_NODE_B,
1514                         .is_static      = False,
1515                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1516                         .ips            = addresses_B_3_4,
1517                         .apply_expected = True
1518                 }
1519         },
1520
1521 /*
1522  * normal groups vs unique section,
1523  */
1524         /* 
1525          * group,active vs. unique,active
1526          * => should NOT be replaced
1527          */
1528         {
1529                 .line   = __location__,
1530                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1531                 .r1     = {
1532                         .owner          = &ctx->a,
1533                         .type           = WREPL_TYPE_GROUP,
1534                         .state          = WREPL_STATE_ACTIVE,
1535                         .node           = WREPL_NODE_B,
1536                         .is_static      = False,
1537                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1538                         .ips            = addresses_A_1,
1539                         .apply_expected = True
1540                 },
1541                 .r2     = {
1542                         .owner          = &ctx->b,
1543                         .type           = WREPL_TYPE_UNIQUE,
1544                         .state          = WREPL_STATE_ACTIVE,
1545                         .node           = WREPL_NODE_B,
1546                         .is_static      = False,
1547                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1548                         .ips            = addresses_A_1,
1549                         .apply_expected = False
1550                 }
1551         },
1552
1553         /* 
1554          * group,active vs. unique,tombstone
1555          * => should NOT be replaced
1556          */
1557         {
1558                 .line   = __location__,
1559                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1560                 .r1     = {
1561                         .owner          = &ctx->a,
1562                         .type           = WREPL_TYPE_GROUP,
1563                         .state          = WREPL_STATE_ACTIVE,
1564                         .node           = WREPL_NODE_B,
1565                         .is_static      = False,
1566                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1567                         .ips            = addresses_A_1,
1568                         .apply_expected = True
1569                 },
1570                 .r2     = {
1571                         .owner          = &ctx->b,
1572                         .type           = WREPL_TYPE_UNIQUE,
1573                         .state          = WREPL_STATE_TOMBSTONE,
1574                         .node           = WREPL_NODE_B,
1575                         .is_static      = False,
1576                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1577                         .ips            = addresses_A_1,
1578                         .apply_expected = False
1579                 }
1580         },
1581
1582         /* 
1583          * group,released vs. unique,active
1584          * => should NOT be replaced
1585          */
1586         {
1587                 .line   = __location__,
1588                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1589                 .r1     = {
1590                         .owner          = &ctx->a,
1591                         .type           = WREPL_TYPE_GROUP,
1592                         .state          = WREPL_STATE_RELEASED,
1593                         .node           = WREPL_NODE_B,
1594                         .is_static      = False,
1595                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1596                         .ips            = addresses_A_1,
1597                         .apply_expected = False
1598                 },
1599                 .r2     = {
1600                         .owner          = &ctx->b,
1601                         .type           = WREPL_TYPE_UNIQUE,
1602                         .state          = WREPL_STATE_ACTIVE,
1603                         .node           = WREPL_NODE_B,
1604                         .is_static      = False,
1605                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1606                         .ips            = addresses_A_1,
1607                         .apply_expected = False
1608                 }
1609         },
1610
1611         /* 
1612          * group,released vs. unique,tombstone
1613          * => should NOT be replaced
1614          */
1615         {
1616                 .line   = __location__,
1617                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1618                 .r1     = {
1619                         .owner          = &ctx->a,
1620                         .type           = WREPL_TYPE_GROUP,
1621                         .state          = WREPL_STATE_RELEASED,
1622                         .node           = WREPL_NODE_B,
1623                         .is_static      = False,
1624                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1625                         .ips            = addresses_A_1,
1626                         .apply_expected = False
1627                 },
1628                 .r2     = {
1629                         .owner          = &ctx->b,
1630                         .type           = WREPL_TYPE_UNIQUE,
1631                         .state          = WREPL_STATE_TOMBSTONE,
1632                         .node           = WREPL_NODE_B,
1633                         .is_static      = False,
1634                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1635                         .ips            = addresses_A_1,
1636                         .apply_expected = False
1637                 }
1638         },
1639
1640         /* 
1641          * group,tombstone vs. unique,active
1642          * => should NOT be replaced
1643          */
1644         {
1645                 .line   = __location__,
1646                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1647                 .r1     = {
1648                         .owner          = &ctx->a,
1649                         .type           = WREPL_TYPE_GROUP,
1650                         .state          = WREPL_STATE_TOMBSTONE,
1651                         .node           = WREPL_NODE_B,
1652                         .is_static      = False,
1653                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1654                         .ips            = addresses_A_1,
1655                         .apply_expected = True
1656                 },
1657                 .r2     = {
1658                         .owner          = &ctx->b,
1659                         .type           = WREPL_TYPE_UNIQUE,
1660                         .state          = WREPL_STATE_ACTIVE,
1661                         .node           = WREPL_NODE_B,
1662                         .is_static      = False,
1663                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1664                         .ips            = addresses_A_1,
1665                         .apply_expected = False
1666                 }
1667         },
1668
1669         /* 
1670          * group,tombstone vs. unique,tombstone
1671          * => should NOT be replaced
1672          */
1673         {
1674                 .line   = __location__,
1675                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1676                 .r1     = {
1677                         .owner          = &ctx->a,
1678                         .type           = WREPL_TYPE_GROUP,
1679                         .state          = WREPL_STATE_TOMBSTONE,
1680                         .node           = WREPL_NODE_B,
1681                         .is_static      = False,
1682                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1683                         .ips            = addresses_A_1,
1684                         .apply_expected = True
1685                 },
1686                 .r2     = {
1687                         .owner          = &ctx->b,
1688                         .type           = WREPL_TYPE_UNIQUE,
1689                         .state          = WREPL_STATE_TOMBSTONE,
1690                         .node           = WREPL_NODE_B,
1691                         .is_static      = False,
1692                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1693                         .ips            = addresses_A_1,
1694                         .apply_expected = False
1695                 }
1696         },
1697
1698 /*
1699  * normal groups vs normal groups section,
1700  */
1701         /* 
1702          * group,active vs. group,active
1703          * => should NOT be replaced
1704          */
1705         {
1706                 .line   = __location__,
1707                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1708                 .r1     = {
1709                         .owner          = &ctx->a,
1710                         .type           = WREPL_TYPE_GROUP,
1711                         .state          = WREPL_STATE_ACTIVE,
1712                         .node           = WREPL_NODE_B,
1713                         .is_static      = False,
1714                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1715                         .ips            = addresses_A_1,
1716                         .apply_expected = True
1717                 },
1718                 .r2     = {
1719                         .owner          = &ctx->b,
1720                         .type           = WREPL_TYPE_GROUP,
1721                         .state          = WREPL_STATE_ACTIVE,
1722                         .node           = WREPL_NODE_B,
1723                         .is_static      = False,
1724                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1725                         .ips            = addresses_A_1,
1726                         .apply_expected = False
1727                 }
1728         },
1729
1730         /* 
1731          * group,active vs. group,tombstone
1732          * => should NOT be replaced
1733          */
1734         {
1735                 .line   = __location__,
1736                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1737                 .r1     = {
1738                         .owner          = &ctx->a,
1739                         .type           = WREPL_TYPE_GROUP,
1740                         .state          = WREPL_STATE_ACTIVE,
1741                         .node           = WREPL_NODE_B,
1742                         .is_static      = False,
1743                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1744                         .ips            = addresses_A_1,
1745                         .apply_expected = True
1746                 },
1747                 .r2     = {
1748                         .owner          = &ctx->b,
1749                         .type           = WREPL_TYPE_GROUP,
1750                         .state          = WREPL_STATE_TOMBSTONE,
1751                         .node           = WREPL_NODE_B,
1752                         .is_static      = False,
1753                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1754                         .ips            = addresses_A_1,
1755                         .apply_expected = False
1756                 }
1757         },
1758
1759         /* 
1760          * group,released vs. group,active
1761          * => should be replaced
1762          */
1763         {
1764                 .line   = __location__,
1765                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1766                 .r1     = {
1767                         .owner          = &ctx->a,
1768                         .type           = WREPL_TYPE_GROUP,
1769                         .state          = WREPL_STATE_RELEASED,
1770                         .node           = WREPL_NODE_B,
1771                         .is_static      = False,
1772                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1773                         .ips            = addresses_A_1,
1774                         .apply_expected = False
1775                 },
1776                 .r2     = {
1777                         .owner          = &ctx->b,
1778                         .type           = WREPL_TYPE_GROUP,
1779                         .state          = WREPL_STATE_ACTIVE,
1780                         .node           = WREPL_NODE_B,
1781                         .is_static      = False,
1782                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1783                         .ips            = addresses_B_1,
1784                         .apply_expected = True
1785                 }
1786         },
1787
1788         /* 
1789          * group,released vs. group,tombstone
1790          * => should be replaced
1791          */
1792         {
1793                 .line   = __location__,
1794                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1795                 .r1     = {
1796                         .owner          = &ctx->a,
1797                         .type           = WREPL_TYPE_GROUP,
1798                         .state          = WREPL_STATE_RELEASED,
1799                         .node           = WREPL_NODE_B,
1800                         .is_static      = False,
1801                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1802                         .ips            = addresses_A_1,
1803                         .apply_expected = False
1804                 },
1805                 .r2     = {
1806                         .owner          = &ctx->b,
1807                         .type           = WREPL_TYPE_GROUP,
1808                         .state          = WREPL_STATE_TOMBSTONE,
1809                         .node           = WREPL_NODE_B,
1810                         .is_static      = False,
1811                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1812                         .ips            = addresses_B_1,
1813                         .apply_expected = True
1814                 }
1815         },
1816
1817         /* 
1818          * group,tombstone vs. group,active
1819          * => should be replaced
1820          */
1821         {
1822                 .line   = __location__,
1823                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1824                 .r1     = {
1825                         .owner          = &ctx->b,
1826                         .type           = WREPL_TYPE_GROUP,
1827                         .state          = WREPL_STATE_TOMBSTONE,
1828                         .node           = WREPL_NODE_B,
1829                         .is_static      = False,
1830                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1831                         .ips            = addresses_B_1,
1832                         .apply_expected = True
1833                 },
1834                 .r2     = {
1835                         .owner          = &ctx->a,
1836                         .type           = WREPL_TYPE_GROUP,
1837                         .state          = WREPL_STATE_ACTIVE,
1838                         .node           = WREPL_NODE_B,
1839                         .is_static      = False,
1840                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1841                         .ips            = addresses_A_1,
1842                         .apply_expected = True
1843                 }
1844         },
1845
1846         /* 
1847          * group,tombstone vs. group,tombstone
1848          * => should be replaced
1849          */
1850         {
1851                 .line   = __location__,
1852                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1853                 .r1     = {
1854                         .owner          = &ctx->a,
1855                         .type           = WREPL_TYPE_GROUP,
1856                         .state          = WREPL_STATE_TOMBSTONE,
1857                         .node           = WREPL_NODE_B,
1858                         .is_static      = False,
1859                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1860                         .ips            = addresses_A_1,
1861                         .apply_expected = True
1862                 },
1863                 .r2     = {
1864                         .owner          = &ctx->b,
1865                         .type           = WREPL_TYPE_GROUP,
1866                         .state          = WREPL_STATE_TOMBSTONE,
1867                         .node           = WREPL_NODE_B,
1868                         .is_static      = False,
1869                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1870                         .ips            = addresses_B_1,
1871                         .apply_expected = True
1872                 }
1873         },
1874
1875 /*
1876  * normal groups vs special groups section,
1877  */
1878         /* 
1879          * group,active vs. sgroup,active
1880          * => should NOT be replaced
1881          */
1882         {
1883                 .line   = __location__,
1884                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1885                 .r1     = {
1886                         .owner          = &ctx->b,
1887                         .type           = WREPL_TYPE_GROUP,
1888                         .state          = WREPL_STATE_ACTIVE,
1889                         .node           = WREPL_NODE_B,
1890                         .is_static      = False,
1891                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1892                         .ips            = addresses_B_1,
1893                         .apply_expected = True
1894                 },
1895                 .r2     = {
1896                         .owner          = &ctx->a,
1897                         .type           = WREPL_TYPE_SGROUP,
1898                         .state          = WREPL_STATE_ACTIVE,
1899                         .node           = WREPL_NODE_B,
1900                         .is_static      = False,
1901                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1902                         .ips            = addresses_B_1,
1903                         .apply_expected = False
1904                 }
1905         },
1906
1907         /* 
1908          * group,active vs. sgroup,tombstone
1909          * => should NOT be replaced
1910          */
1911         {
1912                 .line   = __location__,
1913                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1914                 .r1     = {
1915                         .owner          = &ctx->b,
1916                         .type           = WREPL_TYPE_GROUP,
1917                         .state          = WREPL_STATE_ACTIVE,
1918                         .node           = WREPL_NODE_B,
1919                         .is_static      = False,
1920                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1921                         .ips            = addresses_B_1,
1922                         .apply_expected = True
1923                 },
1924                 .r2     = {
1925                         .owner          = &ctx->a,
1926                         .type           = WREPL_TYPE_SGROUP,
1927                         .state          = WREPL_STATE_TOMBSTONE,
1928                         .node           = WREPL_NODE_B,
1929                         .is_static      = False,
1930                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1931                         .ips            = addresses_B_1,
1932                         .apply_expected = False
1933                 }
1934         },
1935
1936         /* 
1937          * group,released vs. sgroup,active
1938          * => should be replaced
1939          */
1940         {
1941                 .line   = __location__,
1942                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1943                 .r1     = {
1944                         .owner          = &ctx->a,
1945                         .type           = WREPL_TYPE_GROUP,
1946                         .state          = WREPL_STATE_RELEASED,
1947                         .node           = WREPL_NODE_B,
1948                         .is_static      = False,
1949                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1950                         .ips            = addresses_A_1,
1951                         .apply_expected = False
1952                 },
1953                 .r2     = {
1954                         .owner          = &ctx->b,
1955                         .type           = WREPL_TYPE_SGROUP,
1956                         .state          = WREPL_STATE_ACTIVE,
1957                         .node           = WREPL_NODE_B,
1958                         .is_static      = False,
1959                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1960                         .ips            = addresses_B_1,
1961                         .apply_expected = True
1962                 }
1963         },
1964
1965         /* 
1966          * group,released vs. sgroup,tombstone
1967          * => should NOT be replaced
1968          */
1969         {
1970                 .line   = __location__,
1971                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1972                 .r1     = {
1973                         .owner          = &ctx->b,
1974                         .type           = WREPL_TYPE_GROUP,
1975                         .state          = WREPL_STATE_RELEASED,
1976                         .node           = WREPL_NODE_B,
1977                         .is_static      = False,
1978                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1979                         .ips            = addresses_B_1,
1980                         .apply_expected = False
1981                 },
1982                 .r2     = {
1983                         .owner          = &ctx->a,
1984                         .type           = WREPL_TYPE_SGROUP,
1985                         .state          = WREPL_STATE_TOMBSTONE,
1986                         .node           = WREPL_NODE_B,
1987                         .is_static      = False,
1988                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1989                         .ips            = addresses_B_1,
1990                         .apply_expected = False
1991                 }
1992         },
1993
1994         /* 
1995          * group,tombstone vs. sgroup,active
1996          * => should be replaced
1997          */
1998         {
1999                 .line   = __location__,
2000                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2001                 .r1     = {
2002                         .owner          = &ctx->b,
2003                         .type           = WREPL_TYPE_GROUP,
2004                         .state          = WREPL_STATE_TOMBSTONE,
2005                         .node           = WREPL_NODE_B,
2006                         .is_static      = False,
2007                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2008                         .ips            = addresses_B_1,
2009                         .apply_expected = True
2010                 },
2011                 .r2     = {
2012                         .owner          = &ctx->a,
2013                         .type           = WREPL_TYPE_SGROUP,
2014                         .state          = WREPL_STATE_ACTIVE,
2015                         .node           = WREPL_NODE_B,
2016                         .is_static      = False,
2017                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2018                         .ips            = addresses_A_1,
2019                         .apply_expected = True
2020                 }
2021         },
2022
2023         /* 
2024          * group,tombstone vs. sgroup,tombstone
2025          * => should be replaced
2026          */
2027         {
2028                 .line   = __location__,
2029                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2030                 .r1     = {
2031                         .owner          = &ctx->a,
2032                         .type           = WREPL_TYPE_GROUP,
2033                         .state          = WREPL_STATE_TOMBSTONE,
2034                         .node           = WREPL_NODE_B,
2035                         .is_static      = False,
2036                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2037                         .ips            = addresses_A_1,
2038                         .apply_expected = True
2039                 },
2040                 .r2     = {
2041                         .owner          = &ctx->b,
2042                         .type           = WREPL_TYPE_SGROUP,
2043                         .state          = WREPL_STATE_TOMBSTONE,
2044                         .node           = WREPL_NODE_B,
2045                         .is_static      = False,
2046                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2047                         .ips            = addresses_B_1,
2048                         .apply_expected = True
2049                 }
2050         },
2051
2052 /*
2053  * normal groups vs multi homed section,
2054  */
2055         /* 
2056          * group,active vs. mhomed,active
2057          * => should NOT be replaced
2058          */
2059         {
2060                 .line   = __location__,
2061                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2062                 .r1     = {
2063                         .owner          = &ctx->b,
2064                         .type           = WREPL_TYPE_GROUP,
2065                         .state          = WREPL_STATE_ACTIVE,
2066                         .node           = WREPL_NODE_B,
2067                         .is_static      = False,
2068                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2069                         .ips            = addresses_B_1,
2070                         .apply_expected = True
2071                 },
2072                 .r2     = {
2073                         .owner          = &ctx->a,
2074                         .type           = WREPL_TYPE_MHOMED,
2075                         .state          = WREPL_STATE_ACTIVE,
2076                         .node           = WREPL_NODE_B,
2077                         .is_static      = False,
2078                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2079                         .ips            = addresses_B_1,
2080                         .apply_expected = False
2081                 }
2082         },
2083
2084         /* 
2085          * group,active vs. mhomed,tombstone
2086          * => should NOT be replaced
2087          */
2088         {
2089                 .line   = __location__,
2090                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2091                 .r1     = {
2092                         .owner          = &ctx->b,
2093                         .type           = WREPL_TYPE_GROUP,
2094                         .state          = WREPL_STATE_ACTIVE,
2095                         .node           = WREPL_NODE_B,
2096                         .is_static      = False,
2097                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2098                         .ips            = addresses_B_1,
2099                         .apply_expected = True
2100                 },
2101                 .r2     = {
2102                         .owner          = &ctx->a,
2103                         .type           = WREPL_TYPE_MHOMED,
2104                         .state          = WREPL_STATE_TOMBSTONE,
2105                         .node           = WREPL_NODE_B,
2106                         .is_static      = False,
2107                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2108                         .ips            = addresses_B_1,
2109                         .apply_expected = False
2110                 }
2111         },
2112
2113         /* 
2114          * group,released vs. mhomed,active
2115          * => should NOT be replaced
2116          */
2117         {
2118                 .line   = __location__,
2119                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2120                 .r1     = {
2121                         .owner          = &ctx->b,
2122                         .type           = WREPL_TYPE_GROUP,
2123                         .state          = WREPL_STATE_RELEASED,
2124                         .node           = WREPL_NODE_B,
2125                         .is_static      = False,
2126                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2127                         .ips            = addresses_B_1,
2128                         .apply_expected = False
2129                 },
2130                 .r2     = {
2131                         .owner          = &ctx->a,
2132                         .type           = WREPL_TYPE_MHOMED,
2133                         .state          = WREPL_STATE_ACTIVE,
2134                         .node           = WREPL_NODE_B,
2135                         .is_static      = False,
2136                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2137                         .ips            = addresses_B_1,
2138                         .apply_expected = False
2139                 }
2140         },
2141
2142         /* 
2143          * group,released vs. mhomed,tombstone
2144          * => should NOT be replaced
2145          */
2146         {
2147                 .line   = __location__,
2148                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2149                 .r1     = {
2150                         .owner          = &ctx->b,
2151                         .type           = WREPL_TYPE_GROUP,
2152                         .state          = WREPL_STATE_RELEASED,
2153                         .node           = WREPL_NODE_B,
2154                         .is_static      = False,
2155                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2156                         .ips            = addresses_B_1,
2157                         .apply_expected = False
2158                 },
2159                 .r2     = {
2160                         .owner          = &ctx->a,
2161                         .type           = WREPL_TYPE_MHOMED,
2162                         .state          = WREPL_STATE_TOMBSTONE,
2163                         .node           = WREPL_NODE_B,
2164                         .is_static      = False,
2165                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2166                         .ips            = addresses_B_1,
2167                         .apply_expected = False
2168                 }
2169         },
2170
2171         /* 
2172          * group,tombstone vs. mhomed,active
2173          * => should be replaced
2174          */
2175         {
2176                 .line   = __location__,
2177                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2178                 .r1     = {
2179                         .owner          = &ctx->b,
2180                         .type           = WREPL_TYPE_GROUP,
2181                         .state          = WREPL_STATE_TOMBSTONE,
2182                         .node           = WREPL_NODE_B,
2183                         .is_static      = False,
2184                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2185                         .ips            = addresses_B_1,
2186                         .apply_expected = True
2187                 },
2188                 .r2     = {
2189                         .owner          = &ctx->a,
2190                         .type           = WREPL_TYPE_MHOMED,
2191                         .state          = WREPL_STATE_ACTIVE,
2192                         .node           = WREPL_NODE_B,
2193                         .is_static      = False,
2194                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2195                         .ips            = addresses_A_1,
2196                         .apply_expected = True
2197                 }
2198         },
2199
2200         /* 
2201          * group,tombstone vs. mhomed,tombstone
2202          * => should be replaced
2203          */
2204         {
2205                 .line   = __location__,
2206                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2207                 .r1     = {
2208                         .owner          = &ctx->a,
2209                         .type           = WREPL_TYPE_GROUP,
2210                         .state          = WREPL_STATE_TOMBSTONE,
2211                         .node           = WREPL_NODE_B,
2212                         .is_static      = False,
2213                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2214                         .ips            = addresses_A_1,
2215                         .apply_expected = True
2216                 },
2217                 .r2     = {
2218                         .owner          = &ctx->b,
2219                         .type           = WREPL_TYPE_MHOMED,
2220                         .state          = WREPL_STATE_TOMBSTONE,
2221                         .node           = WREPL_NODE_B,
2222                         .is_static      = False,
2223                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2224                         .ips            = addresses_B_1,
2225                         .apply_expected = True
2226                 }
2227         },
2228
2229 /*
2230  * special groups vs unique section,
2231  */
2232         /* 
2233          * sgroup,active vs. unique,active
2234          * => should NOT be replaced
2235          */
2236         {
2237                 .line   = __location__,
2238                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2239                 .r1     = {
2240                         .owner          = &ctx->b,
2241                         .type           = WREPL_TYPE_SGROUP,
2242                         .state          = WREPL_STATE_ACTIVE,
2243                         .node           = WREPL_NODE_B,
2244                         .is_static      = False,
2245                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2246                         .ips            = addresses_B_1,
2247                         .apply_expected = True
2248                 },
2249                 .r2     = {
2250                         .owner          = &ctx->a,
2251                         .type           = WREPL_TYPE_UNIQUE,
2252                         .state          = WREPL_STATE_ACTIVE,
2253                         .node           = WREPL_NODE_B,
2254                         .is_static      = False,
2255                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2256                         .ips            = addresses_B_1,
2257                         .apply_expected = False
2258                 }
2259         },
2260
2261         /* 
2262          * sgroup,active vs. unique,tombstone
2263          * => should NOT be replaced
2264          */
2265         {
2266                 .line   = __location__,
2267                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2268                 .r1     = {
2269                         .owner          = &ctx->b,
2270                         .type           = WREPL_TYPE_SGROUP,
2271                         .state          = WREPL_STATE_ACTIVE,
2272                         .node           = WREPL_NODE_B,
2273                         .is_static      = False,
2274                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2275                         .ips            = addresses_B_1,
2276                         .apply_expected = True
2277                 },
2278                 .r2     = {
2279                         .owner          = &ctx->a,
2280                         .type           = WREPL_TYPE_UNIQUE,
2281                         .state          = WREPL_STATE_TOMBSTONE,
2282                         .node           = WREPL_NODE_B,
2283                         .is_static      = False,
2284                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2285                         .ips            = addresses_B_1,
2286                         .apply_expected = False
2287                 }
2288         },
2289
2290         /* 
2291          * sgroup,released vs. unique,active
2292          * => should be replaced
2293          */
2294         {
2295                 .line   = __location__,
2296                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2297                 .r1     = {
2298                         .owner          = &ctx->b,
2299                         .type           = WREPL_TYPE_SGROUP,
2300                         .state          = WREPL_STATE_RELEASED,
2301                         .node           = WREPL_NODE_B,
2302                         .is_static      = False,
2303                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2304                         .ips            = addresses_B_1,
2305                         .apply_expected = False
2306                 },
2307                 .r2     = {
2308                         .owner          = &ctx->a,
2309                         .type           = WREPL_TYPE_UNIQUE,
2310                         .state          = WREPL_STATE_ACTIVE,
2311                         .node           = WREPL_NODE_B,
2312                         .is_static      = False,
2313                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2314                         .ips            = addresses_A_1,
2315                         .apply_expected = True
2316                 }
2317         },
2318
2319         /* 
2320          * sgroup,released vs. unique,tombstone
2321          * => should be replaced
2322          */
2323         {
2324                 .line   = __location__,
2325                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2326                 .r1     = {
2327                         .owner          = &ctx->a,
2328                         .type           = WREPL_TYPE_SGROUP,
2329                         .state          = WREPL_STATE_RELEASED,
2330                         .node           = WREPL_NODE_B,
2331                         .is_static      = False,
2332                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2333                         .ips            = addresses_A_1,
2334                         .apply_expected = False
2335                 },
2336                 .r2     = {
2337                         .owner          = &ctx->b,
2338                         .type           = WREPL_TYPE_UNIQUE,
2339                         .state          = WREPL_STATE_TOMBSTONE,
2340                         .node           = WREPL_NODE_B,
2341                         .is_static      = False,
2342                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2343                         .ips            = addresses_B_1,
2344                         .apply_expected = True
2345                 }
2346         },
2347
2348         /* 
2349          * sgroup,tombstone vs. unique,active
2350          * => should be replaced
2351          */
2352         {
2353                 .line   = __location__,
2354                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2355                 .r1     = {
2356                         .owner          = &ctx->a,
2357                         .type           = WREPL_TYPE_SGROUP,
2358                         .state          = WREPL_STATE_TOMBSTONE,
2359                         .node           = WREPL_NODE_B,
2360                         .is_static      = False,
2361                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2362                         .ips            = addresses_A_1,
2363                         .apply_expected = True
2364                 },
2365                 .r2     = {
2366                         .owner          = &ctx->b,
2367                         .type           = WREPL_TYPE_UNIQUE,
2368                         .state          = WREPL_STATE_ACTIVE,
2369                         .node           = WREPL_NODE_B,
2370                         .is_static      = False,
2371                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2372                         .ips            = addresses_B_1,
2373                         .apply_expected = True
2374                 }
2375         },
2376
2377         /* 
2378          * sgroup,tombstone vs. unique,tombstone
2379          * => should be replaced
2380          */
2381         {
2382                 .line   = __location__,
2383                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2384                 .r1     = {
2385                         .owner          = &ctx->b,
2386                         .type           = WREPL_TYPE_SGROUP,
2387                         .state          = WREPL_STATE_TOMBSTONE,
2388                         .node           = WREPL_NODE_B,
2389                         .is_static      = False,
2390                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2391                         .ips            = addresses_B_1,
2392                         .apply_expected = True
2393                 },
2394                 .r2     = {
2395                         .owner          = &ctx->a,
2396                         .type           = WREPL_TYPE_UNIQUE,
2397                         .state          = WREPL_STATE_TOMBSTONE,
2398                         .node           = WREPL_NODE_B,
2399                         .is_static      = False,
2400                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2401                         .ips            = addresses_A_1,
2402                         .apply_expected = True
2403                 }
2404         },
2405
2406 /*
2407  * special groups vs normal group section,
2408  */
2409         /* 
2410          * sgroup,active vs. group,active
2411          * => should NOT be replaced
2412          */
2413         {
2414                 .line   = __location__,
2415                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2416                 .r1     = {
2417                         .owner          = &ctx->a,
2418                         .type           = WREPL_TYPE_SGROUP,
2419                         .state          = WREPL_STATE_ACTIVE,
2420                         .node           = WREPL_NODE_B,
2421                         .is_static      = False,
2422                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2423                         .ips            = addresses_A_1,
2424                         .apply_expected = True
2425                 },
2426                 .r2     = {
2427                         .owner          = &ctx->b,
2428                         .type           = WREPL_TYPE_GROUP,
2429                         .state          = WREPL_STATE_ACTIVE,
2430                         .node           = WREPL_NODE_B,
2431                         .is_static      = False,
2432                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2433                         .ips            = addresses_A_1,
2434                         .apply_expected = False
2435                 }
2436         },
2437
2438         /* 
2439          * sgroup,active vs. group,tombstone
2440          * => should NOT be replaced
2441          */
2442         {
2443                 .line   = __location__,
2444                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2445                 .r1     = {
2446                         .owner          = &ctx->a,
2447                         .type           = WREPL_TYPE_SGROUP,
2448                         .state          = WREPL_STATE_ACTIVE,
2449                         .node           = WREPL_NODE_B,
2450                         .is_static      = False,
2451                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2452                         .ips            = addresses_A_1,
2453                         .apply_expected = True
2454                 },
2455                 .r2     = {
2456                         .owner          = &ctx->b,
2457                         .type           = WREPL_TYPE_GROUP,
2458                         .state          = WREPL_STATE_TOMBSTONE,
2459                         .node           = WREPL_NODE_B,
2460                         .is_static      = False,
2461                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2462                         .ips            = addresses_A_1,
2463                         .apply_expected = False
2464                 }
2465         },
2466
2467         /* 
2468          * sgroup,released vs. group,active
2469          * => should be replaced
2470          */
2471         {
2472                 .line   = __location__,
2473                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2474                 .r1     = {
2475                         .owner          = &ctx->a,
2476                         .type           = WREPL_TYPE_SGROUP,
2477                         .state          = WREPL_STATE_RELEASED,
2478                         .node           = WREPL_NODE_B,
2479                         .is_static      = False,
2480                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2481                         .ips            = addresses_A_1,
2482                         .apply_expected = False
2483                 },
2484                 .r2     = {
2485                         .owner          = &ctx->b,
2486                         .type           = WREPL_TYPE_GROUP,
2487                         .state          = WREPL_STATE_ACTIVE,
2488                         .node           = WREPL_NODE_B,
2489                         .is_static      = False,
2490                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2491                         .ips            = addresses_B_1,
2492                         .apply_expected = True
2493                 }
2494         },
2495
2496         /* 
2497          * sgroup,released vs. group,tombstone
2498          * => should be replaced
2499          */
2500         {
2501                 .line   = __location__,
2502                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2503                 .r1     = {
2504                         .owner          = &ctx->b,
2505                         .type           = WREPL_TYPE_SGROUP,
2506                         .state          = WREPL_STATE_RELEASED,
2507                         .node           = WREPL_NODE_B,
2508                         .is_static      = False,
2509                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2510                         .ips            = addresses_B_1,
2511                         .apply_expected = False
2512                 },
2513                 .r2     = {
2514                         .owner          = &ctx->a,
2515                         .type           = WREPL_TYPE_GROUP,
2516                         .state          = WREPL_STATE_TOMBSTONE,
2517                         .node           = WREPL_NODE_B,
2518                         .is_static      = False,
2519                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2520                         .ips            = addresses_A_1,
2521                         .apply_expected = True
2522                 }
2523         },
2524
2525         /* 
2526          * sgroup,tombstone vs. group,active
2527          * => should NOT be replaced
2528          */
2529         {
2530                 .line   = __location__,
2531                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2532                 .r1     = {
2533                         .owner          = &ctx->a,
2534                         .type           = WREPL_TYPE_SGROUP,
2535                         .state          = WREPL_STATE_TOMBSTONE,
2536                         .node           = WREPL_NODE_B,
2537                         .is_static      = False,
2538                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2539                         .ips            = addresses_A_1,
2540                         .apply_expected = True
2541                 },
2542                 .r2     = {
2543                         .owner          = &ctx->b,
2544                         .type           = WREPL_TYPE_GROUP,
2545                         .state          = WREPL_STATE_ACTIVE,
2546                         .node           = WREPL_NODE_B,
2547                         .is_static      = False,
2548                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2549                         .ips            = addresses_B_1,
2550                         .apply_expected = True
2551                 }
2552         },
2553
2554         /* 
2555          * sgroup,tombstone vs. group,tombstone
2556          * => should NOT be replaced
2557          */
2558         {
2559                 .line   = __location__,
2560                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2561                 .r1     = {
2562                         .owner          = &ctx->b,
2563                         .type           = WREPL_TYPE_SGROUP,
2564                         .state          = WREPL_STATE_TOMBSTONE,
2565                         .node           = WREPL_NODE_B,
2566                         .is_static      = False,
2567                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2568                         .ips            = addresses_B_1,
2569                         .apply_expected = True
2570                 },
2571                 .r2     = {
2572                         .owner          = &ctx->a,
2573                         .type           = WREPL_TYPE_GROUP,
2574                         .state          = WREPL_STATE_TOMBSTONE,
2575                         .node           = WREPL_NODE_B,
2576                         .is_static      = False,
2577                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2578                         .ips            = addresses_A_1,
2579                         .apply_expected = True
2580                 }
2581         },
2582
2583 /*
2584  * special groups vs multi homed section,
2585  */
2586         /* 
2587          * sgroup,active vs. mhomed,active
2588          * => should NOT be replaced
2589          */
2590         {
2591                 .line   = __location__,
2592                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2593                 .r1     = {
2594                         .owner          = &ctx->a,
2595                         .type           = WREPL_TYPE_SGROUP,
2596                         .state          = WREPL_STATE_ACTIVE,
2597                         .node           = WREPL_NODE_B,
2598                         .is_static      = False,
2599                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2600                         .ips            = addresses_A_1,
2601                         .apply_expected = True
2602                 },
2603                 .r2     = {
2604                         .owner          = &ctx->b,
2605                         .type           = WREPL_TYPE_MHOMED,
2606                         .state          = WREPL_STATE_ACTIVE,
2607                         .node           = WREPL_NODE_B,
2608                         .is_static      = False,
2609                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2610                         .ips            = addresses_A_1,
2611                         .apply_expected = False
2612                 }
2613         },
2614
2615         /* 
2616          * sgroup,active vs. mhomed,tombstone
2617          * => should NOT be replaced
2618          */
2619         {
2620                 .line   = __location__,
2621                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2622                 .r1     = {
2623                         .owner          = &ctx->a,
2624                         .type           = WREPL_TYPE_SGROUP,
2625                         .state          = WREPL_STATE_ACTIVE,
2626                         .node           = WREPL_NODE_B,
2627                         .is_static      = False,
2628                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2629                         .ips            = addresses_A_1,
2630                         .apply_expected = True
2631                 },
2632                 .r2     = {
2633                         .owner          = &ctx->b,
2634                         .type           = WREPL_TYPE_MHOMED,
2635                         .state          = WREPL_STATE_TOMBSTONE,
2636                         .node           = WREPL_NODE_B,
2637                         .is_static      = False,
2638                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2639                         .ips            = addresses_A_1,
2640                         .apply_expected = False
2641                 }
2642         },
2643
2644         /* 
2645          * sgroup,released vs. mhomed,active
2646          * => should be replaced
2647          */
2648         {
2649                 .line   = __location__,
2650                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2651                 .r1     = {
2652                         .owner          = &ctx->a,
2653                         .type           = WREPL_TYPE_SGROUP,
2654                         .state          = WREPL_STATE_RELEASED,
2655                         .node           = WREPL_NODE_B,
2656                         .is_static      = False,
2657                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2658                         .ips            = addresses_A_1,
2659                         .apply_expected = False
2660                 },
2661                 .r2     = {
2662                         .owner          = &ctx->b,
2663                         .type           = WREPL_TYPE_MHOMED,
2664                         .state          = WREPL_STATE_ACTIVE,
2665                         .node           = WREPL_NODE_B,
2666                         .is_static      = False,
2667                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2668                         .ips            = addresses_B_1,
2669                         .apply_expected = True
2670                 }
2671         },
2672
2673         /* 
2674          * sgroup,released vs. mhomed,tombstone
2675          * => should be replaced
2676          */
2677         {
2678                 .line   = __location__,
2679                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2680                 .r1     = {
2681                         .owner          = &ctx->b,
2682                         .type           = WREPL_TYPE_SGROUP,
2683                         .state          = WREPL_STATE_RELEASED,
2684                         .node           = WREPL_NODE_B,
2685                         .is_static      = False,
2686                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2687                         .ips            = addresses_B_1,
2688                         .apply_expected = False
2689                 },
2690                 .r2     = {
2691                         .owner          = &ctx->a,
2692                         .type           = WREPL_TYPE_MHOMED,
2693                         .state          = WREPL_STATE_TOMBSTONE,
2694                         .node           = WREPL_NODE_B,
2695                         .is_static      = False,
2696                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2697                         .ips            = addresses_A_1,
2698                         .apply_expected = True
2699                 }
2700         },
2701
2702         /* 
2703          * sgroup,tombstone vs. mhomed,active
2704          * => should be replaced
2705          */
2706         {
2707                 .line   = __location__,
2708                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2709                 .r1     = {
2710                         .owner          = &ctx->a,
2711                         .type           = WREPL_TYPE_SGROUP,
2712                         .state          = WREPL_STATE_TOMBSTONE,
2713                         .node           = WREPL_NODE_B,
2714                         .is_static      = False,
2715                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2716                         .ips            = addresses_A_1,
2717                         .apply_expected = True
2718                 },
2719                 .r2     = {
2720                         .owner          = &ctx->b,
2721                         .type           = WREPL_TYPE_MHOMED,
2722                         .state          = WREPL_STATE_ACTIVE,
2723                         .node           = WREPL_NODE_B,
2724                         .is_static      = False,
2725                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2726                         .ips            = addresses_B_1,
2727                         .apply_expected = True
2728                 }
2729         },
2730
2731         /* 
2732          * sgroup,tombstone vs. mhomed,tombstone
2733          * => should be replaced
2734          */
2735         {
2736                 .line   = __location__,
2737                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2738                 .r1     = {
2739                         .owner          = &ctx->b,
2740                         .type           = WREPL_TYPE_SGROUP,
2741                         .state          = WREPL_STATE_TOMBSTONE,
2742                         .node           = WREPL_NODE_B,
2743                         .is_static      = False,
2744                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2745                         .ips            = addresses_B_1,
2746                         .apply_expected = True
2747                 },
2748                 .r2     = {
2749                         .owner          = &ctx->a,
2750                         .type           = WREPL_TYPE_MHOMED,
2751                         .state          = WREPL_STATE_TOMBSTONE,
2752                         .node           = WREPL_NODE_B,
2753                         .is_static      = False,
2754                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2755                         .ips            = addresses_A_1,
2756                         .apply_expected = True
2757                 }
2758         },
2759
2760 /*
2761  * multi homed vs. normal group section,
2762  */
2763         /* 
2764          * mhomed,active vs. group,active
2765          * => should be replaced
2766          */
2767         {
2768                 .line   = __location__,
2769                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2770                 .r1     = {
2771                         .owner          = &ctx->a,
2772                         .type           = WREPL_TYPE_MHOMED,
2773                         .state          = WREPL_STATE_ACTIVE,
2774                         .node           = WREPL_NODE_B,
2775                         .is_static      = False,
2776                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2777                         .ips            = addresses_A_1,
2778                         .apply_expected = True
2779                 },
2780                 .r2     = {
2781                         .owner          = &ctx->b,
2782                         .type           = WREPL_TYPE_GROUP,
2783                         .state          = WREPL_STATE_ACTIVE,
2784                         .node           = WREPL_NODE_B,
2785                         .is_static      = False,
2786                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2787                         .ips            = addresses_B_1,
2788                         .apply_expected = True
2789                 }
2790         },
2791
2792         /* 
2793          * mhomed,active vs. group,tombstone
2794          * => should NOT be replaced
2795          */
2796         {
2797                 .line   = __location__,
2798                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2799                 .r1     = {
2800                         .owner          = &ctx->b,
2801                         .type           = WREPL_TYPE_MHOMED,
2802                         .state          = WREPL_STATE_ACTIVE,
2803                         .node           = WREPL_NODE_B,
2804                         .is_static      = False,
2805                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2806                         .ips            = addresses_B_1,
2807                         .apply_expected = True
2808                 },
2809                 .r2     = {
2810                         .owner          = &ctx->a,
2811                         .type           = WREPL_TYPE_GROUP,
2812                         .state          = WREPL_STATE_TOMBSTONE,
2813                         .node           = WREPL_NODE_B,
2814                         .is_static      = False,
2815                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2816                         .ips            = addresses_B_1,
2817                         .apply_expected = False
2818                 }
2819         },
2820
2821         /* 
2822          * mhomed,released vs. group,active
2823          * => should be replaced
2824          */
2825         {
2826                 .line   = __location__,
2827                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2828                 .r1     = {
2829                         .owner          = &ctx->b,
2830                         .type           = WREPL_TYPE_MHOMED,
2831                         .state          = WREPL_STATE_RELEASED,
2832                         .node           = WREPL_NODE_B,
2833                         .is_static      = False,
2834                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2835                         .ips            = addresses_B_1,
2836                         .apply_expected = False
2837                 },
2838                 .r2     = {
2839                         .owner          = &ctx->a,
2840                         .type           = WREPL_TYPE_GROUP,
2841                         .state          = WREPL_STATE_ACTIVE,
2842                         .node           = WREPL_NODE_B,
2843                         .is_static      = False,
2844                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2845                         .ips            = addresses_A_1,
2846                         .apply_expected = True
2847                 }
2848         },
2849
2850         /* 
2851          * mhomed,released vs. group,tombstone
2852          * => should be replaced
2853          */
2854         {
2855                 .line   = __location__,
2856                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2857                 .r1     = {
2858                         .owner          = &ctx->a,
2859                         .type           = WREPL_TYPE_MHOMED,
2860                         .state          = WREPL_STATE_RELEASED,
2861                         .node           = WREPL_NODE_B,
2862                         .is_static      = False,
2863                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2864                         .ips            = addresses_A_1,
2865                         .apply_expected = False
2866                 },
2867                 .r2     = {
2868                         .owner          = &ctx->b,
2869                         .type           = WREPL_TYPE_GROUP,
2870                         .state          = WREPL_STATE_TOMBSTONE,
2871                         .node           = WREPL_NODE_B,
2872                         .is_static      = False,
2873                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2874                         .ips            = addresses_B_1,
2875                         .apply_expected = True
2876                 }
2877         },
2878
2879         /* 
2880          * mhomed,tombstone vs. group,active
2881          * => should be replaced
2882          */
2883         {
2884                 .line   = __location__,
2885                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2886                 .r1     = {
2887                         .owner          = &ctx->b,
2888                         .type           = WREPL_TYPE_MHOMED,
2889                         .state          = WREPL_STATE_TOMBSTONE,
2890                         .node           = WREPL_NODE_B,
2891                         .is_static      = False,
2892                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2893                         .ips            = addresses_B_1,
2894                         .apply_expected = True
2895                 },
2896                 .r2     = {
2897                         .owner          = &ctx->a,
2898                         .type           = WREPL_TYPE_GROUP,
2899                         .state          = WREPL_STATE_ACTIVE,
2900                         .node           = WREPL_NODE_B,
2901                         .is_static      = False,
2902                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2903                         .ips            = addresses_A_1,
2904                         .apply_expected = True
2905                 }
2906         },
2907
2908         /* 
2909          * mhomed,tombstone vs. group,tombstone
2910          * => should be replaced
2911          */
2912         {
2913                 .line   = __location__,
2914                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2915                 .r1     = {
2916                         .owner          = &ctx->a,
2917                         .type           = WREPL_TYPE_MHOMED,
2918                         .state          = WREPL_STATE_TOMBSTONE,
2919                         .node           = WREPL_NODE_B,
2920                         .is_static      = False,
2921                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2922                         .ips            = addresses_A_1,
2923                         .apply_expected = True
2924                 },
2925                 .r2     = {
2926                         .owner          = &ctx->b,
2927                         .type           = WREPL_TYPE_GROUP,
2928                         .state          = WREPL_STATE_TOMBSTONE,
2929                         .node           = WREPL_NODE_B,
2930                         .is_static      = False,
2931                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2932                         .ips            = addresses_B_1,
2933                         .apply_expected = True
2934                 }
2935         },
2936
2937 /*
2938  * multi homed vs. special group section,
2939  */
2940         /* 
2941          * mhomed,active vs. sgroup,active
2942          * => should NOT be replaced
2943          */
2944         {
2945                 .line   = __location__,
2946                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2947                 .r1     = {
2948                         .owner          = &ctx->a,
2949                         .type           = WREPL_TYPE_MHOMED,
2950                         .state          = WREPL_STATE_ACTIVE,
2951                         .node           = WREPL_NODE_B,
2952                         .is_static      = False,
2953                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2954                         .ips            = addresses_A_1,
2955                         .apply_expected = True
2956                 },
2957                 .r2     = {
2958                         .owner          = &ctx->b,
2959                         .type           = WREPL_TYPE_SGROUP,
2960                         .state          = WREPL_STATE_ACTIVE,
2961                         .node           = WREPL_NODE_B,
2962                         .is_static      = False,
2963                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2964                         .ips            = addresses_A_1,
2965                         .apply_expected = False
2966                 }
2967         },
2968
2969         /* 
2970          * mhomed,active vs. group,tombstone
2971          * => should NOT be replaced
2972          */
2973         {
2974                 .line   = __location__,
2975                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2976                 .r1     = {
2977                         .owner          = &ctx->a,
2978                         .type           = WREPL_TYPE_MHOMED,
2979                         .state          = WREPL_STATE_ACTIVE,
2980                         .node           = WREPL_NODE_B,
2981                         .is_static      = False,
2982                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2983                         .ips            = addresses_A_1,
2984                         .apply_expected = True
2985                 },
2986                 .r2     = {
2987                         .owner          = &ctx->b,
2988                         .type           = WREPL_TYPE_SGROUP,
2989                         .state          = WREPL_STATE_TOMBSTONE,
2990                         .node           = WREPL_NODE_B,
2991                         .is_static      = False,
2992                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2993                         .ips            = addresses_A_1,
2994                         .apply_expected = False
2995                 }
2996         },
2997
2998         /* 
2999          * mhomed,released vs. sgroup,active
3000          * => should be replaced
3001          */
3002         {
3003                 .line   = __location__,
3004                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3005                 .r1     = {
3006                         .owner          = &ctx->a,
3007                         .type           = WREPL_TYPE_MHOMED,
3008                         .state          = WREPL_STATE_RELEASED,
3009                         .node           = WREPL_NODE_B,
3010                         .is_static      = False,
3011                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3012                         .ips            = addresses_A_1,
3013                         .apply_expected = False
3014                 },
3015                 .r2     = {
3016                         .owner          = &ctx->b,
3017                         .type           = WREPL_TYPE_SGROUP,
3018                         .state          = WREPL_STATE_ACTIVE,
3019                         .node           = WREPL_NODE_B,
3020                         .is_static      = False,
3021                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3022                         .ips            = addresses_B_1,
3023                         .apply_expected = True
3024                 }
3025         },
3026
3027         /* 
3028          * mhomed,released vs. group,tombstone
3029          * => should be replaced
3030          */
3031         {
3032                 .line   = __location__,
3033                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3034                 .r1     = {
3035                         .owner          = &ctx->b,
3036                         .type           = WREPL_TYPE_MHOMED,
3037                         .state          = WREPL_STATE_RELEASED,
3038                         .node           = WREPL_NODE_B,
3039                         .is_static      = False,
3040                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3041                         .ips            = addresses_B_1,
3042                         .apply_expected = False
3043                 },
3044                 .r2     = {
3045                         .owner          = &ctx->a,
3046                         .type           = WREPL_TYPE_SGROUP,
3047                         .state          = WREPL_STATE_TOMBSTONE,
3048                         .node           = WREPL_NODE_B,
3049                         .is_static      = False,
3050                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3051                         .ips            = addresses_A_1,
3052                         .apply_expected = True
3053                 }
3054         },
3055
3056         /* 
3057          * mhomed,tombstone vs. sgroup,active
3058          * => should be replaced
3059          */
3060         {
3061                 .line   = __location__,
3062                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3063                 .r1     = {
3064                         .owner          = &ctx->a,
3065                         .type           = WREPL_TYPE_MHOMED,
3066                         .state          = WREPL_STATE_TOMBSTONE,
3067                         .node           = WREPL_NODE_B,
3068                         .is_static      = False,
3069                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3070                         .ips            = addresses_A_1,
3071                         .apply_expected = True
3072                 },
3073                 .r2     = {
3074                         .owner          = &ctx->b,
3075                         .type           = WREPL_TYPE_SGROUP,
3076                         .state          = WREPL_STATE_ACTIVE,
3077                         .node           = WREPL_NODE_B,
3078                         .is_static      = False,
3079                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3080                         .ips            = addresses_B_1,
3081                         .apply_expected = True
3082                 }
3083         },
3084
3085         /* 
3086          * mhomed,tombstone vs. group,tombstone
3087          * => should be replaced
3088          */
3089         {
3090                 .line   = __location__,
3091                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3092                 .r1     = {
3093                         .owner          = &ctx->b,
3094                         .type           = WREPL_TYPE_MHOMED,
3095                         .state          = WREPL_STATE_TOMBSTONE,
3096                         .node           = WREPL_NODE_B,
3097                         .is_static      = False,
3098                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3099                         .ips            = addresses_B_1,
3100                         .apply_expected = True
3101                 },
3102                 .r2     = {
3103                         .owner          = &ctx->a,
3104                         .type           = WREPL_TYPE_SGROUP,
3105                         .state          = WREPL_STATE_TOMBSTONE,
3106                         .node           = WREPL_NODE_B,
3107                         .is_static      = False,
3108                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3109                         .ips            = addresses_A_1,
3110                         .apply_expected = True
3111                 }
3112         },
3113
3114
3115 #if 0
3116 /*
3117  * special group vs special group section,
3118  */
3119         /* 
3120          * sgroup,active vs. sgroup,active
3121          * => should be merged
3122          */
3123         {
3124                 .line   = __location__,
3125                 .name   = _NBT_NAME("_DIFF_OWNER_SG", 0x00, NULL),
3126                 .extra  = True,
3127                 .r1     = {
3128                         .owner          = &ctx->a,
3129                         .type           = WREPL_TYPE_SGROUP,
3130                         .state          = WREPL_STATE_ACTIVE,
3131                         .node           = WREPL_NODE_B,
3132                         .is_static      = False,
3133                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
3134                         .ips            = addresses_A_3_4,
3135                         .apply_expected = True,
3136                 },
3137                 .r2     = {
3138                         .owner          = &ctx->b,
3139                         .type           = WREPL_TYPE_SGROUP,
3140                         .state          = WREPL_STATE_ACTIVE,
3141                         .node           = WREPL_NODE_B,
3142                         .is_static      = False,
3143                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
3144                         .ips            = addresses_B_3_4,
3145                         .apply_expected = False,
3146                         .merge_expected = True
3147                 }
3148         },
3149         {
3150                 .line   = __location__,
3151                 .name   = _NBT_NAME("_DIFF_OWNER_SG", 0x00, NULL),
3152                 .cleanup= True,
3153                 .r1     = {
3154                         .owner          = &ctx->a,
3155                         .type           = WREPL_TYPE_SGROUP,
3156                         .state          = WREPL_STATE_ACTIVE,
3157                         .node           = WREPL_NODE_B,
3158                         .is_static      = False,
3159                         .num_ips        = 0,
3160                         .ips            = NULL,
3161                         .apply_expected = False
3162                 },
3163                 .r2     = {
3164                         .owner          = &ctx->b,
3165                         .type           = WREPL_TYPE_SGROUP,
3166                         .state          = WREPL_STATE_ACTIVE,
3167                         .node           = WREPL_NODE_B,
3168                         .is_static      = False,
3169                         .num_ips        = 0,
3170                         .ips            = NULL,
3171                         .apply_expected = False,
3172                         .merge_expected = False
3173                 }
3174         },
3175         {
3176                 .line   = __location__,
3177                 .name   = _NBT_NAME("_DIFF_OWNER_SG", 0x00, NULL),
3178                 .cleanup= True,
3179                 .r1     = {
3180                         .owner          = &ctx->a,
3181                         .type           = WREPL_TYPE_SGROUP,
3182                         .state          = WREPL_STATE_ACTIVE,
3183                         .node           = WREPL_NODE_B,
3184                         .is_static      = False,
3185                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3186                         .ips            = addresses_A_1,
3187                         .apply_expected = True
3188                 },
3189                 .r2     = {
3190                         .owner          = &ctx->a,
3191                         .type           = WREPL_TYPE_UNIQUE,
3192                         .state          = WREPL_STATE_TOMBSTONE,
3193                         .node           = WREPL_NODE_B,
3194                         .is_static      = False,
3195                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3196                         .ips            = addresses_A_1,
3197                         .apply_expected = True
3198                 }
3199         },
3200 #endif
3201         /* 
3202          * This should be the last record in this array,
3203          * we need to make sure the we leave a tombstoned unique entry
3204          * owned by OWNER_A
3205          */
3206         {
3207                 .line   = __location__,
3208                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3209                 .cleanup= True,
3210                 .r1     = {
3211                         .owner          = &ctx->a,
3212                         .type           = WREPL_TYPE_UNIQUE,
3213                         .state          = WREPL_STATE_TOMBSTONE,
3214                         .node           = WREPL_NODE_B,
3215                         .is_static      = False,
3216                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3217                         .ips            = addresses_A_1,
3218                         .apply_expected = True
3219                 },
3220                 .r2     = {
3221                         .owner          = &ctx->a,
3222                         .type           = WREPL_TYPE_UNIQUE,
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         }}; /* do not add entries here, this should be the last record! */
3231
3232         if (!ctx) return False;
3233
3234         wins_name_r1    = &wins_name1;
3235         wins_name_r2    = &wins_name2;
3236
3237         printf("Test Replica Conflicts with different owners\n");
3238
3239         for(i=0; ret && i < ARRAY_SIZE(records); i++) {
3240         
3241                 if (!records[i].extra && !records[i].cleanup) {
3242                         /* we should test the worst cases */
3243                         if (records[i].r2.apply_expected && records[i].r1.ips==records[i].r2.ips) {
3244                                 printf("(%s) Programmer error, invalid record[%u]: %s\n",
3245                                         __location__, i, records[i].line);
3246                                 return False;
3247                         } else if (!records[i].r2.apply_expected && records[i].r1.ips!=records[i].r2.ips) {
3248                                 printf("(%s) Programmer error, invalid record[%u]: %s\n",
3249                                         __location__, i, records[i].line);
3250                                 return False;
3251                         }
3252                 }
3253
3254                 if (!records[i].cleanup) {
3255                         const char *expected;
3256                         const char *ips;
3257
3258                         if (records[i].r2.merge_expected) {
3259                                 expected = "MERGE";
3260                         } else if (records[i].r2.apply_expected) {
3261                                 expected = "REPLACE";
3262                         } else {
3263                                 expected = "NOT REPLACE";
3264                         }
3265
3266                         if (!records[i].r1.ips && !records[i].r2.ips) {
3267                                 ips = "no";
3268                         } else if (records[i].r1.ips==records[i].r2.ips) {
3269                                 ips = "same";
3270                         } else {
3271                                 ips = "different";
3272                         }
3273
3274                         printf("%s,%s%s vs. %s,%s%s with %s ip(s) => %s\n",
3275                                 wrepl_name_type_string(records[i].r1.type),
3276                                 wrepl_name_state_string(records[i].r1.state),
3277                                 (records[i].r1.is_static?",static":""),
3278                                 wrepl_name_type_string(records[i].r2.type),
3279                                 wrepl_name_state_string(records[i].r2.state),
3280                                 (records[i].r2.is_static?",static":""),
3281                                 ips, expected);
3282                 }
3283
3284                 /*
3285                  * Setup R1
3286                  */
3287                 wins_name_r1->name      = &records[i].name;
3288                 wins_name_r1->flags     = WREPL_NAME_FLAGS(records[i].r1.type,
3289                                                            records[i].r1.state,
3290                                                            records[i].r1.node,
3291                                                            records[i].r1.is_static);
3292                 wins_name_r1->id        = ++records[i].r1.owner->max_version;
3293                 if (wins_name_r1->flags & 2) {
3294                         wins_name_r1->addresses.addresses.num_ips = records[i].r1.num_ips;
3295                         wins_name_r1->addresses.addresses.ips     = discard_const(records[i].r1.ips);
3296                 } else {
3297                         wins_name_r1->addresses.ip = records[i].r1.ips[0].ip;
3298                 }
3299                 wins_name_r1->unknown   = "255.255.255.255";
3300
3301                 /* now apply R1 */
3302                 ret &= test_wrepl_update_one(ctx, records[i].r1.owner, wins_name_r1);
3303                 ret &= test_wrepl_is_applied(ctx, records[i].r1.owner,
3304                                              wins_name_r1, records[i].r1.apply_expected);
3305
3306                 /*
3307                  * Setup R2
3308                  */
3309                 wins_name_r2->name      = &records[i].name;
3310                 wins_name_r2->flags     = WREPL_NAME_FLAGS(records[i].r2.type,
3311                                                            records[i].r2.state,
3312                                                            records[i].r2.node,
3313                                                            records[i].r2.is_static);
3314                 wins_name_r2->id        = ++records[i].r2.owner->max_version;
3315                 if (wins_name_r2->flags & 2) {
3316                         wins_name_r2->addresses.addresses.num_ips = records[i].r2.num_ips;
3317                         wins_name_r2->addresses.addresses.ips     = discard_const(records[i].r2.ips);
3318                 } else {
3319                         wins_name_r2->addresses.ip = records[i].r2.ips[0].ip;
3320                 }
3321                 wins_name_r2->unknown   = "255.255.255.255";
3322
3323                 /* now apply R2 */
3324                 ret &= test_wrepl_update_one(ctx, records[i].r2.owner, wins_name_r2);
3325                 if (records[i].r1.state == WREPL_STATE_RELEASED) {
3326                         ret &= test_wrepl_is_applied(ctx, records[i].r1.owner,
3327                                                      wins_name_r1, False);
3328                 } else if (records[i].r2.merge_expected) {
3329                         ret &= test_wrepl_is_merged(ctx, wins_name_r1, wins_name_r2);           
3330                 } else if (records[i].r1.owner != records[i].r2.owner) {
3331                         BOOL _expected;
3332                         _expected = (records[i].r1.apply_expected && !records[i].r2.apply_expected);
3333                         ret &= test_wrepl_is_applied(ctx, records[i].r1.owner,
3334                                                      wins_name_r1, _expected);
3335                 }
3336                 if (records[i].r2.state == WREPL_STATE_RELEASED) {
3337                         ret &= test_wrepl_is_applied(ctx, records[i].r2.owner,
3338                                                      wins_name_r2, False);
3339                 } else if (!records[i].r2.merge_expected) {
3340                         ret &= test_wrepl_is_applied(ctx, records[i].r2.owner,
3341                                                      wins_name_r2, records[i].r2.apply_expected);
3342                 }
3343
3344                 /* the first one is a cleanup run */
3345                 if (!ret && i == 0) ret = True;
3346
3347                 if (!ret) {
3348                         printf("conflict handled wrong or record[%u]: %s\n", i, records[i].line);
3349                         return ret;
3350                 }
3351         }
3352
3353         return ret;
3354 }
3355
3356 /*
3357   test WINS replication operations
3358 */
3359 BOOL torture_nbt_winsreplication_quick(void)
3360 {
3361         const char *address;
3362         struct nbt_name name;
3363         TALLOC_CTX *mem_ctx = talloc_new(NULL);
3364         NTSTATUS status;
3365         BOOL ret = True;
3366
3367         make_nbt_name_server(&name, lp_parm_string(-1, "torture", "host"));
3368
3369         /* do an initial name resolution to find its IP */
3370         status = resolve_name(&name, mem_ctx, &address, NULL);
3371         if (!NT_STATUS_IS_OK(status)) {
3372                 printf("Failed to resolve %s - %s\n",
3373                        name.name, nt_errstr(status));
3374                 talloc_free(mem_ctx);
3375                 return False;
3376         }
3377
3378         ret &= test_assoc_ctx1(mem_ctx, address);
3379         ret &= test_assoc_ctx2(mem_ctx, address);
3380
3381         talloc_free(mem_ctx);
3382
3383         return ret;
3384 }
3385
3386 /*
3387   test WINS replication operations
3388 */
3389 BOOL torture_nbt_winsreplication(void)
3390 {
3391         const char *address;
3392         struct nbt_name name;
3393         TALLOC_CTX *mem_ctx = talloc_new(NULL);
3394         NTSTATUS status;
3395         BOOL ret = True;
3396         struct test_wrepl_conflict_conn *ctx;
3397
3398         make_nbt_name_server(&name, lp_parm_string(-1, "torture", "host"));
3399
3400         /* do an initial name resolution to find its IP */
3401         status = resolve_name(&name, mem_ctx, &address, NULL);
3402         if (!NT_STATUS_IS_OK(status)) {
3403                 printf("Failed to resolve %s - %s\n",
3404                        name.name, nt_errstr(status));
3405                 talloc_free(mem_ctx);
3406                 return False;
3407         }
3408
3409         ret &= test_assoc_ctx1(mem_ctx, address);
3410         ret &= test_assoc_ctx2(mem_ctx, address);
3411
3412         ret &= test_wins_replication(mem_ctx, address);
3413
3414         ctx = test_create_conflict_ctx(mem_ctx, address);
3415
3416         ret &= test_conflict_same_owner(ctx);
3417         ret &= test_conflict_different_owner(ctx);
3418
3419         talloc_free(mem_ctx);
3420
3421         return ret;
3422 }