Adjust test suite parser update to conform with API changes
[yangtools.git] / yang / yang-parser-rfc7950 / src / test / java / org / opendaylight / yangtools / yang / parser / stmt / rfc7950 / Bug6887Test.java
1 /*
2  * Copyright (c) 2017 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
9 package org.opendaylight.yangtools.yang.parser.stmt.rfc7950;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertTrue;
14 import static org.junit.Assert.fail;
15
16 import com.google.common.collect.ImmutableList;
17 import com.google.common.collect.Iterables;
18 import java.util.List;
19 import org.junit.Test;
20 import org.opendaylight.yangtools.yang.common.QName;
21 import org.opendaylight.yangtools.yang.common.QNameModule;
22 import org.opendaylight.yangtools.yang.common.Revision;
23 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
24 import org.opendaylight.yangtools.yang.model.api.Module;
25 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
26 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
27 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
28 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
29 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
30 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
31 import org.opendaylight.yangtools.yang.model.util.type.BitBuilder;
32 import org.opendaylight.yangtools.yang.model.util.type.EnumPairBuilder;
33 import org.opendaylight.yangtools.yang.model.util.type.InvalidBitDefinitionException;
34 import org.opendaylight.yangtools.yang.model.util.type.InvalidEnumDefinitionException;
35 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
36 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
37 import org.opendaylight.yangtools.yang.stmt.StmtTestUtils;
38
39 public class Bug6887Test {
40
41     @Test
42     public void testRestrictedEnumeration() throws Exception {
43         final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo.yang");
44         assertNotNull(schemaContext);
45
46         final Module foo = schemaContext.findModule("foo", Revision.of("2017-01-26")).get();
47         final LeafSchemaNode myEnumerationLeaf = (LeafSchemaNode) foo.getDataChildByName(
48                 QName.create(foo.getQNameModule(), "my-enumeration-leaf"));
49         assertNotNull(myEnumerationLeaf);
50
51         EnumTypeDefinition enumerationType = (EnumTypeDefinition) myEnumerationLeaf.getType();
52
53         List<EnumPair> enums = enumerationType.getValues();
54         assertEquals(2, enums.size());
55         final EnumPair yellowEnum = createEnumPair("yellow", 2);
56         final EnumPair redEnum = createEnumPair("red", 3);
57         assertContainsEnums(enums, yellowEnum, redEnum);
58
59         enumerationType = enumerationType.getBaseType();
60         enums = enumerationType.getValues();
61         assertEquals(3, enums.size());
62         final EnumPair blackEnum = createEnumPair("black", 4);
63         assertContainsEnums(enums, yellowEnum, redEnum, blackEnum);
64
65         enumerationType = enumerationType.getBaseType();
66         enums = enumerationType.getValues();
67         assertEquals(4, enums.size());
68         final EnumPair whiteEnum = createEnumPair("white", 1);
69         assertContainsEnums(enums, whiteEnum, yellowEnum, redEnum, blackEnum);
70
71         final LeafSchemaNode myEnumerationLeaf2 = (LeafSchemaNode) foo.getDataChildByName(
72                 QName.create(foo.getQNameModule(), "my-enumeration-leaf-2"));
73         assertNotNull(myEnumerationLeaf2);
74
75         enumerationType = (EnumTypeDefinition) myEnumerationLeaf2.getType();
76         enums = enumerationType.getValues();
77         assertEquals(3, enums.size());
78         assertContainsEnums(enums, yellowEnum, redEnum, blackEnum);
79     }
80
81     @Test
82     public void testInvalidRestrictedEnumeration() throws Exception {
83         try {
84             StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo-invalid.yang");
85             fail("An exception should have been thrown.");
86         } catch (final ReactorException ex) {
87             final Throwable cause = ex.getCause();
88             assertTrue(cause instanceof SourceException);
89             assertTrue(cause.getMessage().startsWith("Enum 'purple' is not a subset of its base enumeration type "
90                     + "(foo?revision=2017-02-02)my-derived-enumeration-type."));
91         }
92     }
93
94     @Test
95     public void testInvalidRestrictedEnumeration2() throws Exception {
96         try {
97             StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo-invalid-2.yang");
98             fail("An exception should have been thrown.");
99         } catch (final ReactorException ex) {
100             final Throwable cause = ex.getCause();
101             assertTrue(cause instanceof InvalidEnumDefinitionException);
102             assertTrue(cause.getMessage().startsWith("Enum 'magenta' is not a subset of its base enumeration type "
103                     + "(foo?revision=2017-02-02)my-base-enumeration-type."));
104         }
105     }
106
107     @Test
108     public void testInvalidRestrictedEnumeration3() throws Exception {
109         try {
110             StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo-invalid-3.yang");
111             fail("An exception should have been thrown.");
112         } catch (final ReactorException ex) {
113             final Throwable cause = ex.getCause();
114             assertTrue(cause instanceof InvalidEnumDefinitionException);
115             assertTrue(cause.getMessage().startsWith("Value of enum 'red' must be the same as the value of "
116                     + "corresponding enum in the base enumeration type (foo?revision=2017-02-02)"
117                     + "my-derived-enumeration-type."));
118         }
119     }
120
121     @Test
122     public void testInvalidRestrictedEnumeration4() throws Exception {
123         try {
124             StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo-invalid-4.yang");
125             fail("An exception should have been thrown.");
126         } catch (final ReactorException ex) {
127             final Throwable cause = ex.getCause();
128             assertTrue(cause instanceof InvalidEnumDefinitionException);
129             assertTrue(cause.getMessage().startsWith("Value of enum 'black' must be the same as the value of "
130                     + "corresponding enum in the base enumeration type (foo?revision=2017-02-02)"
131                     + "my-base-enumeration-type."));
132         }
133     }
134
135     @Test
136     public void testValidYang10EnumerationWithUnknownStatements() throws Exception {
137         final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo10-valid.yang");
138         assertNotNull(schemaContext);
139     }
140
141     @Test
142     public void testInvalidYang10RestrictedEnumeration() throws Exception {
143         try {
144             StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo10-invalid.yang");
145             fail("An exception should have been thrown.");
146         } catch (final ReactorException ex) {
147             final Throwable cause = ex.getCause();
148             assertTrue(cause instanceof SourceException);
149             assertTrue(cause.getMessage().startsWith(
150                 "Restricted enumeration type is allowed only in YANG 1.1 version."));
151         }
152     }
153
154     @Test
155     public void testInvalidYang10RestrictedEnumeration2() throws Exception {
156         try {
157             StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo10-invalid-2.yang");
158             fail("An exception should have been thrown.");
159         } catch (final ReactorException ex) {
160             final Throwable cause = ex.getCause();
161             assertTrue(cause instanceof SourceException);
162             assertTrue(cause.getMessage().startsWith(
163                 "Restricted enumeration type is allowed only in YANG 1.1 version."));
164         }
165     }
166
167     @Test
168     public void testRestrictedBits() throws Exception {
169         final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar.yang");
170         assertNotNull(schemaContext);
171
172         final Module bar = schemaContext.findModule("bar", Revision.of("2017-02-02")).get();
173         final LeafSchemaNode myBitsLeaf = (LeafSchemaNode) bar.getDataChildByName(
174                 QName.create(bar.getQNameModule(), "my-bits-leaf"));
175         assertNotNull(myBitsLeaf);
176
177         BitsTypeDefinition bitsType = (BitsTypeDefinition) myBitsLeaf.getType();
178
179         List<Bit> bits = bitsType.getBits();
180         assertEquals(2, bits.size());
181         Bit bitB = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-bits-leaf",
182                 "my-derived-bits-type", "bit-b")), 2);
183         Bit bitC = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-bits-leaf",
184                 "my-derived-bits-type", "bit-c")), 3);
185         assertContainsBits(bits, bitB, bitC);
186
187         bitsType = bitsType.getBaseType();
188         bits = bitsType.getBits();
189         assertEquals(3, bits.size());
190         bitB = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-derived-bits-type",
191                 "my-base-bits-type", "bit-b")), 2);
192         bitC = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-derived-bits-type",
193                 "my-base-bits-type", "bit-c")), 3);
194         Bit bitD = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-derived-bits-type",
195                 "my-base-bits-type", "bit-d")), 4);
196         assertContainsBits(bits, bitB, bitC, bitD);
197
198         bitsType = bitsType.getBaseType();
199         bits = bitsType.getBits();
200         assertEquals(4, bits.size());
201         final Bit bitA = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-base-bits-type",
202                 "bits", "bit-a")), 1);
203         bitB = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-base-bits-type",
204                 "bits", "bit-b")), 2);
205         bitC = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-base-bits-type",
206                 "bits", "bit-c")), 3);
207         bitD = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-base-bits-type",
208                 "bits", "bit-d")), 4);
209         assertContainsBits(bits, bitA, bitB, bitC, bitD);
210
211         final LeafSchemaNode myBitsLeaf2 = (LeafSchemaNode) bar.getDataChildByName(
212                 QName.create(bar.getQNameModule(), "my-bits-leaf-2"));
213         assertNotNull(myBitsLeaf2);
214
215         bitsType = (BitsTypeDefinition) myBitsLeaf2.getType();
216         bits = bitsType.getBits();
217         assertEquals(3, bits.size());
218         bitB = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-derived-bits-type",
219                 "my-base-bits-type", "bit-b")), 2);
220         bitC = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-derived-bits-type",
221                 "my-base-bits-type", "bit-c")), 3);
222         bitD = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-derived-bits-type",
223                 "my-base-bits-type", "bit-d")), 4);
224         assertContainsBits(bits, bitB, bitC, bitD);
225     }
226
227     @Test
228     public void testInvalidRestrictedBits() throws Exception {
229         try {
230             StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar-invalid.yang");
231             fail("An exception should have been thrown.");
232         } catch (final ReactorException ex) {
233             final Throwable cause = ex.getCause();
234             assertTrue(cause instanceof SourceException);
235             assertTrue(cause.getMessage().startsWith("Bit 'bit-w' is not a subset of its base bits type "
236                     + "(bar?revision=2017-02-02)my-derived-bits-type."));
237         }
238     }
239
240     @Test
241     public void testInvalidRestrictedBits2() throws Exception {
242         try {
243             StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar-invalid-2.yang");
244             fail("An exception should have been thrown.");
245         } catch (final ReactorException ex) {
246             final Throwable cause = ex.getCause();
247             assertTrue(cause instanceof InvalidBitDefinitionException);
248             assertTrue(cause.getMessage().startsWith("Bit 'bit-x' is not a subset of its base bits type "
249                     + "(bar?revision=2017-02-02)my-base-bits-type."));
250         }
251     }
252
253     @Test
254     public void testInvalidRestrictedBits3() throws Exception {
255         try {
256             StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar-invalid-3.yang");
257             fail("An exception should have been thrown.");
258         } catch (final ReactorException ex) {
259             final Throwable cause = ex.getCause();
260             assertTrue(cause instanceof InvalidBitDefinitionException);
261             assertTrue(cause.getMessage().startsWith("Position of bit 'bit-c' must be the same as the position of "
262                     + "corresponding bit in the base bits type (bar?revision=2017-02-02)my-derived-bits-type."));
263         }
264     }
265
266     @Test
267     public void testInvalidRestrictedBits4() throws Exception {
268         try {
269             StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar-invalid-4.yang");
270             fail("An exception should have been thrown.");
271         } catch (final ReactorException ex) {
272             final Throwable cause = ex.getCause();
273             assertTrue(cause instanceof InvalidBitDefinitionException);
274             assertTrue(cause.getMessage().startsWith("Position of bit 'bit-d' must be the same as the position of "
275                     + "corresponding bit in the base bits type (bar?revision=2017-02-02)my-base-bits-type."));
276         }
277     }
278
279     @Test
280     public void testValidYang10BitsWithUnknownStatements() throws Exception {
281         final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar10-valid.yang");
282         assertNotNull(schemaContext);
283     }
284
285     @Test
286     public void testInvalidYang10RestrictedBits() throws Exception {
287         try {
288             StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar10-invalid.yang");
289             fail("An exception should have been thrown.");
290         } catch (final ReactorException ex) {
291             final Throwable cause = ex.getCause();
292             assertTrue(cause instanceof SourceException);
293             assertTrue(cause.getMessage().startsWith("Restricted bits type is allowed only in YANG 1.1 version."));
294         }
295     }
296
297     @Test
298     public void testInvalidYang10RestrictedBits2() throws Exception {
299         try {
300             StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar10-invalid-2.yang");
301             fail("An exception should have been thrown.");
302         } catch (final ReactorException ex) {
303             final Throwable cause = ex.getCause();
304             assertTrue(cause instanceof SourceException);
305             assertTrue(cause.getMessage().startsWith("Restricted bits type is allowed only in YANG 1.1 version."));
306         }
307     }
308
309     private static EnumPair createEnumPair(final String name, final int value) {
310         return EnumPairBuilder.create(name, value).build();
311     }
312
313     private static void assertContainsEnums(final List<EnumPair> enumList, final EnumPair... enumPairs) {
314         for (final EnumPair enumPair : enumPairs) {
315             assertTrue(enumList.contains(enumPair));
316         }
317     }
318
319     private static Bit createBit(final SchemaPath path, final long position) {
320         return BitBuilder.create(path, position).build();
321     }
322
323     private static void assertContainsBits(final List<Bit> bitList, final Bit... bits) {
324         for (final Bit bit : bits) {
325             assertTrue(bitList.contains(bit));
326         }
327     }
328
329     private static SchemaPath createSchemaPath(final boolean absolute, final QNameModule qnameModule,
330             final Iterable<String> localNames) {
331         return SchemaPath.create(Iterables.transform(localNames,
332             localName -> QName.create(qnameModule, localName)), true);
333     }
334 }