Bug 6410: Fixed initialization of typedefs in rpc 82/45982/1
authorIgor Foltin <ifoltin@cisco.com>
Tue, 16 Aug 2016 08:10:32 +0000 (10:10 +0200)
committerIgor Foltin <ifoltin@cisco.com>
Wed, 21 Sep 2016 14:23:21 +0000 (16:23 +0200)
In the constructor of RpcEffectiveStatementImpl we initialize substatements
of an rpc statment. However, in the for loop we are incorrectly trying to
find type substatements instead of typedef substatements.

Typedef substatements in RpcEffectiveStatementImpl are now initialized correctly.

This patch is a manual cherry-pick of the following patch:
git.opendaylight.org/gerrit/#/c/44036/

Change-Id: Ic9a02727ffb4b6e6c798360e2266dc99d77c79e7
Signed-off-by: Igor Foltin <ifoltin@cisco.com>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RpcEffectiveStatementImpl.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6410Test.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug6410/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug6410/foo.yang [new file with mode: 0644]

index 187c593838177ccd21ba20a59d5e77d245804100..478a18d8ef697b401df8b7498b1d7a17ead8e1b0 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 import com.google.common.collect.ImmutableSet;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Objects;
 import java.util.Set;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -35,19 +36,24 @@ public class RpcEffectiveStatementImpl extends AbstractEffectiveSchemaNode<RpcSt
         // initSubstatements
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
         Set<GroupingDefinition> groupingsInit = new HashSet<>();
-        Set<TypeDefinition<?>> typeDefinitionsInit = new HashSet<>();
+        Set<TypeDefinition<?>> mutableTypeDefinitions = new LinkedHashSet<>();
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof GroupingDefinition) {
                 GroupingDefinition groupingDefinition = (GroupingDefinition) effectiveStatement;
                 groupingsInit.add(groupingDefinition);
             }
-            if (effectiveStatement instanceof TypeDefinition) {
-                TypeDefinition<?> typeDefinition = (TypeDefinition<?>) effectiveStatement;
-                typeDefinitionsInit.add(typeDefinition);
+            if (effectiveStatement instanceof TypeDefEffectiveStatementImpl) {
+                TypeDefEffectiveStatementImpl typeDef = (TypeDefEffectiveStatementImpl) effectiveStatement;
+                TypeDefinition<?> type = typeDef.getTypeDefinition();
+                if (!mutableTypeDefinitions.contains(type)) {
+                    mutableTypeDefinitions.add(type);
+                } else {
+                    throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement);
+                }
             }
         }
         this.groupings = ImmutableSet.copyOf(groupingsInit);
-        this.typeDefinitions = ImmutableSet.copyOf(typeDefinitionsInit);
+        this.typeDefinitions = ImmutableSet.copyOf(mutableTypeDefinitions);
     }
 
     @Override
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6410Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6410Test.java
new file mode 100644 (file)
index 0000000..e67d31d
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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 java.util.Set;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
+import org.opendaylight.yangtools.yang.stmt.test.StmtTestUtils;
+
+public class Bug6410Test {
+
+    @Test
+    public void testTypedefsInRpc() throws ReactorException {
+        final SchemaContext schemaContext = StmtTestUtils.parseYangSources(
+                new YangStatementSourceImpl("/bugs/bug6410/foo.yang", false));
+
+        final Set<Module> modules = schemaContext.getModules();
+        assertEquals(1, modules.size());
+        final Module module = modules.iterator().next();
+
+        final Set<RpcDefinition> rpcs = module.getRpcs();
+        assertEquals(1, rpcs.size());
+        final RpcDefinition rpc = rpcs.iterator().next();
+
+        final Set<TypeDefinition<?>> typeDefs = rpc.getTypeDefinitions();
+        assertEquals(2, typeDefs.size());
+    }
+
+    @Test
+    public void shouldFailOnDuplicateTypedefs() throws ReactorException {
+        try {
+            final SchemaContext schemaContext = StmtTestUtils.parseYangSources(
+                    new YangStatementSourceImpl("/bugs/bug6410/bar.yang", false));
+            fail("A SourceException should have been thrown.");
+        } catch (SourceException ex) {
+            assertTrue(ex.getMessage().contains("Node name collision"));
+        }
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug6410/bar.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug6410/bar.yang
new file mode 100644 (file)
index 0000000..aff0f9b
--- /dev/null
@@ -0,0 +1,21 @@
+module bar {
+    namespace bar-namespace;
+    prefix bar-prefix;
+
+    revision 2016-08-16;
+
+    rpc test-rpc {
+        typedef test-string-typedef {
+            type string {
+                length "5..15";
+            }
+            default "def-val";
+        }
+        typedef test-string-typedef {
+            type string {
+                range "5..15";
+            }
+            default "def-val";
+        }
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug6410/foo.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug6410/foo.yang
new file mode 100644 (file)
index 0000000..7dccbe1
--- /dev/null
@@ -0,0 +1,21 @@
+module foo {
+    namespace foo-namespace;
+    prefix foo-prefix;
+
+    revision 2016-08-16;
+
+    rpc test-rpc {
+        typedef test-string-typedef {
+            type string {
+                length "5..15";
+            }
+            default "def-val";
+        }
+        typedef test-int-typedef {
+            type int32 {
+                range "10..100";
+            }
+            default 50;
+        }
+    }
+}
\ No newline at end of file