Add/improve yang parser error reporting
[yangtools.git] / yang / yang-parser-impl / src / test / java / org / opendaylight / yangtools / yang / stmt / retest / YangParserNegativeTest.java
1 /*
2  * Copyright (c) 2013 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.stmt.retest;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertTrue;
12 import static org.junit.Assert.fail;
13 import java.io.File;
14 import java.io.FileInputStream;
15 import java.io.InputStream;
16 import java.util.ArrayList;
17 import java.util.Arrays;
18 import java.util.List;
19 import org.junit.Test;
20 import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
21 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
22 import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
23 import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
24 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
25 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
26 import org.opendaylight.yangtools.yang.parser.util.YangValidationException;
27 import com.google.common.base.Throwables;
28
29 public class YangParserNegativeTest {
30
31     @Test
32     public void testInvalidImport() throws Exception {
33         File yang = new File(getClass().getResource("/negative-scenario/testfile1.yang").toURI());
34         try {
35             try (InputStream stream = new FileInputStream(yang)) {
36                 TestUtils.loadModule(stream);
37                 fail("SomeModifiersUnresolvedException should be thrown");
38             }
39         } catch (SomeModifiersUnresolvedException e) {
40             Throwable rootCause = Throwables.getRootCause(e);
41             assertTrue(rootCause instanceof InferenceException);
42             assertTrue(rootCause.getMessage().startsWith("Imported module"));
43             assertTrue(rootCause.getMessage().endsWith("was not found."));
44         }
45     }
46
47     @Test
48     public void testTypeNotFound() throws Exception {
49         File yang = new File(getClass().getResource("/negative-scenario/testfile2.yang").toURI());
50         try {
51             try (InputStream stream = new FileInputStream(yang)) {
52                 TestUtils.loadModule(stream);
53                 fail("IllegalArgumentException should be thrown");
54             }
55         } catch (IllegalStateException e) {
56             assertTrue(e.getMessage().startsWith(
57                     "Type '(urn:simple.types.data.demo?revision=2013-02-27)int-ext' was not found"));
58         }
59     }
60
61     @Test
62     public void testInvalidAugmentTarget() throws Exception {
63         File yang1 = new File(getClass().getResource("/negative-scenario/testfile0.yang").toURI());
64         File yang2 = new File(getClass().getResource("/negative-scenario/testfile3.yang").toURI());
65         try {
66             final List<InputStream> streams = new ArrayList<>(2);
67             try (InputStream testFile0 = new FileInputStream(yang1)) {
68                 streams.add(testFile0);
69                 try (InputStream testFile3 = new FileInputStream(yang2)) {
70                     streams.add(testFile3);
71                     assertEquals("Expected loaded files count is 2", 2, streams.size());
72                     TestUtils.loadModules(streams);
73                     fail("SomeModifiersUnresolvedException should be thrown");
74                 }
75             }
76         } catch (SomeModifiersUnresolvedException e) {
77             final Throwable rootCause = Throwables.getRootCause(e);
78             assertTrue(rootCause instanceof InferenceException);
79             assertEquals(
80                     "Augment target not found: Absolute{path=[(urn:simple.container.demo?revision=1970-01-01)unknown]}",
81                     rootCause.getMessage());
82         }
83     }
84
85     @Test
86     public void testInvalidRefine() throws Exception {
87         File yang = new File(getClass().getResource("/negative-scenario/testfile4.yang").toURI());
88         try {
89             try (InputStream stream = new FileInputStream(yang)) {
90                 TestUtils.loadModule(stream);
91                 fail("SourceException should be thrown");
92             }
93         } catch (SourceException e) {
94             assertTrue(e
95                     .getMessage()
96                     .contains(
97                             "Error in module 'test4' in the refine of uses 'Relative{path=[(urn:simple.container.demo?revision=1970-01-01)node]}': can not perform refine of 'PRESENCE' for the target 'LEAF_LIST'."));
98         }
99     }
100
101     @Test
102     public void testInvalidLength() throws Exception {
103         File yang = new File(getClass().getResource("/negative-scenario/testfile5.yang").toURI());
104         try {
105             try (InputStream stream = new FileInputStream(yang)) {
106                 TestUtils.loadModule(stream);
107                 fail("YangParseException should be thrown");
108             }
109         } catch (YangParseException e) {
110             assertTrue(e.getMessage().contains("Invalid length constraint: <4, 10>"));
111         }
112     }
113
114     @Test
115     public void testInvalidRange() throws Exception {
116         File yang = new File(getClass().getResource("/negative-scenario/testfile6.yang").toURI());
117         try {
118             try (InputStream stream = new FileInputStream(yang)) {
119                 TestUtils.loadModule(stream);
120                 fail("Exception should be thrown");
121             }
122         } catch (YangParseException e) {
123             assertTrue(e.getMessage().contains("Invalid range constraint: <5, 20>"));
124         }
125     }
126
127     @Test
128     public void testDuplicateContainer() throws Exception {
129         File yang = new File(getClass().getResource("/negative-scenario/duplicity/container.yang").toURI());
130         try {
131             try (InputStream stream = new FileInputStream(yang)) {
132                 TestUtils.loadModule(stream);
133                 fail("SourceException should be thrown");
134             }
135         } catch (SourceException e) {
136             String expected = "Error in module 'container': can not add '(urn:simple.container.demo?revision=1970-01-01)foo'. Node name collision: '(urn:simple.container.demo?revision=1970-01-01)foo' already declared.";
137             assertEquals(expected, e.getMessage());
138         }
139     }
140
141     @Test
142     public void testDuplicateContainerList() throws Exception {
143         File yang = new File(getClass().getResource("/negative-scenario/duplicity/container-list.yang").toURI());
144         try {
145             try (InputStream stream = new FileInputStream(yang)) {
146                 TestUtils.loadModule(stream);
147                 fail("SourceException should be thrown");
148             }
149         } catch (SourceException e) {
150             String expected = "Error in module 'container-list': can not add '(urn:simple.container.demo?revision=1970-01-01)foo'. Node name collision: '(urn:simple.container.demo?revision=1970-01-01)foo' already declared.";
151             assertEquals(expected, e.getMessage());
152         }
153     }
154
155     @Test
156     public void testDuplicateContainerLeaf() throws Exception {
157         File yang = new File(getClass().getResource("/negative-scenario/duplicity/container-leaf.yang").toURI());
158         try {
159             try (InputStream stream = new FileInputStream(yang)) {
160                 TestUtils.loadModule(stream);
161                 fail("SourceException should be thrown");
162             }
163         } catch (SourceException e) {
164             String expected = "Error in module 'container-leaf': can not add '(urn:simple.container.demo?revision=1970-01-01)foo'. Node name collision: '(urn:simple.container.demo?revision=1970-01-01)foo' already declared.";
165             assertEquals(expected, e.getMessage());
166         }
167     }
168
169     @Test
170     public void testDuplicateTypedef() throws Exception {
171         File yang = new File(getClass().getResource("/negative-scenario/duplicity/typedef.yang").toURI());
172         try {
173             try (InputStream stream = new FileInputStream(yang)) {
174                 TestUtils.loadModule(stream);
175                 fail("IllegalArgumentException should be thrown");
176             }
177         } catch (IllegalArgumentException e) {
178             String expected = "Duplicate name for typedef (urn:simple.container.demo?revision=1970-01-01)int-ext";
179             assertEquals(expected, e.getMessage());
180         }
181     }
182
183     @Test
184     public void testDuplicityInAugmentTarget1() throws Exception {
185         File yang1 = new File(getClass().getResource("/negative-scenario/duplicity/augment0.yang").toURI());
186         File yang2 = new File(getClass().getResource("/negative-scenario/duplicity/augment1.yang").toURI());
187         try {
188             try (InputStream stream1 = new FileInputStream(yang1); InputStream stream2 = new FileInputStream(yang2)) {
189                 TestUtils.loadModules(Arrays.asList(stream1, stream2));
190                 fail("IllegalStateException should be thrown");
191             }
192         } catch (IllegalStateException e) {
193             assertEquals(e.getMessage(),
194                     "An augment cannot add node named 'id' because this name is already used in target");
195         }
196     }
197
198     @Test
199     public void testDuplicityInAugmentTarget2() throws Exception {
200         File yang1 = new File(getClass().getResource("/negative-scenario/duplicity/augment0.yang").toURI());
201         File yang2 = new File(getClass().getResource("/negative-scenario/duplicity/augment2.yang").toURI());
202         try {
203             try (InputStream stream1 = new FileInputStream(yang1); InputStream stream2 = new FileInputStream(yang2)) {
204                 TestUtils.loadModules(Arrays.asList(stream1, stream2));
205                 fail("IllegalStateException should be thrown");
206             }
207         } catch (IllegalStateException e) {
208             assertEquals(e.getMessage(),
209                     "An augment cannot add node named 'delta' because this name is already used in target");
210         }
211     }
212
213     @Test
214     public void testMandatoryInAugment() throws Exception {
215         File yang1 = new File(getClass().getResource("/negative-scenario/testfile8.yang").toURI());
216         File yang2 = new File(getClass().getResource("/negative-scenario/testfile7.yang").toURI());
217         try {
218             try (InputStream stream1 = new FileInputStream(yang1); InputStream stream2 = new FileInputStream(yang2)) {
219                 TestUtils.loadModules(Arrays.asList(stream1, stream2));
220                 fail("IllegalArgumentException should be thrown");
221             }
222         } catch (IllegalArgumentException e) {
223             String expected = "An augment cannot add node 'linkleaf' because it is mandatory and in module different from target";
224             assertEquals(expected, e.getMessage());
225         }
226     }
227
228     @Test
229     public void testWrongDependenciesDir() throws Exception {
230         try {
231             File yangFile = new File(getClass().getResource("/types/custom-types-test@2012-4-4.yang").toURI());
232             File dependenciesDir = new File("/invalid");
233             YangContextParser parser = new YangParserImpl();
234             parser.parseFile(yangFile, dependenciesDir);
235             fail("Exception should be thrown");
236         } catch (IllegalStateException e) {
237             String expected = File.separator + "invalid does not exists";
238             assertEquals(expected, e.getMessage());
239         }
240     }
241
242     @Test
243     public void testWrongDependenciesDir2() throws Exception {
244         try {
245             File yangFile = new File(getClass().getResource("/types/custom-types-test@2012-4-4.yang").toURI());
246             File dependenciesDir = new File(getClass().getResource("/model").toURI());
247             YangContextParser parser = new YangParserImpl();
248             parser.parseFile(yangFile, dependenciesDir);
249             fail("Exception should be thrown");
250         } catch (YangValidationException e) {
251             String expected = "Not existing module imported";
252             assertTrue(e.getMessage().contains(expected));
253         }
254     }
255
256     @Test
257     public void testInvalidListKeyDefinition() throws Exception {
258         File yang1 = new File(getClass().getResource("/negative-scenario/invalid-list-key-def.yang").toURI());
259         try {
260             try (InputStream stream1 = new FileInputStream(yang1)) {
261                 TestUtils.loadModule(stream1);
262                 fail("IllegalArgumentException should be thrown");
263             }
264         } catch (IllegalArgumentException e) {
265             String expected = "Key 'rib-id' misses node 'rib-id' in list '(invalid:list:key:def?revision=1970-01-01)application-map'";
266             assertTrue(e.getMessage().startsWith(expected));
267         }
268     }
269
270 }