Convert type checking in AbstractTypeStatementSupport
[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 package org.opendaylight.yangtools.yang.parser.stmt.rfc7950;
9
10 import static org.hamcrest.CoreMatchers.instanceOf;
11 import static org.hamcrest.CoreMatchers.startsWith;
12 import static org.hamcrest.MatcherAssert.assertThat;
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertNotNull;
15 import static org.junit.Assert.assertThrows;
16 import static org.junit.Assert.assertTrue;
17
18 import java.util.Collection;
19 import java.util.List;
20 import org.junit.Test;
21 import org.opendaylight.yangtools.yang.common.QName;
22 import org.opendaylight.yangtools.yang.common.Revision;
23 import org.opendaylight.yangtools.yang.common.Uint32;
24 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
25 import org.opendaylight.yangtools.yang.model.api.Module;
26 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
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() {
83         final ReactorException ex = assertThrows(ReactorException.class,
84             () -> StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo-invalid.yang"));
85         final Throwable cause = ex.getCause();
86         assertThat(cause, instanceOf(SourceException.class));
87         assertThat(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     @Test
92     public void testInvalidRestrictedEnumeration2() {
93         final ReactorException ex = assertThrows(ReactorException.class,
94             () -> StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo-invalid-2.yang"));
95         final Throwable cause = ex.getCause();
96         assertThat(cause, instanceOf(InvalidEnumDefinitionException.class));
97         assertThat(cause.getMessage(), startsWith("Enum 'magenta' is not a subset of its base enumeration type "
98             + "(foo?revision=2017-02-02)my-base-enumeration-type."));
99     }
100
101     @Test
102     public void testInvalidRestrictedEnumeration3() {
103         final ReactorException ex = assertThrows(ReactorException.class,
104             () -> StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo-invalid-3.yang"));
105         final Throwable cause = ex.getCause();
106         assertThat(cause, instanceOf(InvalidEnumDefinitionException.class));
107         assertThat(cause.getMessage(), startsWith("Value of enum 'red' must be the same as the value of "
108             + "corresponding enum in the base enumeration type (foo?revision=2017-02-02)"
109             + "my-derived-enumeration-type."));
110     }
111
112     @Test
113     public void testInvalidRestrictedEnumeration4() {
114         final ReactorException ex = assertThrows(ReactorException.class,
115             () -> StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo-invalid-4.yang"));
116         final Throwable cause = ex.getCause();
117         assertThat(cause, instanceOf(InvalidEnumDefinitionException.class));
118         assertThat(cause.getMessage(), startsWith("Value of enum 'black' must be the same as the value of "
119             + "corresponding enum in the base enumeration type (foo?revision=2017-02-02)"
120             + "my-base-enumeration-type."));
121     }
122
123     @Test
124     public void testValidYang10EnumerationWithUnknownStatements() throws Exception {
125         final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo10-valid.yang");
126         assertNotNull(schemaContext);
127     }
128
129     @Test
130     public void testInvalidYang10RestrictedEnumeration() {
131         final ReactorException ex = assertThrows(ReactorException.class,
132             () -> StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo10-invalid.yang"));
133         final Throwable cause = ex.getCause();
134         assertThat(cause, instanceOf(SourceException.class));
135         assertThat(cause.getMessage(), startsWith("Restricted enumeration type is not allowed in YANG version 1 [at "));
136     }
137
138     @Test
139     public void testInvalidYang10RestrictedEnumeration2() {
140         final ReactorException ex = assertThrows(ReactorException.class,
141             () -> StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo10-invalid-2.yang"));
142         final Throwable cause = ex.getCause();
143         assertThat(cause, instanceOf(SourceException.class));
144         assertThat(cause.getMessage(), startsWith("Restricted enumeration type is not allowed in YANG version 1 [at "));
145     }
146
147     @Test
148     public void testRestrictedBits() throws Exception {
149         final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar.yang");
150         assertNotNull(schemaContext);
151
152         final Module bar = schemaContext.findModule("bar", Revision.of("2017-02-02")).get();
153         final LeafSchemaNode myBitsLeaf = (LeafSchemaNode) bar.getDataChildByName(
154                 QName.create(bar.getQNameModule(), "my-bits-leaf"));
155         assertNotNull(myBitsLeaf);
156
157         BitsTypeDefinition bitsType = (BitsTypeDefinition) myBitsLeaf.getType();
158
159         Collection<? extends Bit> bits = bitsType.getBits();
160         assertEquals(2, bits.size());
161         Bit bitB = createBit("bit-b", 2);
162         Bit bitC = createBit("bit-c", 3);
163         assertContainsBits(bits, bitB, bitC);
164
165         bitsType = bitsType.getBaseType();
166         bits = bitsType.getBits();
167         assertEquals(3, bits.size());
168         bitB = createBit("bit-b", 2);
169         bitC = createBit("bit-c", 3);
170         Bit bitD = createBit("bit-d", 4);
171         assertContainsBits(bits, bitB, bitC, bitD);
172
173         bitsType = bitsType.getBaseType();
174         bits = bitsType.getBits();
175         assertEquals(4, bits.size());
176         final Bit bitA = createBit("bit-a", 1);
177         bitB = createBit("bit-b", 2);
178         bitC = createBit("bit-c", 3);
179         bitD = createBit("bit-d", 4);
180         assertContainsBits(bits, bitA, bitB, bitC, bitD);
181
182         final LeafSchemaNode myBitsLeaf2 = (LeafSchemaNode) bar.getDataChildByName(
183                 QName.create(bar.getQNameModule(), "my-bits-leaf-2"));
184         assertNotNull(myBitsLeaf2);
185
186         bitsType = (BitsTypeDefinition) myBitsLeaf2.getType();
187         bits = bitsType.getBits();
188         assertEquals(3, bits.size());
189         bitB = createBit("bit-b", 2);
190         bitC = createBit("bit-c", 3);
191         bitD = createBit("bit-d", 4);
192         assertContainsBits(bits, bitB, bitC, bitD);
193     }
194
195     @Test
196     public void testInvalidRestrictedBits() {
197         final ReactorException ex = assertThrows(ReactorException.class,
198             () -> StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar-invalid.yang"));
199         final Throwable cause = ex.getCause();
200         assertThat(cause, instanceOf(SourceException.class));
201         assertThat(cause.getMessage(), startsWith("Bit 'bit-w' is not a subset of its base bits type "
202             + "(bar?revision=2017-02-02)my-derived-bits-type."));
203     }
204
205     @Test
206     public void testInvalidRestrictedBits2() {
207         final ReactorException ex = assertThrows(ReactorException.class,
208             () -> StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar-invalid-2.yang"));
209         final Throwable cause = ex.getCause();
210         assertThat(cause, instanceOf(InvalidBitDefinitionException.class));
211         assertThat(cause.getMessage(), startsWith("Bit 'bit-x' is not a subset of its base bits type "
212             + "(bar?revision=2017-02-02)my-base-bits-type."));
213     }
214
215     @Test
216     public void testInvalidRestrictedBits3() {
217         final ReactorException ex = assertThrows(ReactorException.class,
218             () -> StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar-invalid-3.yang"));
219         final Throwable cause = ex.getCause();
220         assertThat(cause, instanceOf(InvalidBitDefinitionException.class));
221         assertThat(cause.getMessage(), startsWith("Position of bit 'bit-c' must be the same as the position of "
222             + "corresponding bit in the base bits type (bar?revision=2017-02-02)my-derived-bits-type."));
223     }
224
225     @Test
226     public void testInvalidRestrictedBits4() {
227         final ReactorException ex = assertThrows(ReactorException.class,
228             () -> StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar-invalid-4.yang"));
229         final Throwable cause = ex.getCause();
230         assertThat(cause, instanceOf(InvalidBitDefinitionException.class));
231         assertThat(cause.getMessage(), startsWith("Position of bit 'bit-d' must be the same as the position of "
232             + "corresponding bit in the base bits type (bar?revision=2017-02-02)my-base-bits-type."));
233     }
234
235     @Test
236     public void testValidYang10BitsWithUnknownStatements() throws Exception {
237         final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar10-valid.yang");
238         assertNotNull(schemaContext);
239     }
240
241     @Test
242     public void testInvalidYang10RestrictedBits() {
243         final ReactorException ex = assertThrows(ReactorException.class,
244             () -> StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar10-invalid.yang"));
245         final Throwable cause = ex.getCause();
246         assertThat(cause, instanceOf(SourceException.class));
247         assertThat(cause.getMessage(), startsWith("Restricted bits type is not allowed in YANG version 1 [at "));
248     }
249
250     @Test
251     public void testInvalidYang10RestrictedBits2() {
252         final ReactorException ex = assertThrows(ReactorException.class,
253             () -> StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar10-invalid-2.yang"));
254         final Throwable cause = ex.getCause();
255         assertThat(cause, instanceOf(SourceException.class));
256         assertThat(cause.getMessage(), startsWith("Restricted bits type is not allowed in YANG version 1 [at "));
257     }
258
259     private static EnumPair createEnumPair(final String name, final int value) {
260         return EnumPairBuilder.create(name, value).build();
261     }
262
263     private static void assertContainsEnums(final List<EnumPair> enumList, final EnumPair... enumPairs) {
264         for (final EnumPair enumPair : enumPairs) {
265             assertTrue(enumList.contains(enumPair));
266         }
267     }
268
269     private static Bit createBit(final String name, final long position) {
270         return BitBuilder.create(name, Uint32.valueOf(position)).build();
271     }
272
273     private static void assertContainsBits(final Collection<? extends Bit> bitList, final Bit... bits) {
274         for (final Bit bit : bits) {
275             assertTrue(bitList.contains(bit));
276         }
277     }
278 }