24d3cd3ffe0e5e76fd20770a2d30fbff75d02060
[yangtools.git] / data / yang-data-tree-ri / src / test / java / org / opendaylight / yangtools / yang / data / tree / leafref / YT891Test.java
1 /*
2  * Copyright (c) 2018 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.yangtools.yang.data.tree.leafref;
9
10 import org.junit.AfterClass;
11 import org.junit.Before;
12 import org.junit.BeforeClass;
13 import org.junit.Test;
14 import org.opendaylight.yangtools.yang.common.QName;
15 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
16 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
18 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
19 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
20 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
21 import org.opendaylight.yangtools.yang.data.tree.api.DataTree;
22 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
23 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeConfiguration;
24 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModification;
25 import org.opendaylight.yangtools.yang.data.tree.impl.di.InMemoryDataTreeFactory;
26 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
27 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
28
29 public class YT891Test {
30     private static final QName FOO_TOP = QName.create("urn:opendaylight:params:xml:ns:yang:foo", "2018-07-27",
31         "foo-top");
32     private static final QName CONTAINER_IN_LIST = QName.create(FOO_TOP, "container-in-list");
33     private static final QName LIST_IN_GROUPING = QName.create(FOO_TOP, "list-in-grouping");
34     private static final QName NAME = QName.create(FOO_TOP, "name");
35     private static final QName REF = QName.create(FOO_TOP, "ref");
36     private static final YangInstanceIdentifier FOO_TOP_ID = YangInstanceIdentifier.of(FOO_TOP);
37     private static final QName BAZ_TOP = QName.create("urn:opendaylight:params:xml:ns:yang:baz", "2018-07-27",
38         "baz-top");
39     private static final QName BAZ_NAME = QName.create(BAZ_TOP, "name");
40     private static final QName LIST_IN_CONTAINER = QName.create(BAZ_TOP, "list-in-container");
41     private static final YangInstanceIdentifier BAZ_TOP_ID = YangInstanceIdentifier.of(BAZ_TOP);
42
43     private static EffectiveModelContext schemaContext;
44     private static LeafRefContext leafRefContext;
45
46     private DataTree dataTree;
47
48     @Before
49     public void before() {
50         dataTree = new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_CONFIGURATION, schemaContext);
51     }
52
53     @BeforeClass
54     public static void beforeClass() {
55         schemaContext = YangParserTestUtils.parseYang("""
56             module bar {
57               namespace "urn:opendaylight:params:xml:ns:yang:bar";
58               prefix bar;
59               revision 2018-07-27;
60
61               grouping grouping-with-list {
62                 list list-in-grouping {
63                   key "name";
64                   leaf name {
65                     type leafref {
66                       path "../container-in-list/name";
67                     }
68                   }
69                   container container-in-list {
70                     leaf name {
71                       type string;
72                     }
73                   }
74                 }
75               }
76             }""", """
77             module baz {
78               namespace "urn:opendaylight:params:xml:ns:yang:baz";
79               prefix baz;
80               revision 2018-07-27;
81
82               grouping grouping-with-leafref {
83                 leaf ref {
84                   type leafref {
85                     path "/baz-top/list-in-container/name";
86                   }
87                 }
88               }
89
90               container baz-top {
91                 list list-in-container {
92                   key "name";
93                   leaf name {
94                     type string;
95                   }
96                 }
97               }
98             }""", """
99             module foo {
100               namespace "urn:opendaylight:params:xml:ns:yang:foo";
101               prefix foo;
102
103               import bar {
104                 prefix bar;
105               }
106
107               import baz {
108                 prefix baz;
109               }
110
111               revision 2018-07-27;
112
113               container foo-top {
114                 uses bar:grouping-with-list;
115                 uses baz:grouping-with-leafref;
116               }
117             }""");
118         leafRefContext = LeafRefContext.create(schemaContext);
119     }
120
121     @AfterClass
122     public static void afterClass() {
123         schemaContext = null;
124         leafRefContext = null;
125     }
126
127     @Test
128     public void testValid() throws Exception {
129         final DataTreeModification writeModification = dataTree.takeSnapshot().newModification();
130         writeModification.write(FOO_TOP_ID, fooTopWithList("name1"));
131         writeModification.ready();
132         final DataTreeCandidate writeContributorsCandidate = dataTree.prepare(writeModification);
133         LeafRefValidation.validate(writeContributorsCandidate, leafRefContext);
134         dataTree.commit(writeContributorsCandidate);
135     }
136
137     @Test(expected = LeafRefDataValidationFailedException.class)
138     public void testInvalid() throws Exception {
139         final DataTreeModification writeModification = dataTree.takeSnapshot().newModification();
140         writeModification.write(FOO_TOP_ID, fooTopWithList("name2"));
141         writeModification.ready();
142         LeafRefValidation.validate(dataTree.prepare(writeModification), leafRefContext);
143     }
144
145     @Test
146     public void testGroupingWithLeafrefValid() throws Exception {
147         final DataTreeModification writeModification = dataTree.takeSnapshot().newModification();
148         writeModification.write(BAZ_TOP_ID, bazTop());
149         writeModification.write(FOO_TOP_ID, fooTopWithRef("name1"));
150         writeModification.ready();
151         LeafRefValidation.validate(dataTree.prepare(writeModification), leafRefContext);
152     }
153
154     @Test(expected = LeafRefDataValidationFailedException.class)
155     public void testGroupingWithLeafrefInvalid() throws Exception {
156         final DataTreeModification writeModification = dataTree.takeSnapshot().newModification();
157         writeModification.write(BAZ_TOP_ID, bazTop());
158         writeModification.write(FOO_TOP_ID, fooTopWithRef("name3"));
159         writeModification.ready();
160         LeafRefValidation.validate(dataTree.prepare(writeModification), leafRefContext);
161     }
162
163     private static ContainerNode fooTopWithList(final String refValue) {
164         return Builders.containerBuilder()
165                 .withNodeIdentifier(new NodeIdentifier(FOO_TOP))
166                 .withChild(Builders.mapBuilder()
167                     .withNodeIdentifier(new NodeIdentifier(LIST_IN_GROUPING))
168                     .withChild(Builders.mapEntryBuilder()
169                         .withNodeIdentifier(NodeIdentifierWithPredicates.of(LIST_IN_GROUPING, NAME, "name1"))
170                         .withChild(ImmutableNodes.leafNode(NAME, "name1"))
171                         .withChild(Builders.containerBuilder()
172                             .withNodeIdentifier(new NodeIdentifier(CONTAINER_IN_LIST))
173                             .withChild(ImmutableNodes.leafNode(NAME, refValue))
174                             .build())
175                         .build())
176                     .build())
177                 .build();
178     }
179
180     private static ContainerNode fooTopWithRef(final String refValue) {
181         return Builders.containerBuilder()
182                 .withNodeIdentifier(new NodeIdentifier(FOO_TOP))
183                 .withChild(ImmutableNodes.leafNode(REF, refValue))
184                 .build();
185     }
186
187     private static ContainerNode bazTop() {
188         return Builders.containerBuilder()
189                 .withNodeIdentifier(new NodeIdentifier(BAZ_TOP))
190                 .withChild(Builders.mapBuilder()
191                     .withNodeIdentifier(new NodeIdentifier(LIST_IN_CONTAINER))
192                     .withChild(Builders.mapEntryBuilder()
193                         .withNodeIdentifier(NodeIdentifierWithPredicates.of(LIST_IN_CONTAINER, BAZ_NAME, "name1"))
194                         .withChild(ImmutableNodes.leafNode(BAZ_NAME, "name1"))
195                         .build())
196                     .build())
197                 .build();
198     }
199 }