Map system-ordered leaf-lists to Set<T>
[mdsal.git] / binding / mdsal-binding-dom-codec / src / test / java / org / opendaylight / mdsal / binding / dom / codec / impl / NormalizedNodeSerializeDeserializeTest.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. 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.mdsal.binding.dom.codec.impl;
9
10 import static java.util.Collections.singleton;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotEquals;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.fail;
15 import static org.opendaylight.mdsal.binding.test.model.util.ListsBindingUtils.top;
16 import static org.opendaylight.mdsal.binding.test.model.util.ListsBindingUtils.topLevelList;
17 import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.augmentationBuilder;
18 import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.choiceBuilder;
19 import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.containerBuilder;
20 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.leafNode;
21 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntry;
22 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
23 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
24
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Map.Entry;
28 import java.util.Set;
29 import org.junit.Test;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TopChoiceAugment1Builder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TopChoiceAugment2Builder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeComplexUsesAugment;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeLeafOnlyAugment;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeLeafOnlyAugmentBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.top.choice.augment1.AugmentChoice1;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.top.choice.augment1.augment.choice1.Case1Builder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.top.choice.augment2.augment.choice2.Case11Builder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.top.choice.augment2.augment.choice2.case11.Case11ChoiceCaseContainerBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.ChoiceContainer;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.ChoiceContainerBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top1;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top1Builder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top2;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top2Builder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.TopBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.choice.identifier.ExtendedBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.choice.identifier.extended.ExtendedIdBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelList;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.top.level.list.NestedListBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.top.level.list.NestedListKey;
54 import org.opendaylight.yang.gen.v1.urn.test.foo4798.rev160101.Root;
55 import org.opendaylight.yangtools.yang.binding.Augmentation;
56 import org.opendaylight.yangtools.yang.binding.DataObject;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
58 import org.opendaylight.yangtools.yang.common.QName;
59 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
60 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
61 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
62 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
63 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
64 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
65 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
66 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
67 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
68 import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
69 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
70 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeBuilder;
71 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder;
72 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
73 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder;
74 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
75 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
76 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
77 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUserLeafSetNodeBuilder;
78 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUserMapNodeBuilder;
79
80 public class NormalizedNodeSerializeDeserializeTest extends AbstractBindingCodecTest {
81
82     public static final String TOP_LEVEL_LIST_FOO_KEY_VALUE = "foo";
83     public static final TopLevelListKey TOP_LEVEL_LIST_FOO_KEY = new TopLevelListKey(TOP_LEVEL_LIST_FOO_KEY_VALUE);
84
85     public static final QName TOP_QNAME = Top.QNAME;
86     public static final QName TOP_LEVEL_LIST_QNAME = QName.create(TOP_QNAME, "top-level-list");
87     public static final QName TOP_LEVEL_LIST_KEY_QNAME = QName.create(TOP_QNAME, "name");
88     public static final QName TOP_LEVEL_LEAF_LIST_QNAME = QName.create(TOP_QNAME, "top-level-leaf-list");
89     public static final QName TOP_LEVEL_ORDERED_LEAF_LIST_QNAME = QName.create(TOP_QNAME,
90         "top-level-ordered-leaf-list");
91     public static final QName NESTED_LIST_QNAME = QName.create(TOP_QNAME, "nested-list");
92     public static final QName NESTED_LIST_KEY_QNAME = QName.create(TOP_QNAME, "name");
93     public static final QName CHOICE_CONTAINER_QNAME = ChoiceContainer.QNAME;
94     public static final QName CHOICE_IDENTIFIER_QNAME = QName.create(CHOICE_CONTAINER_QNAME, "identifier");
95     public static final QName CHOICE_IDENTIFIER_ID_QNAME = QName.create(CHOICE_CONTAINER_QNAME, "id");
96     public static final QName SIMPLE_ID_QNAME = QName.create(CHOICE_CONTAINER_QNAME, "simple-id");
97     public static final QName EXTENDED_ID_QNAME = QName.create(CHOICE_CONTAINER_QNAME, "extended-id");
98     private static final QName SIMPLE_VALUE_QNAME = QName.create(TreeComplexUsesAugment.QNAME, "simple-value");
99
100     private static final InstanceIdentifier<TopLevelList> BA_TOP_LEVEL_LIST = InstanceIdentifier
101             .builder(Top.class).child(TopLevelList.class, TOP_LEVEL_LIST_FOO_KEY).build();
102     private static final InstanceIdentifier<TreeLeafOnlyAugment> BA_TREE_LEAF_ONLY =
103             BA_TOP_LEVEL_LIST.augmentation(TreeLeafOnlyAugment.class);
104     private static final InstanceIdentifier<TreeComplexUsesAugment> BA_TREE_COMPLEX_USES =
105             BA_TOP_LEVEL_LIST.augmentation(TreeComplexUsesAugment.class);
106
107     public static final YangInstanceIdentifier BI_TOP_PATH = YangInstanceIdentifier.of(TOP_QNAME);
108     public static final YangInstanceIdentifier BI_TOP_LEVEL_LIST_PATH = BI_TOP_PATH.node(TOP_LEVEL_LIST_QNAME);
109     public static final YangInstanceIdentifier BI_TOP_LEVEL_LIST_FOO_PATH = BI_TOP_LEVEL_LIST_PATH
110             .node(NodeIdentifierWithPredicates.of(TOP_LEVEL_LIST_QNAME,
111                 TOP_LEVEL_LIST_KEY_QNAME, TOP_LEVEL_LIST_FOO_KEY_VALUE));
112     public static final YangInstanceIdentifier BI_CHOICE_CONTAINER_PATH = YangInstanceIdentifier.of(
113         CHOICE_CONTAINER_QNAME);
114
115     @Test
116     public void containerToNormalized() {
117         final Entry<YangInstanceIdentifier, NormalizedNode> entry = codecContext.toNormalizedNode(
118             InstanceIdentifier.create(Top.class), top());
119         final ContainerNode topNormalized = getEmptyTop();
120         assertEquals(topNormalized, entry.getValue());
121     }
122
123     @Test
124     public void containerFromNormalized() {
125         final ContainerNode topNormalized = getEmptyTop();
126         final Entry<InstanceIdentifier<?>, DataObject> entry = codecContext.fromNormalizedNode(BI_TOP_PATH,
127             topNormalized);
128         assertEquals(top(), entry.getValue());
129     }
130
131     private static ContainerNode getEmptyTop() {
132         return ImmutableContainerNodeBuilder.create()
133                     .withNodeIdentifier(new NodeIdentifier(TOP_QNAME))
134                     .build();
135     }
136
137     private static final QName AGUMENT_STRING_Q = QName.create(TOP_QNAME, "augmented-string");
138     private static final String AUGMENT_STRING_VALUE = "testingEquals";
139     private static final QName AUGMENT_INT_Q = QName.create(TOP_QNAME, "augmented-int");
140     private static final int AUGMENT_INT_VALUE = 44;
141
142     @Test
143     public void equalsWithAugment() {
144         final ContainerNode topNormalizedWithAugments = getNormalizedTopWithAugments(
145             augmentationBuilder()
146                 .withNodeIdentifier(new AugmentationIdentifier(singleton(AGUMENT_STRING_Q)))
147                 .withChild(ImmutableNodes.leafNode(AGUMENT_STRING_Q, AUGMENT_STRING_VALUE))
148                 .build());
149         final ContainerNode topNormalized = getEmptyTop();
150
151         final Entry<InstanceIdentifier<?>, DataObject> entry = codecContext.fromNormalizedNode(BI_TOP_PATH,
152             topNormalized);
153         final Entry<InstanceIdentifier<?>, DataObject> entryWithAugments = codecContext.fromNormalizedNode(BI_TOP_PATH,
154             topNormalizedWithAugments);
155
156         // Equals on other with no augmentation should be false
157         assertNotEquals(top(), entryWithAugments.getValue());
158         // Equals on other(reversed) with no augmentation should be false
159         assertNotEquals(entryWithAugments.getValue(), top());
160         // Equals on other(lazy) with no augmentation should be false
161         assertNotEquals(entry.getValue(), entryWithAugments.getValue());
162         // Equals on other(lazy, reversed) with no augmentation should be false
163         assertNotEquals(entryWithAugments.getValue(), entry.getValue());
164
165         final Top topWithAugments = topWithAugments(
166             Map.of(Top1.class, new Top1Builder().setAugmentedString(AUGMENT_STRING_VALUE).build()));
167         // Equals other with same augment should be true
168         assertEquals(topWithAugments, entryWithAugments.getValue());
169         // Equals other with same augment should be true
170         assertEquals(entryWithAugments.getValue(), topWithAugments);
171         // Equals on self should be true
172         assertEquals(entryWithAugments.getValue(), entryWithAugments.getValue());
173
174         final Top topWithAugmentsDiffValue = topWithAugments(
175             Map.of(Top1.class, new Top1Builder().setAugmentedString("differentValue").build()));
176         assertNotEquals(topWithAugmentsDiffValue, entryWithAugments.getValue());
177         assertNotEquals(entryWithAugments.getValue(), topWithAugmentsDiffValue);
178     }
179
180     @Test
181     public void equalsWithMultipleAugments() {
182         final ContainerNode topNormalizedWithAugments = getNormalizedTopWithAugments(
183             augmentationBuilder()
184                 .withNodeIdentifier(new AugmentationIdentifier(singleton(AGUMENT_STRING_Q)))
185                 .withChild(ImmutableNodes.leafNode(AGUMENT_STRING_Q, AUGMENT_STRING_VALUE))
186                 .build(),
187             augmentationBuilder()
188                 .withNodeIdentifier(new AugmentationIdentifier(singleton(AUGMENT_INT_Q)))
189                 .withChild(ImmutableNodes.leafNode(AUGMENT_INT_Q, AUGMENT_INT_VALUE))
190                 .build());
191
192         final Entry<InstanceIdentifier<?>, DataObject> entryWithAugments = codecContext.fromNormalizedNode(BI_TOP_PATH,
193             topNormalizedWithAugments);
194         Top topWithAugments = topWithAugments(Map.of(
195             Top1.class, new Top1Builder().setAugmentedString(AUGMENT_STRING_VALUE).build(),
196             Top2.class, new Top2Builder().setAugmentedInt(AUGMENT_INT_VALUE).build()));
197
198         assertEquals(topWithAugments, entryWithAugments.getValue());
199         assertEquals(entryWithAugments.getValue(), topWithAugments);
200
201         topWithAugments = topWithAugments(Map.of(
202             Top1.class, new Top1Builder().setAugmentedString(AUGMENT_STRING_VALUE).build(),
203             Top2.class, new Top2Builder().setAugmentedInt(999).build()));
204
205         assertNotEquals(topWithAugments, entryWithAugments.getValue());
206         assertNotEquals(entryWithAugments.getValue(), topWithAugments);
207     }
208
209     private static ContainerNode getNormalizedTopWithAugments(final AugmentationNode... augChild) {
210         final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> builder = ImmutableContainerNodeBuilder.create();
211
212         for (AugmentationNode augmentationNode : augChild) {
213             builder.withChild(augmentationNode);
214         }
215         return builder.withNodeIdentifier(new NodeIdentifier(TOP_QNAME))
216                     .withChild(mapNodeBuilder(TOP_LEVEL_LIST_QNAME).build()).build();
217     }
218
219     private static Top topWithAugments(
220             final Map<Class<? extends Augmentation<Top>>, ? extends Augmentation<Top>> augments) {
221         final TopBuilder topBuilder = new TopBuilder();
222         for (Augmentation<Top> augment : augments.values()) {
223             topBuilder.addAugmentation(augment);
224         }
225         return topBuilder.build();
226     }
227
228     @Test
229     public void listWithKeysToNormalized() {
230         final Entry<YangInstanceIdentifier, NormalizedNode> entry = codecContext.toNormalizedNode(
231             BA_TOP_LEVEL_LIST, topLevelList(TOP_LEVEL_LIST_FOO_KEY));
232         final MapEntryNode topLevelListNormalized = ImmutableMapEntryNodeBuilder.create()
233                 .withNodeIdentifier(NodeIdentifierWithPredicates.of(TOP_LEVEL_LIST_QNAME, TOP_LEVEL_LIST_KEY_QNAME,
234                     TOP_LEVEL_LIST_FOO_KEY_VALUE))
235                 .withChild(leafNode(TOP_LEVEL_LIST_KEY_QNAME, TOP_LEVEL_LIST_FOO_KEY_VALUE))
236                 .build();
237         assertEquals(topLevelListNormalized, entry.getValue());
238     }
239
240     @Test
241     public void listWithKeysFromNormalized() {
242         final MapEntryNode topLevelListNormalized = ImmutableMapEntryNodeBuilder.create()
243                 .withNodeIdentifier(NodeIdentifierWithPredicates.of(TOP_LEVEL_LIST_QNAME, TOP_LEVEL_LIST_KEY_QNAME,
244                     TOP_LEVEL_LIST_FOO_KEY_VALUE))
245                 .withChild(leafNode(TOP_LEVEL_LIST_KEY_QNAME, TOP_LEVEL_LIST_FOO_KEY_VALUE))
246                 .build();
247         final Entry<InstanceIdentifier<?>, DataObject> entry = codecContext.fromNormalizedNode(
248             BI_TOP_LEVEL_LIST_FOO_PATH, topLevelListNormalized);
249         assertEquals(topLevelList(TOP_LEVEL_LIST_FOO_KEY), entry.getValue());
250     }
251
252     @Test
253     public void leafOnlyAugmentationToNormalized() {
254         final Entry<YangInstanceIdentifier, NormalizedNode> entry = codecContext.toNormalizedNode(
255             BA_TREE_LEAF_ONLY, new TreeLeafOnlyAugmentBuilder().setSimpleValue("simpleValue").build());
256         final AugmentationNode augmentationNode = ImmutableAugmentationNodeBuilder.create()
257                 .withNodeIdentifier(new AugmentationIdentifier(Set.of(SIMPLE_VALUE_QNAME)))
258                 .withChild(leafNode(SIMPLE_VALUE_QNAME, "simpleValue"))
259                 .build();
260         assertEquals(augmentationNode, entry.getValue());
261     }
262
263     @Test
264     public void leafOnlyAugmentationFromNormalized() {
265         final AugmentationIdentifier augmentationId = new AugmentationIdentifier(Set.of(SIMPLE_VALUE_QNAME));
266         final AugmentationNode augmentationNode = ImmutableAugmentationNodeBuilder.create()
267                 .withNodeIdentifier(augmentationId)
268                 .withChild(leafNode(SIMPLE_VALUE_QNAME, "simpleValue"))
269                 .build();
270         final Entry<InstanceIdentifier<?>, DataObject> entry = codecContext.fromNormalizedNode(
271             BI_TOP_LEVEL_LIST_FOO_PATH.node(augmentationId), augmentationNode);
272         assertEquals(new TreeLeafOnlyAugmentBuilder().setSimpleValue("simpleValue").build(), entry.getValue());
273     }
274
275     @Test
276     public void orderedleafListToNormalized() {
277         Top top = new TopBuilder().setTopLevelOrderedLeafList(List.of("foo")).build();
278
279         Entry<YangInstanceIdentifier, NormalizedNode> entry = codecContext.toNormalizedNode(
280             InstanceIdentifier.create(Top.class), top);
281         ContainerNode containerNode = ImmutableContainerNodeBuilder.create()
282                 .withNodeIdentifier(new NodeIdentifier(TOP_QNAME))
283                 .withChild(ImmutableUserLeafSetNodeBuilder.create()
284                         .withNodeIdentifier(new NodeIdentifier(TOP_LEVEL_ORDERED_LEAF_LIST_QNAME))
285                         .withChild(
286                                 ImmutableLeafSetEntryNodeBuilder.create()
287                                         .withNodeIdentifier(new NodeWithValue<>(TOP_LEVEL_ORDERED_LEAF_LIST_QNAME,
288                                                 "foo"))
289                                         .withValue("foo")
290                                         .build())
291                         .build())
292                 .build();
293         assertEquals(containerNode, entry.getValue());
294     }
295
296     @Test
297     public void leafListToNormalized() {
298         final Top top = new TopBuilder().setTopLevelLeafList(Set.of("foo")).build();
299
300         final Entry<YangInstanceIdentifier, NormalizedNode> entry = codecContext.toNormalizedNode(
301             InstanceIdentifier.create(Top.class), top);
302         final ContainerNode containerNode = ImmutableContainerNodeBuilder.create()
303                 .withNodeIdentifier(new NodeIdentifier(TOP_QNAME))
304                 .withChild(ImmutableLeafSetNodeBuilder.create()
305                         .withNodeIdentifier(new NodeIdentifier(TOP_LEVEL_LEAF_LIST_QNAME))
306                         .withChild(
307                                 ImmutableLeafSetEntryNodeBuilder.create()
308                                         .withNodeIdentifier(new NodeWithValue<>(TOP_LEVEL_LEAF_LIST_QNAME, "foo"))
309                                         .withValue("foo")
310                                         .build())
311                         .build())
312                 .build();
313         assertEquals(containerNode, entry.getValue());
314     }
315
316     @Test
317     public void leafListFromNormalized() {
318         final ContainerNode topWithLeafList = ImmutableContainerNodeBuilder.create()
319                 .withNodeIdentifier(new NodeIdentifier(TOP_QNAME))
320                 .withChild(ImmutableLeafSetNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(
321                     TOP_LEVEL_LEAF_LIST_QNAME))
322                     .withChild(ImmutableLeafSetEntryNodeBuilder.create()
323                         .withNodeIdentifier(new NodeWithValue<>(TOP_LEVEL_LEAF_LIST_QNAME, "foo"))
324                         .withValue("foo").build()).build())
325                 .build();
326         final Entry<InstanceIdentifier<?>, DataObject> entry = codecContext.fromNormalizedNode(BI_TOP_PATH,
327             topWithLeafList);
328         final Top top = new TopBuilder().setTopLevelLeafList(Set.of("foo")).build();
329         assertEquals(top, entry.getValue());
330     }
331
332     @Test
333     public void orderedLeafListFromNormalized() {
334         ContainerNode topWithLeafList = ImmutableContainerNodeBuilder.create()
335                 .withNodeIdentifier(new NodeIdentifier(TOP_QNAME))
336                 .withChild(ImmutableUserLeafSetNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(
337                     TOP_LEVEL_ORDERED_LEAF_LIST_QNAME))
338                     .withChild(ImmutableLeafSetEntryNodeBuilder.create().withNodeIdentifier(
339                         new NodeWithValue<>(TOP_LEVEL_ORDERED_LEAF_LIST_QNAME, "foo")).withValue("foo").build())
340                     .build())
341                 .build();
342         Entry<InstanceIdentifier<?>, DataObject> entry = codecContext.fromNormalizedNode(BI_TOP_PATH, topWithLeafList);
343         Top top = new TopBuilder().setTopLevelOrderedLeafList(List.of("foo")).build();
344         assertEquals(top, entry.getValue());
345     }
346
347     @Test
348     public void choiceToNormalized() {
349         final ChoiceContainer choiceContainerBA = new ChoiceContainerBuilder().setIdentifier(new ExtendedBuilder()
350             .setExtendedId(new ExtendedIdBuilder().setId("identifier_value").build()).build()).build();
351         final Entry<YangInstanceIdentifier, NormalizedNode> entry = codecContext.toNormalizedNode(
352             InstanceIdentifier.create(ChoiceContainer.class), choiceContainerBA);
353         final ContainerNode choiceContainer = ImmutableContainerNodeBuilder.create()
354                 .withNodeIdentifier(new NodeIdentifier(CHOICE_CONTAINER_QNAME))
355                 .withChild(ImmutableChoiceNodeBuilder.create()
356                     .withNodeIdentifier(new NodeIdentifier(CHOICE_IDENTIFIER_QNAME))
357                         .withChild(ImmutableContainerNodeBuilder.create()
358                             .withNodeIdentifier(new NodeIdentifier(EXTENDED_ID_QNAME))
359                             .withChild(leafNode(CHOICE_IDENTIFIER_ID_QNAME, "identifier_value")).build()).build())
360                 .build();
361         assertEquals(choiceContainer, entry.getValue());
362     }
363
364     @Test
365     public void test4798() {
366         final QName containerIdentifierQname4798 = Root.QNAME;
367         final QName choiceIdentifierQname4798 = QName.create(containerIdentifierQname4798, "bug4798-choice");
368         final QName nestedListQname4798 = QName.create(containerIdentifierQname4798, "list-in-case");
369         final QName nestedListKeyQname4798 = QName.create(containerIdentifierQname4798, "test-leaf");
370         final QName nestedContainerValidQname = QName.create(containerIdentifierQname4798, "case-b-container");
371         final QName nestedContainerOuterQname = QName.create(containerIdentifierQname4798, "outer-container");
372         final QName nestedContainerLeafOuterQname = QName.create(containerIdentifierQname4798,
373                 "leaf-in-outer-container");
374
375         final YangInstanceIdentifier yangInstanceIdentifierOuter = YangInstanceIdentifier.of(
376             containerIdentifierQname4798);
377         final ContainerNode containerNodeOuter = ImmutableContainerNodeBuilder.create()
378                 .withNodeIdentifier(new NodeIdentifier(containerIdentifierQname4798))
379                 .withChild(ImmutableContainerNodeBuilder.create()
380                         .withNodeIdentifier(new NodeIdentifier(nestedContainerOuterQname))
381                         .withChild(leafNode(nestedContainerLeafOuterQname, "bar"))
382                         .build())
383                 .build();
384         final Entry<InstanceIdentifier<?>, DataObject> entryContainer = codecContext.fromNormalizedNode(
385             yangInstanceIdentifierOuter, containerNodeOuter);
386         assertNotNull(entryContainer.getValue());
387         assertNotNull(entryContainer.getKey());
388
389         final NodeIdentifierWithPredicates nodeIdentifierWithPredicates4798 =
390                 NodeIdentifierWithPredicates.of(nestedListQname4798, nestedListKeyQname4798, "foo");
391         final YangInstanceIdentifier yangInstanceIdentifier4798 = YangInstanceIdentifier.of(
392             containerIdentifierQname4798)
393                 .node(choiceIdentifierQname4798)
394                 .node(nestedListQname4798)
395                 .node(nodeIdentifierWithPredicates4798);
396
397         final YangInstanceIdentifier yangInstanceIdentifierValid = YangInstanceIdentifier.of(
398             containerIdentifierQname4798)
399                 .node(choiceIdentifierQname4798)
400                 .node(nestedContainerValidQname)
401                 .node(nestedListQname4798)
402                 .node(nodeIdentifierWithPredicates4798);
403         final ContainerNode containerNodeValid = ImmutableContainerNodeBuilder.create()
404                 .withNodeIdentifier(new NodeIdentifier(containerIdentifierQname4798))
405                 .withChild(ImmutableChoiceNodeBuilder.create()
406                         .withNodeIdentifier(new NodeIdentifier(choiceIdentifierQname4798))
407                         .withChild(ImmutableContainerNodeBuilder.create()
408                                 .withNodeIdentifier(new NodeIdentifier(nestedContainerValidQname))
409                                 .withChild(ImmutableMapNodeBuilder.create()
410                                     .withNodeIdentifier(new NodeIdentifier(nestedListQname4798))
411                                         .withChild(mapEntry(nestedListQname4798, nestedListKeyQname4798, "foo"))
412                                         .withChild(mapEntry(nestedListQname4798, nestedListKeyQname4798, "bar"))
413                                         .build())
414                                 .build())
415                         .build())
416                 .build();
417         try {
418             codecContext.fromNormalizedNode(yangInstanceIdentifierValid, containerNodeValid);
419             fail("Incorect YangInstanceIdentifier should fail");
420         } catch (IllegalStateException e) {
421             // Expected
422         }
423
424         final ContainerNode containerNode4798 = ImmutableContainerNodeBuilder.create()
425                 .withNodeIdentifier(new NodeIdentifier(containerIdentifierQname4798))
426                 .withChild(ImmutableChoiceNodeBuilder.create()
427                         .withNodeIdentifier(new NodeIdentifier(choiceIdentifierQname4798))
428                         .withChild(ImmutableMapNodeBuilder.create()
429                             .withNodeIdentifier(new NodeIdentifier(nestedListQname4798))
430                             .withChild(mapEntry(nestedListQname4798, nestedListKeyQname4798, "foo"))
431                             .withChild(mapEntry(nestedListQname4798, nestedListKeyQname4798, "bar"))
432                             .build())
433                         .build())
434                 .build();
435         try {
436             codecContext.fromNormalizedNode(yangInstanceIdentifier4798, containerNode4798);
437             fail("Incorect YangInstanceIdentifier should fail");
438         } catch (IllegalStateException e) {
439             // Expected
440         }
441     }
442
443     @Test
444     public void choiceFromNormalized() {
445         final ContainerNode choiceContainerBI = ImmutableContainerNodeBuilder.create()
446                 .withNodeIdentifier(new NodeIdentifier(CHOICE_CONTAINER_QNAME))
447                 .withChild(ImmutableChoiceNodeBuilder.create()
448                     .withNodeIdentifier(new NodeIdentifier(CHOICE_IDENTIFIER_QNAME))
449                     .withChild(ImmutableContainerNodeBuilder.create()
450                         .withNodeIdentifier(new NodeIdentifier(EXTENDED_ID_QNAME))
451                         .withChild(leafNode(CHOICE_IDENTIFIER_ID_QNAME, "identifier_value")).build()).build())
452                 .build();
453         final Entry<InstanceIdentifier<?>, DataObject> entry = codecContext.fromNormalizedNode(BI_CHOICE_CONTAINER_PATH,
454             choiceContainerBI);
455         final ChoiceContainer choiceContainerBA = new ChoiceContainerBuilder().setIdentifier(new ExtendedBuilder()
456             .setExtendedId(new ExtendedIdBuilder().setId("identifier_value").build()).build()).build();
457         assertEquals(choiceContainerBA, entry.getValue());
458     }
459
460     @Test
461     public void orderedLisToNormalized() {
462         final TopLevelList topLevelList = new TopLevelListBuilder()
463             .withKey(TOP_LEVEL_LIST_FOO_KEY)
464             .setNestedList(List.of(
465                 new NestedListBuilder().withKey(new NestedListKey("foo")).build(),
466                 new NestedListBuilder().withKey(new NestedListKey("bar")).build()))
467             .build();
468         final Entry<YangInstanceIdentifier, NormalizedNode> entry = codecContext.toNormalizedNode(BA_TOP_LEVEL_LIST,
469             topLevelList);
470         final MapEntryNode foo = mapEntryBuilder().withNodeIdentifier(NodeIdentifierWithPredicates.of(
471                 TOP_LEVEL_LIST_QNAME, TOP_LEVEL_LIST_KEY_QNAME, TOP_LEVEL_LIST_FOO_KEY_VALUE))
472                 .withChild(leafNode(TOP_LEVEL_LIST_KEY_QNAME, TOP_LEVEL_LIST_FOO_KEY_VALUE))
473                 .withChild(ImmutableUserMapNodeBuilder.create()
474                     .withNodeIdentifier(new NodeIdentifier(NESTED_LIST_QNAME))
475                     .withChild(mapEntry(NESTED_LIST_QNAME, NESTED_LIST_KEY_QNAME, "foo"))
476                     .withChild(mapEntry(NESTED_LIST_QNAME, NESTED_LIST_KEY_QNAME, "bar")).build()).build();
477         assertEquals(foo, entry.getValue());
478     }
479
480     @Test
481     public void orderedLisFromNormalized() {
482         final MapEntryNode foo = mapEntryBuilder().withNodeIdentifier(NodeIdentifierWithPredicates.of(
483                 TOP_LEVEL_LIST_QNAME, TOP_LEVEL_LIST_KEY_QNAME, TOP_LEVEL_LIST_FOO_KEY_VALUE))
484                 .withChild(leafNode(TOP_LEVEL_LIST_KEY_QNAME, TOP_LEVEL_LIST_FOO_KEY_VALUE))
485                 .withChild(ImmutableUserMapNodeBuilder.create()
486                     .withNodeIdentifier(new NodeIdentifier(NESTED_LIST_QNAME))
487                     .withChild(mapEntry(NESTED_LIST_QNAME, NESTED_LIST_KEY_QNAME, "foo"))
488                     .withChild(mapEntry(NESTED_LIST_QNAME, NESTED_LIST_KEY_QNAME, "bar")).build()).build();
489         final Entry<InstanceIdentifier<?>, DataObject> entry = codecContext.fromNormalizedNode(
490             BI_TOP_LEVEL_LIST_FOO_PATH, foo);
491         final TopLevelList topLevelList = new TopLevelListBuilder()
492             .withKey(TOP_LEVEL_LIST_FOO_KEY)
493             .setNestedList(List.of(
494                 new NestedListBuilder().withKey(new NestedListKey("foo")).build(),
495                 new NestedListBuilder().withKey(new NestedListKey("bar")).build()))
496             .build();
497         assertEquals(topLevelList, entry.getValue());
498     }
499
500     @Test
501     public void augmentMultipleChoices() {
502         final QName augmentChoice1QName = AugmentChoice1.QNAME;
503         final QName augmentChoice2QName = QName.create(augmentChoice1QName, "augment-choice2");
504         final QName containerQName = QName.create(augmentChoice1QName, "case11-choice-case-container");
505         final QName leafQName = QName.create(augmentChoice1QName, "case11-choice-case-leaf");
506
507         final AugmentationIdentifier aug1Id = new AugmentationIdentifier(Set.of(augmentChoice1QName));
508         final AugmentationIdentifier aug2Id = new AugmentationIdentifier(Set.of(augmentChoice2QName));
509         final NodeIdentifier augmentChoice1Id = new NodeIdentifier(augmentChoice1QName);
510         final NodeIdentifier augmentChoice2Id = new NodeIdentifier(augmentChoice2QName);
511         final NodeIdentifier containerId = new NodeIdentifier(containerQName);
512
513         final TopBuilder tBuilder = new TopBuilder();
514         final TopChoiceAugment1Builder tca1Builder = new TopChoiceAugment1Builder();
515         final Case1Builder c1Builder = new Case1Builder();
516         final TopChoiceAugment2Builder tca2Builder = new TopChoiceAugment2Builder();
517         final Case11Builder c11Builder = new Case11Builder();
518         final Case11ChoiceCaseContainerBuilder cccc1Builder = new Case11ChoiceCaseContainerBuilder();
519         cccc1Builder.setCase11ChoiceCaseLeaf("leaf-value");
520         c11Builder.setCase11ChoiceCaseContainer(cccc1Builder.build());
521         tca2Builder.setAugmentChoice2(c11Builder.build());
522         c1Builder.addAugmentation(tca2Builder.build());
523         tca1Builder.setAugmentChoice1(c1Builder.build());
524         tBuilder.addAugmentation(tca1Builder.build());
525         final Top top = tBuilder.build();
526
527         final Entry<YangInstanceIdentifier, NormalizedNode> biResult = codecContext.toNormalizedNode(
528             InstanceIdentifier.create(Top.class), top);
529
530         final NormalizedNode topNormalized = containerBuilder()
531                 .withNodeIdentifier(new NodeIdentifier(TOP_QNAME))
532                 .withChild(augmentationBuilder().withNodeIdentifier(aug1Id)
533                         .withChild(choiceBuilder().withNodeIdentifier(augmentChoice1Id)
534                                 .withChild(augmentationBuilder().withNodeIdentifier(aug2Id)
535                                         .withChild(choiceBuilder().withNodeIdentifier(augmentChoice2Id)
536                                                 .withChild(containerBuilder().withNodeIdentifier(containerId)
537                                                         .withChild(leafNode(leafQName, "leaf-value"))
538                                                         .build())
539                                                 .build())
540                                         .build())
541                                 .build())
542                         .build()).build();
543
544         assertEquals(BI_TOP_PATH, biResult.getKey());
545         assertEquals(topNormalized, biResult.getValue());
546
547         final Entry<InstanceIdentifier<?>, DataObject> baResult = codecContext.fromNormalizedNode(BI_TOP_PATH,
548             topNormalized);
549
550         assertEquals(InstanceIdentifier.create(Top.class), baResult.getKey());
551         assertEquals(top, baResult.getValue());
552     }
553 }