2 * Copyright (c) 2016 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
8 package org.opendaylight.yangtools.yang.stmt;
10 import static org.hamcrest.CoreMatchers.containsString;
11 import static org.hamcrest.CoreMatchers.startsWith;
12 import static org.hamcrest.MatcherAssert.assertThat;
13 import static org.hamcrest.Matchers.isA;
14 import static org.junit.Assert.fail;
16 import com.google.common.base.Throwables;
17 import java.io.ByteArrayOutputStream;
18 import java.io.IOException;
19 import java.io.PrintStream;
20 import java.io.UnsupportedEncodingException;
21 import java.nio.charset.StandardCharsets;
22 import org.junit.After;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
26 import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
27 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
28 import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
29 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
31 public class YangParserNegativeTest {
33 @SuppressWarnings("checkstyle:regexpSinglelineJava")
34 private final PrintStream stdout = System.out;
35 private final ByteArrayOutputStream output = new ByteArrayOutputStream();
36 private String testLog;
39 public void setUp() throws UnsupportedEncodingException {
40 System.setOut(new PrintStream(output, true, StandardCharsets.UTF_8));
44 public void cleanUp() {
45 System.setOut(stdout);
49 public void testInvalidImport() throws IOException, ReactorException, YangSyntaxErrorException {
51 TestUtils.loadModuleResources(getClass(), "/negative-scenario/testfile1.yang");
52 fail("SomeModifiersUnresolvedException should be thrown");
53 } catch (final SomeModifiersUnresolvedException e) {
54 final Throwable rootCause = Throwables.getRootCause(e);
55 assertThat(rootCause, isA(InferenceException.class));
56 assertThat(rootCause.getMessage(), startsWith("Imported module"));
57 assertThat(rootCause.getMessage(), containsString("was not found."));
62 public void testTypeNotFound() throws IOException, ReactorException, YangSyntaxErrorException {
64 TestUtils.loadModuleResources(getClass(), "/negative-scenario/testfile2.yang");
65 fail("InferenceException should be thrown");
66 } catch (final SomeModifiersUnresolvedException e) {
67 final Throwable rootCause = Throwables.getRootCause(e);
68 assertThat(rootCause, isA(InferenceException.class));
69 assertThat(rootCause.getMessage(),
70 startsWith("Type [(urn:simple.types.data.demo?revision=2013-02-27)int-ext] was not found."));
75 public void testInvalidAugmentTarget() throws IOException, ReactorException, YangSyntaxErrorException {
77 TestUtils.loadModuleResources(getClass(),
78 "/negative-scenario/testfile0.yang",
79 "/negative-scenario/testfile3.yang");
80 fail("SomeModifiersUnresolvedException should be thrown");
81 } catch (final SomeModifiersUnresolvedException e) {
82 final Throwable rootCause = Throwables.getRootCause(e);
83 assertThat(rootCause, isA(InferenceException.class));
84 assertThat(rootCause.getMessage(), startsWith(
85 "Augment target 'Absolute{qnames=[(urn:simple.container.demo)unknown]}' not found"));
90 public void testInvalidRefine() throws IOException, ReactorException, YangSyntaxErrorException {
92 TestUtils.loadModuleResources(getClass(), "/negative-scenario/testfile4.yang");
93 fail("ReactorException should be thrown");
94 } catch (final ReactorException e) {
95 assertThat(e.getCause().getMessage(), containsString("Error in module 'test4' in the refine of uses "
96 + "'Descendant{qnames=[(urn:simple.container.demo)node]}': can not perform refine of 'PRESENCE' for"
97 + " the target 'LEAF_LIST'."));
102 public void testInvalidLength() throws IOException, YangSyntaxErrorException {
104 TestUtils.loadModuleResources(getClass(), "/negative-scenario/testfile5.yang");
105 fail("ReactorException should be thrown");
106 } catch (final ReactorException e) {
107 assertThat(e.getCause().getMessage(), containsString("Invalid length constraint [4..10]"));
112 public void testInvalidRange() throws IOException, YangSyntaxErrorException {
114 TestUtils.loadModuleResources(getClass(), "/negative-scenario/testfile6.yang");
115 fail("ReactorException should be thrown");
116 } catch (final ReactorException e) {
117 assertThat(e.getCause().getMessage(), startsWith("Invalid range constraint: [[5..20]]"));
122 public void testDuplicateContainer() throws IOException, YangSyntaxErrorException {
124 TestUtils.loadModuleResources(getClass(), "/negative-scenario/duplicity/container.yang");
125 fail("SourceException should be thrown");
126 } catch (final ReactorException e) {
127 final String expected = "Error in module 'container': cannot add '(urn:simple.container.demo)foo'. "
128 + "Node name collision: '(urn:simple.container.demo)foo' already declared";
129 assertThat(e.getCause().getMessage(), containsString(expected));
134 public void testDuplicateContainerList() throws IOException, YangSyntaxErrorException {
136 TestUtils.loadModuleResources(getClass(), "/negative-scenario/duplicity/container-list.yang");
137 fail("SourceException should be thrown");
138 } catch (final ReactorException e) {
139 final String expected = "Error in module 'container-list': cannot add '(urn:simple.container.demo)foo'. "
140 + "Node name collision: '(urn:simple.container.demo)foo' already declared";
141 assertThat(e.getCause().getMessage(), containsString(expected));
146 public void testDuplicateContainerLeaf() throws IOException, YangSyntaxErrorException {
148 TestUtils.loadModuleResources(getClass(), "/negative-scenario/duplicity/container-leaf.yang");
149 fail("SourceException should be thrown");
150 } catch (final ReactorException e) {
151 final String expected = "Error in module 'container-leaf': cannot add '(urn:simple.container.demo)foo'. "
152 + "Node name collision: '(urn:simple.container.demo)foo' already declared";
153 assertThat(e.getCause().getMessage(), containsString(expected));
158 public void testDuplicateTypedef() throws IOException, YangSyntaxErrorException {
160 TestUtils.loadModuleResources(getClass(), "/negative-scenario/duplicity/typedef.yang");
161 fail("SourceException should be thrown");
162 } catch (final ReactorException e) {
163 assertThat(e.getCause().getMessage(), startsWith(
164 "Duplicate name for typedef (urn:simple.container.demo)int-ext [at"));
169 public void testDuplicityInAugmentTarget1() throws IOException, ReactorException, YangSyntaxErrorException {
170 TestUtils.loadModuleResources(getClass(),
171 "/negative-scenario/duplicity/augment0.yang",
172 "/negative-scenario/duplicity/augment1.yang");
173 testLog = output.toString();
174 assertThat(testLog, containsString(
175 "An augment cannot add node named 'id' because this name is already used in target"));
179 public void testDuplicityInAugmentTarget2() throws IOException, ReactorException, YangSyntaxErrorException {
181 TestUtils.loadModuleResources(getClass(),
182 "/negative-scenario/duplicity/augment0.yang",
183 "/negative-scenario/duplicity/augment2.yang");
184 fail("Duplicate leaf not detected");
185 } catch (SomeModifiersUnresolvedException e) {
186 final Throwable rootCause = Throwables.getRootCause(e);
187 assertThat(rootCause, isA(SourceException.class));
188 assertThat(rootCause.getMessage(), containsString("Cannot add schema tree child with name "
189 + "(urn:simple.augment2.demo?revision=2014-06-02)delta, a conflicting child already exists"));
195 public void testMandatoryInAugment() throws IOException, ReactorException, YangSyntaxErrorException {
196 TestUtils.loadModuleResources(getClass(),
197 "/negative-scenario/testfile8.yang",
198 "/negative-scenario/testfile7.yang");
199 testLog = output.toString();
200 assertThat(testLog, containsString(
201 "An augment cannot add node 'linkleaf' because it is mandatory and in module different than target"));
205 public void testInvalidListKeyDefinition() throws IOException, YangSyntaxErrorException {
207 TestUtils.loadModuleResources(getClass(), "/negative-scenario/invalid-list-key-def.yang");
208 fail("InferenceException should be thrown");
209 } catch (final ReactorException e) {
210 assertThat(e.getCause().getMessage(),
211 startsWith("Key 'rib-id' misses node 'rib-id' in list '(invalid:list:key:def)application-map'"));