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