Fix failure source not being reported 50/100950/1
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 3 May 2022 17:27:59 +0000 (19:27 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 3 May 2022 19:03:43 +0000 (21:03 +0200)
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 <robert.varga@pantheon.tech>
(cherry picked from commit 6dd19d2f87b3391b95d8087a3ff025c5414fd4e9)

parser/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/AssembleSources.java
parser/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/AbstractSchemaRepositoryTest.java [new file with mode: 0644]
parser/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/SchemaContextFactoryDeviationsTest.java
parser/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/YT1428Test.java [new file with mode: 0644]
parser/yang-parser-impl/src/test/resources/yt1428/deviate.yang [new file with mode: 0644]
parser/yang-parser-impl/src/test/resources/yt1428/orig.yang [new file with mode: 0644]

index 2b04e8e4ddc8fa0b637f40e180a09401816dcecc..29880fa62ab97715ed6a9cfcf43e78f5b3ac1531 100644 (file)
@@ -90,6 +90,11 @@ final class AssembleSources implements AsyncFunction<List<IRSchemaSource>, Effec
         try {
             schemaContext = parser.buildEffectiveModel();
         } catch (final YangParserException e) {
+            final Throwable cause = e.getCause();
+            if (cause instanceof ReactorException) {
+                throw new SchemaResolutionException("Failed to resolve required models",
+                    ((ReactorException) cause).getSourceIdentifier(), e);
+            }
             throw new SchemaResolutionException("Failed to resolve required models", e);
         }
 
@@ -105,4 +110,4 @@ final class AssembleSources implements AsyncFunction<List<IRSchemaSource>, 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 (file)
index 0000000..16db94d
--- /dev/null
@@ -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<EffectiveModelContext> createSchemaContext(
+            final SetMultimap<QNameModule, QNameModule> 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<IRSchemaSource> 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);
+    }
+}
index 82a85c0d04fcfa60c5713bff1790c614cab7c318..fb035a41b834ffa809305282f1761cb78f114976 100644 (file)
@@ -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<IRSchemaSource> getImmediateYangSourceProviderFromResource(
-            final String resourceName) throws Exception {
-        final YangTextSchemaSource yangSource = YangTextSchemaSource.forResource(resourceName);
-        return SettableSchemaProvider.createImmediate(TextToIRTransformer.transformText(yangSource),
-                IRSchemaSource.class);
-    }
-
-    private static ListenableFuture<EffectiveModelContext> createSchemaContext(
-            final SetMultimap<QNameModule, QNameModule> modulesWithSupportedDeviations, final String... resources)
-            throws Exception {
-        final SharedSchemaRepository sharedSchemaRepository = new SharedSchemaRepository(
-                "shared-schema-repo-with-deviations-test");
-
-        final Collection<SourceIdentifier> requiredSources = new ArrayList<>();
-        for (final String resource : resources) {
-            final SettableSchemaProvider<IRSchemaSource> 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 (file)
index 0000000..89f7ff7
--- /dev/null
@@ -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 (file)
index 0000000..aaae9cd
--- /dev/null
@@ -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 (file)
index 0000000..9ec16dc
--- /dev/null
@@ -0,0 +1,10 @@
+module orig {
+  namespace "urn:orig";
+  prefix orig;
+
+  container foo {
+    leaf bar {
+      type string;
+    }
+  }
+}