/* * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.yangtools.yang.stmt; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import com.google.common.base.Throwables; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.InputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException; import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException; import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream; public class YangParserNegativeTest { private final PrintStream stdout = System.out; private final ByteArrayOutputStream output = new ByteArrayOutputStream(); private String testLog; @Before public void setUp() throws UnsupportedEncodingException { System.setOut(new PrintStream(output, true, "UTF-8")); } @After public void cleanUp() { System.setOut(stdout); } @Test public void testInvalidImport() throws Exception { final File yang = new File(getClass().getResource("/negative-scenario/testfile1.yang").toURI()); try { try (InputStream stream = new NamedFileInputStream(yang, yang.getPath())) { TestUtils.loadModule(stream); fail("SomeModifiersUnresolvedException should be thrown"); } } catch (final SomeModifiersUnresolvedException e) { final Throwable rootCause = Throwables.getRootCause(e); assertTrue(rootCause instanceof InferenceException); assertTrue(rootCause.getMessage().startsWith("Imported module")); assertTrue(rootCause.getMessage().contains("was not found.")); } } @Test public void testTypeNotFound() throws Exception { final File yang = new File(getClass().getResource("/negative-scenario/testfile2.yang").toURI()); try { try (InputStream stream = new NamedFileInputStream(yang, yang.getPath())) { TestUtils.loadModule(stream); fail("InferenceException should be thrown"); } } catch (final SomeModifiersUnresolvedException e) { final Throwable rootCause = Throwables.getRootCause(e); assertTrue(rootCause instanceof InferenceException); assertTrue(rootCause.getMessage() .startsWith("Type [(urn:simple.types.data.demo?revision=2013-02-27)int-ext] was not found.")); } } @Test public void testInvalidAugmentTarget() throws Exception { final File yang1 = new File(getClass().getResource("/negative-scenario/testfile0.yang").toURI()); final File yang2 = new File(getClass().getResource("/negative-scenario/testfile3.yang").toURI()); try { final List<InputStream> streams = new ArrayList<>(2); try (InputStream testFile0 = new NamedFileInputStream(yang1, yang1.getPath())) { streams.add(testFile0); try (InputStream testFile3 = new NamedFileInputStream(yang2, yang2.getPath())) { streams.add(testFile3); assertEquals("Expected loaded files count is 2", 2, streams.size()); TestUtils.loadModules(streams); fail("SomeModifiersUnresolvedException should be thrown"); } } } catch (final SomeModifiersUnresolvedException e) { final Throwable rootCause = Throwables.getRootCause(e); assertTrue(rootCause instanceof InferenceException); assertTrue(rootCause.getMessage().startsWith( "Augment target 'Absolute{path=[(urn:simple.container.demo?revision=1970-01-01)unknown]}' not found")); } } @Test public void testInvalidRefine() throws Exception { final File yang = new File(getClass().getResource("/negative-scenario/testfile4.yang").toURI()); try { try (InputStream stream = new NamedFileInputStream(yang, yang.getPath())) { TestUtils.loadModule(stream); fail("SourceException should be thrown"); } } catch (final ReactorException e) { assertTrue(e.getCause().getMessage().contains("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'.")); } } @Test public void testInvalidLength() throws Exception { final File yang = new File(getClass().getResource("/negative-scenario/testfile5.yang").toURI()); try { try (InputStream stream = new NamedFileInputStream(yang, yang.getPath())) { TestUtils.loadModule(stream); fail("YangParseException should be thrown"); } } catch (final ReactorException e) { assertTrue(e.getCause().getMessage().contains("Invalid length constraint: <4, 10>")); } } @Test public void testInvalidRange() throws Exception { final File yang = new File(getClass().getResource("/negative-scenario/testfile6.yang").toURI()); try { try (InputStream stream = new NamedFileInputStream(yang, yang.getPath())) { TestUtils.loadModule(stream); fail("Exception should be thrown"); } } catch (final ReactorException e) { assertTrue(e.getCause().getMessage().contains("Invalid range constraint: <5, 20>")); } } @Test public void testDuplicateContainer() throws Exception { final File yang = new File(getClass().getResource("/negative-scenario/duplicity/container.yang").toURI()); try { try (InputStream stream = new NamedFileInputStream(yang, yang.getPath())) { TestUtils.loadModule(stream); fail("SourceException should be thrown"); } } catch (final ReactorException e) { final String expected = "Error in module 'container': cannot add '(urn:simple.container" + ".demo?revision=1970-01-01)foo'. Node name collision: '(urn:simple.container" + ".demo?revision=1970-01-01)foo' already declared"; assertTrue(e.getCause().getMessage().contains(expected)); } } @Test public void testDuplicateContainerList() throws Exception { final File yang = new File(getClass().getResource("/negative-scenario/duplicity/container-list.yang").toURI()); try { try (InputStream stream = new NamedFileInputStream(yang, yang.getPath())) { TestUtils.loadModule(stream); fail("SourceException should be thrown"); } } catch (final ReactorException e) { final String expected = "Error in module 'container-list': cannot add '(urn:simple.container" + ".demo?revision=1970-01-01)foo'. Node name collision: '(urn:simple.container" + ".demo?revision=1970-01-01)foo' already declared"; assertTrue(e.getCause().getMessage().contains(expected)); } } @Test public void testDuplicateContainerLeaf() throws Exception { final File yang = new File(getClass().getResource("/negative-scenario/duplicity/container-leaf.yang").toURI()); try { try (InputStream stream = new NamedFileInputStream(yang, yang.getPath())) { TestUtils.loadModule(stream); fail("SourceException should be thrown"); } } catch (final ReactorException e) { final String expected = "Error in module 'container-leaf': cannot add '(urn:simple.container" + ".demo?revision=1970-01-01)foo'. Node name collision: '(urn:simple.container" + ".demo?revision=1970-01-01)foo' already declared"; assertTrue(e.getCause().getMessage().contains(expected)); } } @Test public void testDuplicateTypedef() throws Exception { final File yang = new File(getClass().getResource("/negative-scenario/duplicity/typedef.yang").toURI()); try { try (InputStream stream = new NamedFileInputStream(yang, yang.getPath())) { TestUtils.loadModule(stream); fail("SourceException should be thrown"); } } catch (final ReactorException e) { assertTrue(e.getCause().getMessage().startsWith( "Duplicate name for typedef (urn:simple.container.demo?revision=1970-01-01)int-ext [at")); } } @Test public void testDuplicityInAugmentTarget1() throws Exception { final File yang1 = new File(getClass().getResource("/negative-scenario/duplicity/augment0.yang").toURI()); final File yang2 = new File(getClass().getResource("/negative-scenario/duplicity/augment1.yang").toURI()); try (InputStream stream1 = new NamedFileInputStream(yang1, yang1.getPath()); InputStream stream2 = new NamedFileInputStream(yang2, yang2.getPath())) { TestUtils.loadModules(Arrays.asList(stream1, stream2)); testLog = output.toString(); assertTrue(testLog.contains("An augment cannot add node named 'id' because this name is already used in target")); } } @Test public void testDuplicityInAugmentTarget2() throws Exception { final File yang1 = new File(getClass().getResource("/negative-scenario/duplicity/augment0.yang").toURI()); final File yang2 = new File(getClass().getResource("/negative-scenario/duplicity/augment2.yang").toURI()); try (InputStream stream1 = new NamedFileInputStream(yang1, yang1.getPath()); InputStream stream2 = new NamedFileInputStream(yang2, yang2.getPath())) { TestUtils.loadModules(Arrays.asList(stream1, stream2)); testLog = output.toString(); assertTrue(testLog.contains("An augment cannot add node named 'delta' because this name is already used in target")); } } @Test public void testMandatoryInAugment() throws Exception { final File yang1 = new File(getClass().getResource("/negative-scenario/testfile8.yang").toURI()); final File yang2 = new File(getClass().getResource("/negative-scenario/testfile7.yang").toURI()); try (InputStream stream1 = new NamedFileInputStream(yang1, yang1.getPath()); InputStream stream2 = new NamedFileInputStream(yang2, yang2.getPath())) { TestUtils.loadModules(Arrays.asList(stream1, stream2)); testLog = output.toString(); assertTrue(testLog.contains( "An augment cannot add node 'linkleaf' because it is mandatory and in module different than target")); } } @Test public void testInvalidListKeyDefinition() throws Exception { final File yang1 = new File(getClass().getResource("/negative-scenario/invalid-list-key-def.yang").toURI()); try { try (InputStream stream1 = new NamedFileInputStream(yang1, yang1.getPath())) { TestUtils.loadModule(stream1); fail("InferenceException should be thrown"); } } catch (final ReactorException e) { final String expected = "Key 'rib-id' misses node 'rib-id' in list '(invalid:list:key:def?revision=1970-01-01)" + "application-map'"; assertTrue(e.getCause().getMessage().startsWith(expected)); } } }