52e1fc827115ad802411df21a7b74358cb3fa3b6
[yangtools.git] / yang / yang-data-api / src / test / java / org / opendaylight / yangtools / yang / data / api / schema / tree / DataTreeCandidatesAggregateTest.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.data.api.schema.tree;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.mockito.Mockito.doReturn;
12 import static org.mockito.Mockito.mock;
13 import static org.mockito.Mockito.when;
14
15 import java.util.Arrays;
16 import java.util.Collections;
17 import java.util.List;
18 import java.util.Optional;
19 import org.junit.Test;
20 import org.opendaylight.yangtools.yang.common.QName;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
23 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
24
25 public class DataTreeCandidatesAggregateTest {
26     private static final YangInstanceIdentifier ROOT_PATH = YangInstanceIdentifier.of(QName.create(
27             "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:container",
28             "2014-03-13", "container"));
29     private static final YangInstanceIdentifier.PathArgument CHILD_ID = new NodeIdentifier(QName.create(
30             "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:container:data",
31             "2014-03-13", "data"));
32
33     @Test
34     public void testLeafUnmodifiedUnmodified() {
35         NormalizedNode<?, ?> normalizedNode1 = normalizedNode("value1");
36         NormalizedNode<?, ?> normalizedNode2 = normalizedNode("value1");
37         NormalizedNode<?, ?> normalizedNode3 = normalizedNode("value1");
38
39         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, normalizedNode2,
40                 ModificationType.UNMODIFIED);
41         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
42
43         DataTreeCandidateNode node2 = dataTreeCandidateNode(normalizedNode2, normalizedNode3,
44                 ModificationType.UNMODIFIED);
45         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
46
47         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
48
49         assertEquals(ModificationType.UNMODIFIED, aggregationResult.getRootNode().getModificationType());
50         assertEquals("value1", aggregationResult.getRootNode().getDataBefore().get().getValue());
51         assertEquals("value1", aggregationResult.getRootNode().getDataAfter().get().getValue());
52     }
53
54     @Test
55     public void testLeaftUnmodifiedWrite() {
56         NormalizedNode<?, ?> normalizedNode1 = normalizedNode("value1");
57         NormalizedNode<?, ?> normalizedNode2 = normalizedNode("value1");
58         NormalizedNode<?, ?> normalizedNode3 = normalizedNode("value2");
59
60         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, normalizedNode2,
61                 ModificationType.UNMODIFIED);
62         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
63
64         DataTreeCandidateNode node2 = dataTreeCandidateNode(normalizedNode2, normalizedNode3,
65                 ModificationType.WRITE);
66         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
67
68         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
69
70         assertEquals(ModificationType.WRITE, aggregationResult.getRootNode().getModificationType());
71         assertEquals("value1", aggregationResult.getRootNode().getDataBefore().get().getValue());
72         assertEquals("value2", aggregationResult.getRootNode().getDataAfter().get().getValue());
73     }
74
75     @Test
76     public void testLeafUnmodifiedDelete() {
77         NormalizedNode<?, ?> normalizedNode1 = normalizedNode("value1");
78         NormalizedNode<?, ?> normalizedNode2 = normalizedNode("value1");
79
80         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, normalizedNode2,
81                 ModificationType.UNMODIFIED);
82         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
83
84         DataTreeCandidateNode node2 = dataTreeCandidateNode(normalizedNode2, null,
85                 ModificationType.DELETE);
86         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
87
88         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
89
90         assertEquals(ModificationType.DELETE, aggregationResult.getRootNode().getModificationType());
91         assertEquals("value1", aggregationResult.getRootNode().getDataBefore().get().getValue());
92         assertEquals(Optional.empty(), aggregationResult.getRootNode().getDataAfter());
93     }
94
95     @Test(expected = IllegalArgumentException.class)
96     public void testLeafUnmodifiedDeleteWithoutDataBefore() {
97         DataTreeCandidateNode node1 = dataTreeCandidateNode(null, null,
98                 ModificationType.UNMODIFIED);
99         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
100
101         DataTreeCandidateNode node2 = dataTreeCandidateNode(null, null,
102                 ModificationType.DELETE);
103         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
104
105         DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
106     }
107
108     @Test(expected = IllegalArgumentException.class)
109     public void testLeafUnmodifiedSubtreeModifiedWithoutDataBefore() {
110         DataTreeCandidateNode node1 = dataTreeCandidateNode(null, null,
111                 ModificationType.UNMODIFIED);
112         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
113
114         DataTreeCandidateNode node2 = dataTreeCandidateNode(null, null,
115                 ModificationType.SUBTREE_MODIFIED);
116         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
117
118         DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
119     }
120
121     @Test
122     public void testLeafWriteUnmodified() {
123         NormalizedNode<?, ?> normalizedNode1 = normalizedNode("value1");
124         NormalizedNode<?, ?> normalizedNode2 = normalizedNode("value2");
125
126         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, normalizedNode2,
127                 ModificationType.WRITE);
128         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
129
130         DataTreeCandidateNode node2 = dataTreeCandidateNode(normalizedNode2, normalizedNode2,
131                 ModificationType.UNMODIFIED);
132         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
133
134         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
135
136         assertEquals(ModificationType.WRITE, aggregationResult.getRootNode().getModificationType());
137         assertEquals("value1", aggregationResult.getRootNode().getDataBefore().get().getValue());
138         assertEquals("value2", aggregationResult.getRootNode().getDataAfter().get().getValue());
139     }
140
141     @Test
142     public void testLeafWriteWrite() {
143         NormalizedNode<?, ?> normalizedNode1 = normalizedNode("value1");
144         NormalizedNode<?, ?> normalizedNode2 = normalizedNode("value2");
145         NormalizedNode<?, ?> normalizedNode3 = normalizedNode("value3");
146
147         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, normalizedNode2,
148                 ModificationType.WRITE);
149         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
150
151         DataTreeCandidateNode node2 = dataTreeCandidateNode(normalizedNode2, normalizedNode3,
152                 ModificationType.WRITE);
153         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
154
155         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
156
157         assertEquals(ModificationType.WRITE, aggregationResult.getRootNode().getModificationType());
158         assertEquals("value1", aggregationResult.getRootNode().getDataBefore().get().getValue());
159         assertEquals("value3", aggregationResult.getRootNode().getDataAfter().get().getValue());
160     }
161
162     @Test
163     public void testLeafWriteDeleteWithoutChanges() {
164         NormalizedNode<?, ?> normalizedNode = normalizedNode("value1");
165
166         DataTreeCandidateNode node1 = dataTreeCandidateNode(null, normalizedNode,
167                 ModificationType.WRITE);
168         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
169
170         DataTreeCandidateNode node2 = dataTreeCandidateNode(normalizedNode, null,
171                 ModificationType.DELETE);
172         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
173
174         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
175
176         assertEquals(ModificationType.UNMODIFIED, aggregationResult.getRootNode().getModificationType());
177         assertEquals(Optional.empty(), aggregationResult.getRootNode().getDataBefore());
178         assertEquals(Optional.empty(), aggregationResult.getRootNode().getDataAfter());
179     }
180
181     @Test
182     public void testLeafWriteDelete() {
183         NormalizedNode<?, ?> normalizedNode1 = normalizedNode("value1");
184         NormalizedNode<?, ?> normalizedNode2 = normalizedNode("value2");
185
186         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, normalizedNode2,
187                 ModificationType.WRITE);
188         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
189
190         DataTreeCandidateNode node2 = dataTreeCandidateNode(normalizedNode2, null,
191                 ModificationType.DELETE);
192         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
193
194         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
195
196         assertEquals(ModificationType.DELETE, aggregationResult.getRootNode().getModificationType());
197         assertEquals("value1", aggregationResult.getRootNode().getDataBefore().get().getValue());
198         assertEquals(Optional.empty(), aggregationResult.getRootNode().getDataAfter());
199     }
200
201     @Test
202     public void testLeafDeleteUnmodified() {
203         NormalizedNode<?, ?> normalizedNode = normalizedNode("value");
204
205         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode, null,
206                 ModificationType.DELETE);
207         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
208
209         DataTreeCandidateNode node2 = dataTreeCandidateNode(null, null,
210                 ModificationType.UNMODIFIED);
211         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
212
213         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
214
215         assertEquals(ModificationType.DELETE, aggregationResult.getRootNode().getModificationType());
216         assertEquals("value", aggregationResult.getRootNode().getDataBefore().get().getValue());
217         assertEquals(Optional.empty(), aggregationResult.getRootNode().getDataAfter());
218     }
219
220     @Test
221     public void testLeafDeleteWrite() {
222         NormalizedNode<?, ?> normalizedNode1 = normalizedNode("value1");
223         NormalizedNode<?, ?> normalizedNode2 = normalizedNode("value2");
224
225         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, null,
226                 ModificationType.DELETE);
227         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
228
229         DataTreeCandidateNode node2 = dataTreeCandidateNode(null, normalizedNode2,
230                 ModificationType.WRITE);
231         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
232
233         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
234
235         assertEquals(ModificationType.WRITE, aggregationResult.getRootNode().getModificationType());
236         assertEquals("value1", aggregationResult.getRootNode().getDataBefore().get().getValue());
237         assertEquals("value2", aggregationResult.getRootNode().getDataAfter().get().getValue());
238     }
239
240     @Test(expected = IllegalArgumentException.class)
241     public void testLeafDeleteDelete() {
242         NormalizedNode<?, ?> normalizedNode1 = normalizedNode("value1");
243
244         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, null,
245                 ModificationType.DELETE);
246         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
247
248         DataTreeCandidateNode node2 = dataTreeCandidateNode(null, null,
249                 ModificationType.DELETE);
250         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
251
252         DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
253     }
254
255     @Test(expected = IllegalArgumentException.class)
256     public void testLeafDeleteDisappear() {
257         NormalizedNode<?, ?> normalizedNode1 = normalizedNode("value1");
258
259         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, null,
260                 ModificationType.DELETE);
261         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
262
263         DataTreeCandidateNode node2 = dataTreeCandidateNode(null, null,
264                 ModificationType.DISAPPEARED);
265         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
266
267         DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
268     }
269
270     @Test(expected = IllegalArgumentException.class)
271     public void testLeafDeleteSubtreeModified() {
272         NormalizedNode<?, ?> normalizedNode1 = normalizedNode("value1");
273
274         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, null,
275                 ModificationType.DELETE);
276         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
277
278         DataTreeCandidateNode node2 = dataTreeCandidateNode(null, null,
279                 ModificationType.SUBTREE_MODIFIED);
280         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
281
282         DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
283     }
284
285     @Test
286     public void testUnmodifiedUnmodified() throws NoSuchFieldException {
287         NormalizedNode<?, ?> parentNode = normalizedNode("container");
288         NormalizedNode<?, ?> childNode = normalizedNode("child");
289
290         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode, parentNode,
291                 ModificationType.UNMODIFIED);
292         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, childNode,
293                 ModificationType.UNMODIFIED);
294         setChildNodes(node1, Collections.singletonList(child1));
295         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
296
297         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, parentNode,
298                 ModificationType.UNMODIFIED);
299         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode, childNode,
300                 ModificationType.UNMODIFIED);
301         setChildNodes(node2, Collections.singletonList(child2));
302         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
303
304         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
305
306         assertEquals(ModificationType.UNMODIFIED, aggregationResult.getRootNode().getModificationType());
307     }
308
309     @Test
310     public void testUnmodifiedDelete() {
311         NormalizedNode<?, ?> parentNode = normalizedNode("container");
312         NormalizedNode<?, ?> childNode = normalizedNode("child");
313
314         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode, parentNode,
315                 ModificationType.UNMODIFIED);
316         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, childNode,
317                 ModificationType.UNMODIFIED);
318         setChildNodes(node1, Collections.singletonList(child1));
319         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
320
321         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, null,
322                 ModificationType.DELETE);
323         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode, null,
324                 ModificationType.DELETE);
325         setChildNodes(node2, Collections.singletonList(child2));
326         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
327
328         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
329
330         assertEquals(ModificationType.DELETE, aggregationResult.getRootNode().getModificationType());
331     }
332
333     @Test
334     public void testUnmodifiedWrite() {
335         NormalizedNode<?, ?> parentNode1 = normalizedNode("container1");
336         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
337         NormalizedNode<?, ?> parentNode2 = normalizedNode("container2");
338         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
339
340         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1,
341                 ModificationType.UNMODIFIED);
342         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode1,
343                 ModificationType.UNMODIFIED);
344         setChildNodes(node1, Collections.singletonList(child1));
345         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
346
347         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode2,
348                 ModificationType.WRITE);
349         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2,
350                 ModificationType.WRITE);
351         setChildNodes(node2, Collections.singletonList(child2));
352         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
353
354         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
355
356         assertEquals(ModificationType.WRITE, aggregationResult.getRootNode().getModificationType());
357     }
358
359     @Test(expected = IllegalArgumentException.class)
360     public void testUnmodifiedSubtreeModifiedWithoutDataBefore() {
361         NormalizedNode<?, ?> parentNode = normalizedNode("container");
362         NormalizedNode<?, ?> childNode = normalizedNode("child");
363
364         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, null,
365                 ModificationType.UNMODIFIED);
366         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, null,
367                 ModificationType.UNMODIFIED);
368         setChildNodes(node1, Collections.singletonList(child1));
369         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
370
371         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, parentNode,
372                 ModificationType.SUBTREE_MODIFIED);
373         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode,
374                 ModificationType.WRITE);
375         setChildNodes(node2, Collections.singletonList(child2));
376         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
377
378         DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
379     }
380
381     //FIXME
382     @Test
383     public void testUnmodifiedSubtreeModified() {
384         NormalizedNode<?, ?> parentNode1 = normalizedNode("container1");
385         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
386         NormalizedNode<?, ?> parentNode2 = normalizedNode("container1");
387         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
388
389         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1,
390                 ModificationType.UNMODIFIED);
391         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode1,
392                 ModificationType.UNMODIFIED);
393         setChildNodes(node1, Collections.singletonList(child1));
394         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
395
396         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode2,
397                 ModificationType.SUBTREE_MODIFIED);
398         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2,
399                 ModificationType.WRITE);
400         setChildNodes(node2, Collections.singletonList(child2));
401         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
402
403         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
404
405         assertEquals(ModificationType.SUBTREE_MODIFIED, aggregationResult.getRootNode().getModificationType());
406     }
407
408     @Test(expected = IllegalArgumentException.class)
409     public void testUnmodifiedAppearedWithDataBefore() {
410         NormalizedNode<?, ?> parentNode1 = normalizedNode("container1");
411         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
412         NormalizedNode<?, ?> parentNode2 = normalizedNode("container1");
413         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
414
415         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1,
416                 ModificationType.UNMODIFIED);
417         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode1,
418                 ModificationType.UNMODIFIED);
419         setChildNodes(node1, Collections.singletonList(child1));
420         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
421
422         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode2,
423                 ModificationType.APPEARED);
424         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2,
425                 ModificationType.WRITE);
426         setChildNodes(node2, Collections.singletonList(child2));
427         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
428
429         DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
430     }
431
432     //FIXME
433     @Test
434     public void testUnmodifiedAppeared() {
435         NormalizedNode<?, ?> parentNode = normalizedNode("container");
436         NormalizedNode<?, ?> childNode = normalizedNode("child");
437
438         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, null,
439                 ModificationType.UNMODIFIED);
440         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, null,
441                 ModificationType.UNMODIFIED);
442         setChildNodes(node1, Collections.singletonList(child1));
443         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
444
445         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, parentNode,
446                 ModificationType.APPEARED);
447         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode,
448                 ModificationType.WRITE);
449         setChildNodes(node2, Collections.singletonList(child2));
450         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
451
452         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
453
454         assertEquals(ModificationType.APPEARED, aggregationResult.getRootNode().getModificationType());
455     }
456
457     @Test(expected = IllegalArgumentException.class)
458     public void testUnmodifiedDisappearWithoutDataBefore() {
459         NormalizedNode<?, ?> parentNode = normalizedNode("container");
460         NormalizedNode<?, ?> childNode = normalizedNode("child");
461
462         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, null,
463                 ModificationType.UNMODIFIED);
464         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, null,
465                 ModificationType.UNMODIFIED);
466         setChildNodes(node1, Collections.singletonList(child1));
467         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
468
469         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, parentNode,
470                 ModificationType.DISAPPEARED);
471         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode,
472                 ModificationType.DELETE);
473         setChildNodes(node2, Collections.singletonList(child2));
474         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
475
476         DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
477     }
478
479     @Test
480     public void testUnmodifiedDisappear() {
481         NormalizedNode<?, ?> parentNode1 = normalizedNode("container1");
482         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
483
484         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1,
485                 ModificationType.UNMODIFIED);
486         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode1,
487                 ModificationType.UNMODIFIED);
488         setChildNodes(node1, Collections.singletonList(child1));
489         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
490
491         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, null,
492                 ModificationType.DISAPPEARED);
493         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, null,
494                 ModificationType.DELETE);
495         setChildNodes(node2, Collections.singletonList(child2));
496         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
497
498         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
499
500         assertEquals(ModificationType.DISAPPEARED, aggregationResult.getRootNode().getModificationType());
501     }
502
503     @Test
504     public void testDeleteUnmodified() {
505         NormalizedNode<?, ?> parentNode = normalizedNode("container");
506         NormalizedNode<?, ?> childNode = normalizedNode("child");
507
508         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode, null,
509                 ModificationType.DELETE);
510         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, null,
511                 ModificationType.DELETE);
512         setChildNodes(node1, Collections.singletonList(child1));
513         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
514
515         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, null,
516                 ModificationType.UNMODIFIED);
517         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, null,
518                 ModificationType.UNMODIFIED);
519         setChildNodes(node2, Collections.singletonList(child2));
520         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
521
522         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
523
524         assertEquals(ModificationType.DELETE, aggregationResult.getRootNode().getModificationType());
525     }
526
527     @Test
528     public void testDeleteWrite() {
529         NormalizedNode<?, ?> parentNode1 = normalizedNode("container1");
530         NormalizedNode<?, ?> parentNode2 = normalizedNode("container2");
531         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
532         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
533
534         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null,
535                 ModificationType.DELETE);
536         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null,
537                 ModificationType.DELETE);
538         setChildNodes(node1, Collections.singletonList(child1));
539         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
540
541         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, parentNode2,
542                 ModificationType.WRITE);
543         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode2,
544                 ModificationType.WRITE);
545         setChildNodes(node2, Collections.singletonList(child2));
546         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
547
548         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
549
550         assertEquals(ModificationType.WRITE, aggregationResult.getRootNode().getModificationType());
551     }
552
553     @Test
554     public void testDeleteAppear() {
555         NormalizedNode<?, ?> parentNode1 = normalizedNode("container1");
556         NormalizedNode<?, ?> parentNode2 = normalizedNode("container2");
557         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
558         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
559
560         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null,
561                 ModificationType.DELETE);
562         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null,
563                 ModificationType.DELETE);
564         setChildNodes(node1, Collections.singletonList(child1));
565         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
566
567         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, parentNode2,
568                 ModificationType.APPEARED);
569         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode2,
570                 ModificationType.WRITE);
571         setChildNodes(node2, Collections.singletonList(child2));
572         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
573
574         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
575
576         assertEquals(ModificationType.WRITE, aggregationResult.getRootNode().getModificationType());
577     }
578
579     @Test
580     public void testWriteUnmodified() {
581         NormalizedNode<?, ?> parentNode = normalizedNode("container");
582         NormalizedNode<?, ?> childNode = normalizedNode("child");
583
584         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode,
585                 ModificationType.WRITE);
586         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode,
587                 ModificationType.WRITE);
588         setChildNodes(node1, Collections.singletonList(child1));
589         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
590
591         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, parentNode,
592                 ModificationType.UNMODIFIED);
593         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode, childNode,
594                 ModificationType.UNMODIFIED);
595         setChildNodes(node2, Collections.singletonList(child2));
596         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
597
598         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
599
600         assertEquals(ModificationType.WRITE, aggregationResult.getRootNode().getModificationType());
601     }
602
603     @Test
604     public void testWriteDeleteWithoutChanges() {
605         NormalizedNode<?, ?> parentNode = normalizedNode("container");
606         NormalizedNode<?, ?> childNode = normalizedNode("child");
607
608         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode,
609                 ModificationType.WRITE);
610         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode,
611                 ModificationType.WRITE);
612         setChildNodes(node1, Collections.singletonList(child1));
613         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
614
615         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, null,
616                 ModificationType.DELETE);
617         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode, null,
618                 ModificationType.DELETE);
619         setChildNodes(node2, Collections.singletonList(child2));
620         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
621
622         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
623
624         assertEquals(ModificationType.UNMODIFIED, aggregationResult.getRootNode().getModificationType());
625     }
626
627     @Test
628     public void testWriteDelete() {
629         NormalizedNode<?, ?> parentNode1 = normalizedNode("container1");
630         NormalizedNode<?, ?> parentNode2 = normalizedNode("container2");
631         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
632         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
633
634         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode2,
635                 ModificationType.WRITE);
636         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode2,
637                 ModificationType.WRITE);
638         setChildNodes(node1, Collections.singletonList(child1));
639         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
640
641         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode2, null,
642                 ModificationType.DELETE);
643         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode2, null,
644                 ModificationType.DELETE);
645         setChildNodes(node2, Collections.singletonList(child2));
646         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
647
648         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
649
650         assertEquals(ModificationType.DELETE, aggregationResult.getRootNode().getModificationType());
651     }
652
653     @Test
654     public void testWriteWrite() {
655         NormalizedNode<?, ?> parentNode1 = normalizedNode("container1");
656         NormalizedNode<?, ?> parentNode2 = normalizedNode("container2");
657         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
658         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
659
660         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode1,
661                 ModificationType.WRITE);
662         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode1,
663                 ModificationType.WRITE);
664         setChildNodes(node1, Collections.singletonList(child1));
665         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
666
667         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode2,
668                 ModificationType.WRITE);
669         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2,
670                 ModificationType.WRITE);
671         setChildNodes(node2, Collections.singletonList(child2));
672         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
673
674         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
675
676         assertEquals(ModificationType.WRITE, aggregationResult.getRootNode().getModificationType());
677     }
678
679     @Test
680     public void testWriteSubtreeModified() {
681         NormalizedNode<?, ?> parentNode = normalizedNode("container");
682         NormalizedNode<?, ?> parentNode1 = normalizedNode("container1");
683         NormalizedNode<?, ?> parentNode2 = normalizedNode("container1");
684         NormalizedNode<?, ?> childNode = normalizedNode("child");
685         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
686         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
687
688         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode, parentNode1,
689                 ModificationType.WRITE);
690         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, childNode1,
691                 ModificationType.WRITE);
692         setChildNodes(node1, Collections.singletonList(child1));
693         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
694
695         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode2,
696                 ModificationType.SUBTREE_MODIFIED);
697         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2,
698                 ModificationType.WRITE);
699         setChildNodes(node2, Collections.singletonList(child2));
700         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
701
702         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
703
704         assertEquals(ModificationType.WRITE, aggregationResult.getRootNode().getModificationType());
705     }
706
707     @Test(expected = IllegalArgumentException.class)
708     public void testWriteAppear() {
709         NormalizedNode<?, ?> parentNode1 = normalizedNode("container1");
710         NormalizedNode<?, ?> parentNode2 = normalizedNode("container2");
711         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
712         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
713         NormalizedNode<?, ?> childNode3 = normalizedNode("child3");
714
715         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode2,
716                 ModificationType.WRITE);
717         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode2,
718                 ModificationType.WRITE);
719         setChildNodes(node1, Collections.singletonList(child1));
720         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
721
722         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode2, parentNode2,
723                 ModificationType.APPEARED);
724         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode2, childNode3,
725                 ModificationType.WRITE);
726         setChildNodes(node2, Collections.singletonList(child2));
727         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
728
729         DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
730     }
731
732     @Test
733     public void testWriteDisappearWithoutChanges() {
734         NormalizedNode<?, ?> parentNode = normalizedNode("container");
735         NormalizedNode<?, ?> childNode = normalizedNode("child");
736
737         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode,
738                 ModificationType.WRITE);
739         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode,
740                 ModificationType.WRITE);
741         setChildNodes(node1, Collections.singletonList(child1));
742         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
743
744         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, null,
745                 ModificationType.DISAPPEARED);
746         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode, null,
747                 ModificationType.DELETE);
748         setChildNodes(node2, Collections.singletonList(child2));
749         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
750
751         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
752
753         assertEquals(ModificationType.UNMODIFIED, aggregationResult.getRootNode().getModificationType());
754     }
755
756     @Test
757     public void testWriteDisappear() {
758         NormalizedNode<?, ?> parentNode1 = normalizedNode("container1");
759         NormalizedNode<?, ?> parentNode2 = normalizedNode("container2");
760         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
761         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
762
763         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode2,
764                 ModificationType.WRITE);
765         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode2,
766                 ModificationType.WRITE);
767         setChildNodes(node1, Collections.singletonList(child1));
768         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
769
770         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode2, null,
771                 ModificationType.DISAPPEARED);
772         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode2, null,
773                 ModificationType.DELETE);
774         setChildNodes(node2, Collections.singletonList(child2));
775         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
776
777         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
778
779         assertEquals(ModificationType.DISAPPEARED, aggregationResult.getRootNode().getModificationType());
780     }
781
782     @Test
783     public void testSubtreeModifiedUnmodified() {
784         NormalizedNode<?, ?> parentNode1 = normalizedNode("container1");
785         NormalizedNode<?, ?> parentNode2 = normalizedNode("container1");
786         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
787         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
788
789         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode2,
790                 ModificationType.SUBTREE_MODIFIED);
791         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode2,
792                 ModificationType.WRITE);
793         setChildNodes(node1, Collections.singletonList(child1));
794         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
795
796         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode2, parentNode2,
797                 ModificationType.UNMODIFIED);
798         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode2, childNode2,
799                 ModificationType.UNMODIFIED);
800         setChildNodes(node2, Collections.singletonList(child2));
801         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
802
803         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
804
805         assertEquals(ModificationType.SUBTREE_MODIFIED, aggregationResult.getRootNode().getModificationType());
806     }
807
808     @Test
809     public void testSubtreeModifiedDelete() {
810         NormalizedNode<?, ?> parentNode1 = normalizedNode("container1");
811         NormalizedNode<?, ?> parentNode2 = normalizedNode("container1");
812         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
813         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
814
815         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode2,
816                 ModificationType.SUBTREE_MODIFIED);
817         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode2,
818                 ModificationType.WRITE);
819         setChildNodes(node1, Collections.singletonList(child1));
820         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
821
822         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode2, null,
823                 ModificationType.DELETE);
824         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode2, null,
825                 ModificationType.DELETE);
826         setChildNodes(node2, Collections.singletonList(child2));
827         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
828
829         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
830
831         assertEquals(ModificationType.DELETE, aggregationResult.getRootNode().getModificationType());
832     }
833
834     @Test
835     public void testSubtreeModifiedWrite() {
836         NormalizedNode<?, ?> parentNode1 = normalizedNode("container");
837         NormalizedNode<?, ?> parentNode2 = normalizedNode("value2");
838         NormalizedNode<?, ?> childNode = normalizedNode("childNode");
839         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
840         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
841
842         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1,
843                 ModificationType.SUBTREE_MODIFIED);
844         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, childNode1,
845                 ModificationType.WRITE);
846         setChildNodes(node1, Collections.singletonList(child1));
847         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
848
849         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode2,
850                 ModificationType.WRITE);
851         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2,
852                 ModificationType.WRITE);
853         setChildNodes(node2, Collections.singletonList(child2));
854         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
855
856         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
857
858         assertEquals(ModificationType.WRITE, aggregationResult.getRootNode().getModificationType());
859     }
860
861     @Test
862     public void testSubtreeModifiedSubtreeModified() {
863         NormalizedNode<?, ?> parentNode1 = normalizedNode("container");
864         NormalizedNode<?, ?> childNode = normalizedNode("childNode");
865         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
866         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
867
868         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1,
869                 ModificationType.SUBTREE_MODIFIED);
870         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, childNode1,
871                 ModificationType.WRITE);
872         setChildNodes(node1, Collections.singletonList(child1));
873         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
874
875         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode1,
876                 ModificationType.SUBTREE_MODIFIED);
877         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2,
878                 ModificationType.WRITE);
879         setChildNodes(node2, Collections.singletonList(child2));
880         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
881
882         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
883
884         assertEquals(ModificationType.SUBTREE_MODIFIED, aggregationResult.getRootNode().getModificationType());
885     }
886
887     @Test(expected = IllegalArgumentException.class)
888     public void testSubtreeModifiedAppear() {
889         NormalizedNode<?, ?> parentNode1 = normalizedNode("container");
890         NormalizedNode<?, ?> parentNode2 = normalizedNode("value2");
891         NormalizedNode<?, ?> childNode = normalizedNode("childNode");
892         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
893         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
894
895         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1,
896                 ModificationType.SUBTREE_MODIFIED);
897         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, childNode1,
898                 ModificationType.WRITE);
899         setChildNodes(node1, Collections.singletonList(child1));
900         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
901
902         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, parentNode2,
903                 ModificationType.APPEARED);
904         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode2,
905                 ModificationType.WRITE);
906         setChildNodes(node2, Collections.singletonList(child2));
907         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
908
909         DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
910     }
911
912     @Test
913     public void testSubtreeModifiedDisappear() {
914         NormalizedNode<?, ?> parentNode1 = normalizedNode("container");
915         NormalizedNode<?, ?> childNode = normalizedNode("childNode");
916         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
917
918         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1,
919                 ModificationType.SUBTREE_MODIFIED);
920         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, childNode1,
921                 ModificationType.WRITE);
922         setChildNodes(node1, Collections.singletonList(child1));
923         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
924
925         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, null,
926                 ModificationType.DISAPPEARED);
927         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, null,
928                 ModificationType.DELETE);
929         setChildNodes(node2, Collections.singletonList(child2));
930         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
931
932         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
933
934         assertEquals(ModificationType.DISAPPEARED, aggregationResult.getRootNode().getModificationType());
935     }
936
937     @Test
938     public void testAppearedUnmodified() {
939         NormalizedNode<?, ?> parentNode1 = normalizedNode("container");
940         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
941
942         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode1,
943                 ModificationType.APPEARED);
944         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode1,
945                 ModificationType.WRITE);
946         setChildNodes(node1, Collections.singletonList(child1));
947         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
948
949         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode1,
950                 ModificationType.UNMODIFIED);
951         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode1,
952                 ModificationType.UNMODIFIED);
953         setChildNodes(node2, Collections.singletonList(child2));
954         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
955
956         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
957
958         assertEquals(ModificationType.APPEARED, aggregationResult.getRootNode().getModificationType());
959     }
960
961     @Test
962     public void testAppearedDelete() {
963         NormalizedNode<?, ?> parentNode1 = normalizedNode("container");
964         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
965
966         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode1,
967                 ModificationType.APPEARED);
968         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode1,
969                 ModificationType.WRITE);
970         setChildNodes(node1, Collections.singletonList(child1));
971         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
972
973         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, null,
974                 ModificationType.DELETE);
975         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, null,
976                 ModificationType.DELETE);
977         setChildNodes(node2, Collections.singletonList(child2));
978         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
979
980         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
981
982         assertEquals(ModificationType.UNMODIFIED, aggregationResult.getRootNode().getModificationType());
983     }
984
985     @Test
986     public void testAppearedWriteWithoutChanges() {
987         NormalizedNode<?, ?> parentNode1 = normalizedNode("container");
988         NormalizedNode<?, ?> parentNode2 = normalizedNode("value2");
989         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
990         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
991
992         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode1,
993                 ModificationType.APPEARED);
994         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode1,
995                 ModificationType.WRITE);
996         setChildNodes(node1, Collections.singletonList(child1));
997         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
998
999         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode2,
1000                 ModificationType.WRITE);
1001         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2,
1002                 ModificationType.WRITE);
1003         setChildNodes(node2, Collections.singletonList(child2));
1004         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
1005
1006         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
1007
1008         assertEquals(ModificationType.WRITE, aggregationResult.getRootNode().getModificationType());
1009     }
1010
1011     @Test
1012     public void testAppearedSubtreeModified() {
1013         NormalizedNode<?, ?> parentNode1 = normalizedNode("container");
1014         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
1015         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
1016
1017         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode1,
1018                 ModificationType.APPEARED);
1019         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode1,
1020                 ModificationType.WRITE);
1021         setChildNodes(node1, Collections.singletonList(child1));
1022         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
1023
1024         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode1,
1025                 ModificationType.SUBTREE_MODIFIED);
1026         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2,
1027                 ModificationType.WRITE);
1028         setChildNodes(node2, Collections.singletonList(child2));
1029         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
1030
1031         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
1032
1033         assertEquals(ModificationType.APPEARED, aggregationResult.getRootNode().getModificationType());
1034     }
1035
1036     @Test(expected = IllegalArgumentException.class)
1037     public void testAppearedAppeared() {
1038         NormalizedNode<?, ?> parentNode1 = normalizedNode("container");
1039         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
1040
1041         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode1,
1042                 ModificationType.APPEARED);
1043         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode1,
1044                 ModificationType.WRITE);
1045         setChildNodes(node1, Collections.singletonList(child1));
1046         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
1047
1048         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, parentNode1,
1049                 ModificationType.APPEARED);
1050         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode1,
1051                 ModificationType.WRITE);
1052         setChildNodes(node2, Collections.singletonList(child2));
1053         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
1054
1055         DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
1056     }
1057
1058     @Test
1059     public void testAppearedDisappeared() {
1060         NormalizedNode<?, ?> parentNode1 = normalizedNode("container");
1061         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
1062
1063         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode1,
1064                 ModificationType.APPEARED);
1065         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode1,
1066                 ModificationType.WRITE);
1067         setChildNodes(node1, Collections.singletonList(child1));
1068         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
1069
1070         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, null,
1071                 ModificationType.DISAPPEARED);
1072         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, null,
1073                 ModificationType.DELETE);
1074         setChildNodes(node2, Collections.singletonList(child2));
1075         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
1076
1077         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
1078
1079         assertEquals(ModificationType.UNMODIFIED, aggregationResult.getRootNode().getModificationType());
1080     }
1081
1082     @Test
1083     public void testDisappearedUnmodified() {
1084         NormalizedNode<?, ?> parentNode1 = normalizedNode("container");
1085         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
1086
1087         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null,
1088                 ModificationType.DISAPPEARED);
1089         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null,
1090                 ModificationType.DELETE);
1091         setChildNodes(node1, Collections.singletonList(child1));
1092         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
1093
1094         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, null,
1095                 ModificationType.UNMODIFIED);
1096         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, null,
1097                 ModificationType.UNMODIFIED);
1098         setChildNodes(node2, Collections.singletonList(child2));
1099         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
1100
1101         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
1102
1103         assertEquals(ModificationType.DISAPPEARED, aggregationResult.getRootNode().getModificationType());
1104     }
1105
1106     @Test(expected = IllegalArgumentException.class)
1107     public void testDisappearedDelete() {
1108         NormalizedNode<?, ?> parentNode1 = normalizedNode("container");
1109         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
1110
1111         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null,
1112                 ModificationType.DISAPPEARED);
1113         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null,
1114                 ModificationType.DELETE);
1115         setChildNodes(node1, Collections.singletonList(child1));
1116         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
1117
1118         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, null,
1119                 ModificationType.DELETE);
1120         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, null,
1121                 ModificationType.DELETE);
1122         setChildNodes(node2, Collections.singletonList(child2));
1123         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
1124
1125         DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
1126     }
1127
1128     @Test
1129     public void testDisappearedWrite() {
1130         NormalizedNode<?, ?> parentNode1 = normalizedNode("container1");
1131         NormalizedNode<?, ?> parentNode2 = normalizedNode("container2");
1132         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
1133         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
1134
1135         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null,
1136                 ModificationType.DISAPPEARED);
1137         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null,
1138                 ModificationType.DELETE);
1139         setChildNodes(node1, Collections.singletonList(child1));
1140         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
1141
1142         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, parentNode2,
1143                 ModificationType.WRITE);
1144         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode2,
1145                 ModificationType.WRITE);
1146         setChildNodes(node2, Collections.singletonList(child2));
1147         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
1148
1149         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
1150
1151         assertEquals(ModificationType.WRITE, aggregationResult.getRootNode().getModificationType());
1152     }
1153
1154     @Test(expected = IllegalArgumentException.class)
1155     public void testDisappearedSubtreeModified() {
1156         NormalizedNode<?, ?> parentNode1 = normalizedNode("container");
1157         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
1158         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
1159
1160         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null,
1161                 ModificationType.DISAPPEARED);
1162         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null,
1163                 ModificationType.DELETE);
1164         setChildNodes(node1, Collections.singletonList(child1));
1165         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
1166
1167         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, null,
1168                 ModificationType.SUBTREE_MODIFIED);
1169         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode2,
1170                 ModificationType.WRITE);
1171         setChildNodes(node2, Collections.singletonList(child2));
1172         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
1173
1174         DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
1175     }
1176
1177     @Test
1178     public void testDisappearedAppeared() {
1179         NormalizedNode<?, ?> parentNode1 = normalizedNode("container");
1180         NormalizedNode<?, ?> parentNode2 = normalizedNode("container");
1181         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
1182         NormalizedNode<?, ?> childNode2 = normalizedNode("child2");
1183
1184         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null,
1185                 ModificationType.DISAPPEARED);
1186         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null,
1187                 ModificationType.DELETE);
1188         setChildNodes(node1, Collections.singletonList(child1));
1189         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
1190
1191         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, parentNode2,
1192                 ModificationType.APPEARED);
1193         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode2,
1194                 ModificationType.WRITE);
1195         setChildNodes(node2, Collections.singletonList(child2));
1196         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
1197
1198         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
1199
1200         assertEquals(ModificationType.SUBTREE_MODIFIED, aggregationResult.getRootNode().getModificationType());
1201     }
1202
1203     @Test(expected = IllegalArgumentException.class)
1204     public void testDisappearedDisappear() {
1205         NormalizedNode<?, ?> parentNode1 = normalizedNode("container");
1206         NormalizedNode<?, ?> childNode1 = normalizedNode("child1");
1207
1208         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null,
1209                 ModificationType.DISAPPEARED);
1210         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null,
1211                 ModificationType.DELETE);
1212         setChildNodes(node1, Collections.singletonList(child1));
1213         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
1214
1215         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, null,
1216                 ModificationType.DISAPPEARED);
1217         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, null,
1218                 ModificationType.DELETE);
1219         setChildNodes(node2, Collections.singletonList(child2));
1220         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
1221
1222         DataTreeCandidates.aggregate(Arrays.asList(candidate1, candidate2));
1223     }
1224
1225     private static NormalizedNode<?, ?> normalizedNode(final String value) {
1226         NormalizedNode<?, ?> node = mock(NormalizedNode.class);
1227         doReturn(value).when(node).getValue();
1228         return node;
1229     }
1230
1231     private static TerminalDataTreeCandidateNode dataTreeCandidateNode(final NormalizedNode<?, ?> before,
1232                                                                        final NormalizedNode<?, ?> after,
1233                                                                        final ModificationType modification) {
1234         TerminalDataTreeCandidateNode dataTreeCandidateNode = mock(TerminalDataTreeCandidateNode.class);
1235         doReturn(null).when(dataTreeCandidateNode).getIdentifier();
1236         doReturn(Optional.ofNullable(before)).when(dataTreeCandidateNode).getDataBefore();
1237         doReturn(Optional.ofNullable(after)).when(dataTreeCandidateNode).getDataAfter();
1238         doReturn(modification).when(dataTreeCandidateNode).getModificationType();
1239         return dataTreeCandidateNode;
1240     }
1241
1242     private static void setChildNodes(final TerminalDataTreeCandidateNode parentNode,
1243                                       final List<DataTreeCandidateNode> childNodes) {
1244         when(parentNode.getIdentifier()).thenReturn(null);
1245         childNodes.forEach(child -> {
1246             when(child.getIdentifier()).thenReturn(CHILD_ID);
1247         });
1248         when(parentNode.getChildNodes()).thenReturn(childNodes);
1249     }
1250
1251 }