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