Bug 6410: Fixed initialization of typedefs in rpc 67/44067/2
authorIgor Foltin <ifoltin@cisco.com>
Tue, 16 Aug 2016 08:10:32 +0000 (10:10 +0200)
committerRobert Varga <nite@hq.sk>
Tue, 16 Aug 2016 15:54:20 +0000 (15:54 +0000)
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.

Change-Id: Ic9a02727ffb4b6e6c798360e2266dc99d77c79e7
Signed-off-by: Igor Foltin <ifoltin@cisco.com>
(cherry picked from commit 8b7928e1337c94936434af5b4d9844804d2720de)

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 0e640571202ebea0b240bfdd197a9dd5b4b1b649..ecd26e5401c66804a24e80dada70dd47e6ce870e 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..0ab758b
--- /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;
+
+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() {
+        try {
+            final SchemaContext schemaContext = StmtTestUtils.parseYangSources(
+                    new YangStatementSourceImpl("/bugs/bug6410/bar.yang", false));
+            fail("A ReactorException should have been thrown.");
+        } catch (ReactorException ex) {
+            assertTrue(ex.getCause() instanceof SourceException);
+            assertTrue(ex.getCause().getMessage().contains("Node name collision"));
+        }
+    }
+}
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