2 * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.yangtools.yang.parser.stmt.rfc7950;
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;
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.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.SchemaPath;
26 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
27 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
28 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
29 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
30 import org.opendaylight.yangtools.yang.model.util.type.BitBuilder;
31 import org.opendaylight.yangtools.yang.model.util.type.EnumPairBuilder;
32 import org.opendaylight.yangtools.yang.model.util.type.InvalidBitDefinitionException;
33 import org.opendaylight.yangtools.yang.model.util.type.InvalidEnumDefinitionException;
34 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
35 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
36 import org.opendaylight.yangtools.yang.stmt.StmtTestUtils;
38 public class Bug6887Test {
41 public void testRestrictedEnumeration() throws Exception {
42 final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo.yang");
43 assertNotNull(schemaContext);
45 final Module foo = schemaContext.findModule("foo", QName.parseRevision("2017-01-26")).get();
46 final LeafSchemaNode myEnumerationLeaf = (LeafSchemaNode) foo.getDataChildByName(
47 QName.create(foo.getQNameModule(), "my-enumeration-leaf"));
48 assertNotNull(myEnumerationLeaf);
50 EnumTypeDefinition enumerationType = (EnumTypeDefinition) myEnumerationLeaf.getType();
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);
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);
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);
70 final LeafSchemaNode myEnumerationLeaf2 = (LeafSchemaNode) foo.getDataChildByName(
71 QName.create(foo.getQNameModule(), "my-enumeration-leaf-2"));
72 assertNotNull(myEnumerationLeaf2);
74 enumerationType = (EnumTypeDefinition) myEnumerationLeaf2.getType();
75 enums = enumerationType.getValues();
76 assertEquals(3, enums.size());
77 assertContainsEnums(enums, yellowEnum, redEnum, blackEnum);
81 public void testInvalidRestrictedEnumeration() throws Exception {
83 StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo-invalid.yang");
84 fail("An exception should have been thrown.");
85 } catch (final ReactorException ex) {
86 final Throwable cause = ex.getCause();
87 assertTrue(cause instanceof SourceException);
88 assertTrue(cause.getMessage().startsWith("Enum 'purple' is not a subset of its base enumeration type "
89 + "(foo?revision=2017-02-02)my-derived-enumeration-type."));
94 public void testInvalidRestrictedEnumeration2() throws Exception {
96 StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo-invalid-2.yang");
97 fail("An exception should have been thrown.");
98 } catch (final ReactorException ex) {
99 final Throwable cause = ex.getCause();
100 assertTrue(cause instanceof InvalidEnumDefinitionException);
101 assertTrue(cause.getMessage().startsWith("Enum 'magenta' is not a subset of its base enumeration type "
102 + "(foo?revision=2017-02-02)my-base-enumeration-type."));
107 public void testInvalidRestrictedEnumeration3() throws Exception {
109 StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo-invalid-3.yang");
110 fail("An exception should have been thrown.");
111 } catch (final ReactorException ex) {
112 final Throwable cause = ex.getCause();
113 assertTrue(cause instanceof InvalidEnumDefinitionException);
114 assertTrue(cause.getMessage().startsWith("Value of enum 'red' must be the same as the value of "
115 + "corresponding enum in the base enumeration type (foo?revision=2017-02-02)"
116 + "my-derived-enumeration-type."));
121 public void testInvalidRestrictedEnumeration4() throws Exception {
123 StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo-invalid-4.yang");
124 fail("An exception should have been thrown.");
125 } catch (final ReactorException ex) {
126 final Throwable cause = ex.getCause();
127 assertTrue(cause instanceof InvalidEnumDefinitionException);
128 assertTrue(cause.getMessage().startsWith("Value of enum 'black' must be the same as the value of "
129 + "corresponding enum in the base enumeration type (foo?revision=2017-02-02)"
130 + "my-base-enumeration-type."));
135 public void testValidYang10EnumerationWithUnknownStatements() throws Exception {
136 final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo10-valid.yang");
137 assertNotNull(schemaContext);
141 public void testInvalidYang10RestrictedEnumeration() throws Exception {
143 StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo10-invalid.yang");
144 fail("An exception should have been thrown.");
145 } catch (final ReactorException ex) {
146 final Throwable cause = ex.getCause();
147 assertTrue(cause instanceof SourceException);
148 assertTrue(cause.getMessage().startsWith(
149 "Restricted enumeration type is allowed only in YANG 1.1 version."));
154 public void testInvalidYang10RestrictedEnumeration2() throws Exception {
156 StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo10-invalid-2.yang");
157 fail("An exception should have been thrown.");
158 } catch (final ReactorException ex) {
159 final Throwable cause = ex.getCause();
160 assertTrue(cause instanceof SourceException);
161 assertTrue(cause.getMessage().startsWith(
162 "Restricted enumeration type is allowed only in YANG 1.1 version."));
167 public void testRestrictedBits() throws Exception {
168 final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar.yang");
169 assertNotNull(schemaContext);
171 final Module bar = schemaContext.findModule("bar", QName.parseRevision("2017-02-02")).get();
172 final LeafSchemaNode myBitsLeaf = (LeafSchemaNode) bar.getDataChildByName(
173 QName.create(bar.getQNameModule(), "my-bits-leaf"));
174 assertNotNull(myBitsLeaf);
176 BitsTypeDefinition bitsType = (BitsTypeDefinition) myBitsLeaf.getType();
178 List<Bit> bits = bitsType.getBits();
179 assertEquals(2, bits.size());
180 Bit bitB = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-bits-leaf",
181 "my-derived-bits-type", "bit-b")), 2);
182 Bit bitC = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-bits-leaf",
183 "my-derived-bits-type", "bit-c")), 3);
184 assertContainsBits(bits, bitB, bitC);
186 bitsType = bitsType.getBaseType();
187 bits = bitsType.getBits();
188 assertEquals(3, bits.size());
189 bitB = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-derived-bits-type",
190 "my-base-bits-type", "bit-b")), 2);
191 bitC = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-derived-bits-type",
192 "my-base-bits-type", "bit-c")), 3);
193 Bit bitD = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-derived-bits-type",
194 "my-base-bits-type", "bit-d")), 4);
195 assertContainsBits(bits, bitB, bitC, bitD);
197 bitsType = bitsType.getBaseType();
198 bits = bitsType.getBits();
199 assertEquals(4, bits.size());
200 final Bit bitA = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-base-bits-type",
201 "bits", "bit-a")), 1);
202 bitB = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-base-bits-type",
203 "bits", "bit-b")), 2);
204 bitC = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-base-bits-type",
205 "bits", "bit-c")), 3);
206 bitD = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-base-bits-type",
207 "bits", "bit-d")), 4);
208 assertContainsBits(bits, bitA, bitB, bitC, bitD);
210 final LeafSchemaNode myBitsLeaf2 = (LeafSchemaNode) bar.getDataChildByName(
211 QName.create(bar.getQNameModule(), "my-bits-leaf-2"));
212 assertNotNull(myBitsLeaf2);
214 bitsType = (BitsTypeDefinition) myBitsLeaf2.getType();
215 bits = bitsType.getBits();
216 assertEquals(3, bits.size());
217 bitB = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-derived-bits-type",
218 "my-base-bits-type", "bit-b")), 2);
219 bitC = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-derived-bits-type",
220 "my-base-bits-type", "bit-c")), 3);
221 bitD = createBit(createSchemaPath(true, bar.getQNameModule(), ImmutableList.of("my-derived-bits-type",
222 "my-base-bits-type", "bit-d")), 4);
223 assertContainsBits(bits, bitB, bitC, bitD);
227 public void testInvalidRestrictedBits() throws Exception {
229 StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar-invalid.yang");
230 fail("An exception should have been thrown.");
231 } catch (final ReactorException ex) {
232 final Throwable cause = ex.getCause();
233 assertTrue(cause instanceof SourceException);
234 assertTrue(cause.getMessage().startsWith("Bit 'bit-w' is not a subset of its base bits type "
235 + "(bar?revision=2017-02-02)my-derived-bits-type."));
240 public void testInvalidRestrictedBits2() throws Exception {
242 StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar-invalid-2.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("Bit 'bit-x' is not a subset of its base bits type "
248 + "(bar?revision=2017-02-02)my-base-bits-type."));
253 public void testInvalidRestrictedBits3() throws Exception {
255 StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar-invalid-3.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-c' must be the same as the position of "
261 + "corresponding bit in the base bits type (bar?revision=2017-02-02)my-derived-bits-type."));
266 public void testInvalidRestrictedBits4() throws Exception {
268 StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar-invalid-4.yang");
269 fail("An exception should have been thrown.");
270 } catch (final ReactorException ex) {
271 final Throwable cause = ex.getCause();
272 assertTrue(cause instanceof InvalidBitDefinitionException);
273 assertTrue(cause.getMessage().startsWith("Position of bit 'bit-d' must be the same as the position of "
274 + "corresponding bit in the base bits type (bar?revision=2017-02-02)my-base-bits-type."));
279 public void testValidYang10BitsWithUnknownStatements() throws Exception {
280 final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar10-valid.yang");
281 assertNotNull(schemaContext);
285 public void testInvalidYang10RestrictedBits() throws Exception {
287 StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar10-invalid.yang");
288 fail("An exception should have been thrown.");
289 } catch (final ReactorException ex) {
290 final Throwable cause = ex.getCause();
291 assertTrue(cause instanceof SourceException);
292 assertTrue(cause.getMessage().startsWith("Restricted bits type is allowed only in YANG 1.1 version."));
297 public void testInvalidYang10RestrictedBits2() throws Exception {
299 StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar10-invalid-2.yang");
300 fail("An exception should have been thrown.");
301 } catch (final ReactorException ex) {
302 final Throwable cause = ex.getCause();
303 assertTrue(cause instanceof SourceException);
304 assertTrue(cause.getMessage().startsWith("Restricted bits type is allowed only in YANG 1.1 version."));
308 private static EnumPair createEnumPair(final String name, final int value) {
309 return EnumPairBuilder.create(name, value).build();
312 private static void assertContainsEnums(final List<EnumPair> enumList, final EnumPair... enumPairs) {
313 for (final EnumPair enumPair : enumPairs) {
314 assertTrue(enumList.contains(enumPair));
318 private static Bit createBit(final SchemaPath path, final long position) {
319 return BitBuilder.create(path, position).build();
322 private static void assertContainsBits(final List<Bit> bitList, final Bit... bits) {
323 for (final Bit bit : bits) {
324 assertTrue(bitList.contains(bit));
328 private static SchemaPath createSchemaPath(final boolean absolute, final QNameModule qnameModule,
329 final Iterable<String> localNames) {
330 return SchemaPath.create(Iterables.transform(localNames,
331 localName -> QName.create(qnameModule, localName)), true);