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 org.junit.After;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
25 import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
26 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
27 import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
28 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
30 public class YangParserNegativeTest {
32 @SuppressWarnings("checkstyle:regexpSinglelineJava")
33 private final PrintStream stdout = System.out;
34 private final ByteArrayOutputStream output = new ByteArrayOutputStream();
35 private String testLog;
38 public void setUp() throws UnsupportedEncodingException {
39 System.setOut(new PrintStream(output, true, "UTF-8"));
43 public void cleanUp() {
44 System.setOut(stdout);
48 public void testInvalidImport() throws IOException, ReactorException, YangSyntaxErrorException {
50 TestUtils.loadModuleResources(getClass(), "/negative-scenario/testfile1.yang");
51 fail("SomeModifiersUnresolvedException should be thrown");
52 } catch (final SomeModifiersUnresolvedException e) {
53 final Throwable rootCause = Throwables.getRootCause(e);
54 assertThat(rootCause, isA(InferenceException.class));
55 assertThat(rootCause.getMessage(), startsWith("Imported module"));
56 assertThat(rootCause.getMessage(), containsString("was not found."));
61 public void testTypeNotFound() throws IOException, ReactorException, YangSyntaxErrorException {
63 TestUtils.loadModuleResources(getClass(), "/negative-scenario/testfile2.yang");
64 fail("InferenceException should be thrown");
65 } catch (final SomeModifiersUnresolvedException e) {
66 final Throwable rootCause = Throwables.getRootCause(e);
67 assertThat(rootCause, isA(InferenceException.class));
68 assertThat(rootCause.getMessage(),
69 startsWith("Type [(urn:simple.types.data.demo?revision=2013-02-27)int-ext] was not found."));
74 public void testInvalidAugmentTarget() throws IOException, ReactorException, YangSyntaxErrorException {
76 TestUtils.loadModuleResources(getClass(),
77 "/negative-scenario/testfile0.yang",
78 "/negative-scenario/testfile3.yang");
79 fail("SomeModifiersUnresolvedException should be thrown");
80 } catch (final SomeModifiersUnresolvedException e) {
81 final Throwable rootCause = Throwables.getRootCause(e);
82 assertThat(rootCause, isA(InferenceException.class));
83 assertThat(rootCause.getMessage(), startsWith(
84 "Augment target 'Absolute{qnames=(urn:simple.container.demo)unknown}' not found"));
89 public void testInvalidRefine() throws IOException, ReactorException, YangSyntaxErrorException {
91 TestUtils.loadModuleResources(getClass(), "/negative-scenario/testfile4.yang");
92 fail("ReactorException should be thrown");
93 } catch (final ReactorException e) {
94 assertThat(e.getCause().getMessage(), containsString("Error in module 'test4' in the refine of uses "
95 + "'Descendant{qnames=(urn:simple.container.demo)node}': can not perform refine of 'PRESENCE' for"
96 + " the target 'LEAF_LIST'."));
101 public void testInvalidLength() throws IOException, YangSyntaxErrorException {
103 TestUtils.loadModuleResources(getClass(), "/negative-scenario/testfile5.yang");
104 fail("ReactorException should be thrown");
105 } catch (final ReactorException e) {
106 assertThat(e.getCause().getMessage(), containsString("Invalid length constraint [4..10]"));
111 public void testInvalidRange() throws IOException, YangSyntaxErrorException {
113 TestUtils.loadModuleResources(getClass(), "/negative-scenario/testfile6.yang");
114 fail("ReactorException should be thrown");
115 } catch (final ReactorException e) {
116 assertThat(e.getCause().getMessage(), startsWith("Invalid range constraint: [[5..20]]"));
121 public void testDuplicateContainer() throws IOException, YangSyntaxErrorException {
123 TestUtils.loadModuleResources(getClass(), "/negative-scenario/duplicity/container.yang");
124 fail("SourceException should be thrown");
125 } catch (final ReactorException e) {
126 final String expected = "Error in module 'container': cannot add '(urn:simple.container.demo)foo'. "
127 + "Node name collision: '(urn:simple.container.demo)foo' already declared";
128 assertThat(e.getCause().getMessage(), containsString(expected));
133 public void testDuplicateContainerList() throws IOException, YangSyntaxErrorException {
135 TestUtils.loadModuleResources(getClass(), "/negative-scenario/duplicity/container-list.yang");
136 fail("SourceException should be thrown");
137 } catch (final ReactorException e) {
138 final String expected = "Error in module 'container-list': cannot add '(urn:simple.container.demo)foo'. "
139 + "Node name collision: '(urn:simple.container.demo)foo' already declared";
140 assertThat(e.getCause().getMessage(), containsString(expected));
145 public void testDuplicateContainerLeaf() throws IOException, YangSyntaxErrorException {
147 TestUtils.loadModuleResources(getClass(), "/negative-scenario/duplicity/container-leaf.yang");
148 fail("SourceException should be thrown");
149 } catch (final ReactorException e) {
150 final String expected = "Error in module 'container-leaf': cannot add '(urn:simple.container.demo)foo'. "
151 + "Node name collision: '(urn:simple.container.demo)foo' already declared";
152 assertThat(e.getCause().getMessage(), containsString(expected));
157 public void testDuplicateTypedef() throws IOException, YangSyntaxErrorException {
159 TestUtils.loadModuleResources(getClass(), "/negative-scenario/duplicity/typedef.yang");
160 fail("SourceException should be thrown");
161 } catch (final ReactorException e) {
162 assertThat(e.getCause().getMessage(), startsWith(
163 "Duplicate name for typedef (urn:simple.container.demo)int-ext [at"));
168 public void testDuplicityInAugmentTarget1() throws IOException, ReactorException, YangSyntaxErrorException {
169 TestUtils.loadModuleResources(getClass(),
170 "/negative-scenario/duplicity/augment0.yang",
171 "/negative-scenario/duplicity/augment1.yang");
172 testLog = output.toString();
173 assertThat(testLog, containsString(
174 "An augment cannot add node named 'id' because this name is already used in target"));
178 public void testDuplicityInAugmentTarget2() throws IOException, ReactorException, YangSyntaxErrorException {
180 TestUtils.loadModuleResources(getClass(),
181 "/negative-scenario/duplicity/augment0.yang",
182 "/negative-scenario/duplicity/augment2.yang");
183 fail("Duplicate leaf not detected");
184 } catch (SomeModifiersUnresolvedException e) {
185 final Throwable rootCause = Throwables.getRootCause(e);
186 assertThat(rootCause, isA(SourceException.class));
187 assertThat(rootCause.getMessage(), containsString("Cannot add schema tree child with name "
188 + "(urn:simple.augment2.demo?revision=2014-06-02)delta, a conflicting child already exists"));
194 public void testMandatoryInAugment() throws IOException, ReactorException, YangSyntaxErrorException {
195 TestUtils.loadModuleResources(getClass(),
196 "/negative-scenario/testfile8.yang",
197 "/negative-scenario/testfile7.yang");
198 testLog = output.toString();
199 assertThat(testLog, containsString(
200 "An augment cannot add node 'linkleaf' because it is mandatory and in module different than target"));
204 public void testInvalidListKeyDefinition() throws IOException, YangSyntaxErrorException {
206 TestUtils.loadModuleResources(getClass(), "/negative-scenario/invalid-list-key-def.yang");
207 fail("InferenceException should be thrown");
208 } catch (final ReactorException e) {
209 assertThat(e.getCause().getMessage(),
210 startsWith("Key 'rib-id' misses node 'rib-id' in list '(invalid:list:key:def)application-map'"));