From 6dd19d2f87b3391b95d8087a3ff025c5414fd4e9 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 3 May 2022 19:27:59 +0200 Subject: [PATCH] Fix failure source not being reported When the parser fails with a well-known exception, extract the SourceIdentifier of the failed YANG source. JIRA: YANGTOOLS-1428 Change-Id: Ib40b01a977131ce1d244be5bd4e67c39e04ab626 Signed-off-by: Robert Varga --- .../yang/parser/repo/AssembleSources.java | 5 +- .../repo/AbstractSchemaRepositoryTest.java | 52 +++++++++++++++++++ .../SchemaContextFactoryDeviationsTest.java | 37 +------------ .../yang/parser/repo/YT1428Test.java | 29 +++++++++++ .../src/test/resources/yt1428/deviate.yang | 12 +++++ .../src/test/resources/yt1428/orig.yang | 10 ++++ 6 files changed, 108 insertions(+), 37 deletions(-) create mode 100644 parser/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/AbstractSchemaRepositoryTest.java create mode 100644 parser/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/YT1428Test.java create mode 100644 parser/yang-parser-impl/src/test/resources/yt1428/deviate.yang create mode 100644 parser/yang-parser-impl/src/test/resources/yt1428/orig.yang diff --git a/parser/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/AssembleSources.java b/parser/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/AssembleSources.java index 2b04e8e4dd..9405cb891c 100644 --- a/parser/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/AssembleSources.java +++ b/parser/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/AssembleSources.java @@ -90,6 +90,9 @@ final class AssembleSources implements AsyncFunction, Effec try { schemaContext = parser.buildEffectiveModel(); } catch (final YangParserException e) { + if (e.getCause() instanceof ReactorException re) { + throw new SchemaResolutionException("Failed to resolve required models", re.getSourceIdentifier(), e); + } throw new SchemaResolutionException("Failed to resolve required models", e); } @@ -105,4 +108,4 @@ final class AssembleSources implements AsyncFunction, Effec return SemVerSourceIdentifier.create(identifier.getName(), identifier.getRevision(), semver); } -} \ No newline at end of file +} diff --git a/parser/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/AbstractSchemaRepositoryTest.java b/parser/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/AbstractSchemaRepositoryTest.java new file mode 100644 index 0000000000..16db94dd6d --- /dev/null +++ b/parser/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/AbstractSchemaRepositoryTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.parser.repo; + +import com.google.common.collect.SetMultimap; +import com.google.common.util.concurrent.ListenableFuture; +import java.io.IOException; +import java.util.Arrays; +import java.util.stream.Collectors; +import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; +import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactoryConfiguration; +import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.opendaylight.yangtools.yang.parser.api.YangSyntaxErrorException; +import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource; +import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransformer; + +public abstract class AbstractSchemaRepositoryTest { + static ListenableFuture createSchemaContext( + final SetMultimap modulesWithSupportedDeviations, final String... resources) { + final var sharedSchemaRepository = new SharedSchemaRepository(); + final var requiredSources = Arrays.stream(resources) + .map(resource -> { + final var yangSource = assertYangTextResource(resource); + yangSource.register(sharedSchemaRepository); + yangSource.setResult(); + return yangSource.getId(); + }) + .collect(Collectors.toUnmodifiableList()); + + return sharedSchemaRepository + .createEffectiveModelContextFactory(SchemaContextFactoryConfiguration.builder() + .setModulesDeviatedByModules(modulesWithSupportedDeviations) + .build()) + .createEffectiveModelContext(requiredSources); + } + + private static SettableSchemaProvider assertYangTextResource(final String resourceName) { + final IRSchemaSource yangSource; + try { + yangSource = TextToIRTransformer.transformText(YangTextSchemaSource.forResource(resourceName)); + } catch (YangSyntaxErrorException | IOException e) { + throw new AssertionError("Failed to parse " + resourceName, e); + } + return SettableSchemaProvider.createImmediate(yangSource, IRSchemaSource.class); + } +} diff --git a/parser/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/SchemaContextFactoryDeviationsTest.java b/parser/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/SchemaContextFactoryDeviationsTest.java index 82a85c0d04..fb035a41b8 100644 --- a/parser/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/SchemaContextFactoryDeviationsTest.java +++ b/parser/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/SchemaContextFactoryDeviationsTest.java @@ -20,8 +20,6 @@ import com.google.common.base.Throwables; import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.SetMultimap; import com.google.common.util.concurrent.ListenableFuture; -import java.util.ArrayList; -import java.util.Collection; import java.util.Optional; import java.util.concurrent.ExecutionException; import org.junit.Test; @@ -30,14 +28,9 @@ import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.common.Revision; import org.opendaylight.yangtools.yang.common.XMLNamespace; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; -import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactoryConfiguration; -import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; -import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; -import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource; -import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransformer; import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException; -public class SchemaContextFactoryDeviationsTest { +public class SchemaContextFactoryDeviationsTest extends AbstractSchemaRepositoryTest { private static final String FOO = "/bug9195/foo.yang"; private static final String BAR = "/bug9195/bar.yang"; private static final String BAZ = "/bug9195/baz.yang"; @@ -127,32 +120,4 @@ public class SchemaContextFactoryDeviationsTest { private static void assertPresent(final EffectiveModelContext schemaContext, final QName qname) { assertNotEquals(Optional.empty(), schemaContext.findDataTreeChild(qname)); } - - private static SettableSchemaProvider getImmediateYangSourceProviderFromResource( - final String resourceName) throws Exception { - final YangTextSchemaSource yangSource = YangTextSchemaSource.forResource(resourceName); - return SettableSchemaProvider.createImmediate(TextToIRTransformer.transformText(yangSource), - IRSchemaSource.class); - } - - private static ListenableFuture createSchemaContext( - final SetMultimap modulesWithSupportedDeviations, final String... resources) - throws Exception { - final SharedSchemaRepository sharedSchemaRepository = new SharedSchemaRepository( - "shared-schema-repo-with-deviations-test"); - - final Collection requiredSources = new ArrayList<>(); - for (final String resource : resources) { - final SettableSchemaProvider yangSource = getImmediateYangSourceProviderFromResource( - resource); - yangSource.register(sharedSchemaRepository); - yangSource.setResult(); - requiredSources.add(yangSource.getId()); - } - - final SchemaContextFactoryConfiguration config = SchemaContextFactoryConfiguration.builder() - .setModulesDeviatedByModules(modulesWithSupportedDeviations).build(); - return sharedSchemaRepository.createEffectiveModelContextFactory(config).createEffectiveModelContext( - requiredSources); - } } diff --git a/parser/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/YT1428Test.java b/parser/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/YT1428Test.java new file mode 100644 index 0000000000..89f7ff7998 --- /dev/null +++ b/parser/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/YT1428Test.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.parser.repo; + +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +import com.google.common.util.concurrent.Futures; +import java.util.concurrent.ExecutionException; +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier; +import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException; + +public class YT1428Test extends AbstractSchemaRepositoryTest { + @Test + public void testDeviateSourceReported() throws Exception { + final var future = createSchemaContext(null, "/yt1428/orig.yang", "/yt1428/deviate.yang"); + final var cause = assertThrows(ExecutionException.class, () -> Futures.getDone(future)).getCause(); + assertThat(cause, instanceOf(SchemaResolutionException.class)); + assertEquals(RevisionSourceIdentifier.create("deviate"), ((SchemaResolutionException) cause).getFailedSource()); + } +} diff --git a/parser/yang-parser-impl/src/test/resources/yt1428/deviate.yang b/parser/yang-parser-impl/src/test/resources/yt1428/deviate.yang new file mode 100644 index 0000000000..aaae9cd820 --- /dev/null +++ b/parser/yang-parser-impl/src/test/resources/yt1428/deviate.yang @@ -0,0 +1,12 @@ +module deviate { + namespace "urn:deviate"; + prefix dev; + + import orig { + prefix orig; + } + + deviation "/orig:foo/orig:bar/orig:baz" { + deviate not-supported; + } +} diff --git a/parser/yang-parser-impl/src/test/resources/yt1428/orig.yang b/parser/yang-parser-impl/src/test/resources/yt1428/orig.yang new file mode 100644 index 0000000000..9ec16dc485 --- /dev/null +++ b/parser/yang-parser-impl/src/test/resources/yt1428/orig.yang @@ -0,0 +1,10 @@ +module orig { + namespace "urn:orig"; + prefix orig; + + container foo { + leaf bar { + type string; + } + } +} -- 2.36.6