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.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;
39 public class Bug6887Test {
42 public void testRestrictedEnumeration() throws Exception {
43 final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo.yang");
44 assertNotNull(schemaContext);
46 final Module foo = schemaContext.findModule("foo", Revision.valueOf("2017-01-26")).get();
47 final LeafSchemaNode myEnumerationLeaf = (LeafSchemaNode) foo.getDataChildByName(
48 QName.create(foo.getQNameModule(), "my-enumeration-leaf"));
49 assertNotNull(myEnumerationLeaf);
51 EnumTypeDefinition enumerationType = (EnumTypeDefinition) myEnumerationLeaf.getType();
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);
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);
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);
71 final LeafSchemaNode myEnumerationLeaf2 = (LeafSchemaNode) foo.getDataChildByName(
72 QName.create(foo.getQNameModule(), "my-enumeration-leaf-2"));
73 assertNotNull(myEnumerationLeaf2);
75 enumerationType = (EnumTypeDefinition) myEnumerationLeaf2.getType();
76 enums = enumerationType.getValues();
77 assertEquals(3, enums.size());
78 assertContainsEnums(enums, yellowEnum, redEnum, blackEnum);
82 public void testInvalidRestrictedEnumeration() throws Exception {
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."));
95 public void testInvalidRestrictedEnumeration2() throws Exception {
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."));
108 public void testInvalidRestrictedEnumeration3() throws Exception {
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."));
122 public void testInvalidRestrictedEnumeration4() throws Exception {
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."));
136 public void testValidYang10EnumerationWithUnknownStatements() throws Exception {
137 final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6887/foo10-valid.yang");
138 assertNotNull(schemaContext);
142 public void testInvalidYang10RestrictedEnumeration() throws Exception {
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."));
155 public void testInvalidYang10RestrictedEnumeration2() throws Exception {
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."));
168 public void testRestrictedBits() throws Exception {
169 final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar.yang");
170 assertNotNull(schemaContext);
172 final Module bar = schemaContext.findModule("bar", Revision.valueOf("2017-02-02")).get();
173 final LeafSchemaNode myBitsLeaf = (LeafSchemaNode) bar.getDataChildByName(
174 QName.create(bar.getQNameModule(), "my-bits-leaf"));
175 assertNotNull(myBitsLeaf);
177 BitsTypeDefinition bitsType = (BitsTypeDefinition) myBitsLeaf.getType();
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);
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);
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);
211 final LeafSchemaNode myBitsLeaf2 = (LeafSchemaNode) bar.getDataChildByName(
212 QName.create(bar.getQNameModule(), "my-bits-leaf-2"));
213 assertNotNull(myBitsLeaf2);
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);
228 public void testInvalidRestrictedBits() throws Exception {
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."));
241 public void testInvalidRestrictedBits2() throws Exception {
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."));
254 public void testInvalidRestrictedBits3() throws Exception {
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."));
267 public void testInvalidRestrictedBits4() throws Exception {
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."));
280 public void testValidYang10BitsWithUnknownStatements() throws Exception {
281 final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6887/bar10-valid.yang");
282 assertNotNull(schemaContext);
286 public void testInvalidYang10RestrictedBits() throws Exception {
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."));
298 public void testInvalidYang10RestrictedBits2() throws Exception {
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."));
309 private static EnumPair createEnumPair(final String name, final int value) {
310 return EnumPairBuilder.create(name, value).build();
313 private static void assertContainsEnums(final List<EnumPair> enumList, final EnumPair... enumPairs) {
314 for (final EnumPair enumPair : enumPairs) {
315 assertTrue(enumList.contains(enumPair));
319 private static Bit createBit(final SchemaPath path, final long position) {
320 return BitBuilder.create(path, position).build();
323 private static void assertContainsBits(final List<Bit> bitList, final Bit... bits) {
324 for (final Bit bit : bits) {
325 assertTrue(bitList.contains(bit));
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);