From db2d6f91b55a28d5da6e6b362295b1d412d8d363 Mon Sep 17 00:00:00 2001 From: Jakub Toth Date: Thu, 9 Mar 2017 11:31:08 +0100 Subject: [PATCH] Bug 7759 - TEST - Getter of BA object fails to construct class instance Change-Id: Idfb3ceabe6808bcd9c421d189566f680f8f0077f Signed-off-by: Jakub Toth --- .../BindingToNormalizedNodeCodecTest.java | 110 ++++++++++++++++++ .../src/test/resources/test.yang | 26 +++++ .../urn/test/rev170101/ContVlanIdBuilder.java | 20 ++++ .../src/main/yang/test.yang | 26 +++++ 4 files changed, 182 insertions(+) create mode 100644 binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodecTest.java create mode 100644 binding/mdsal-binding-dom-adapter/src/test/resources/test.yang create mode 100644 binding/mdsal-binding-test-model/src/main/java/org/opendaylight/yang/gen/v1/urn/test/rev170101/ContVlanIdBuilder.java create mode 100644 binding/mdsal-binding-test-model/src/main/yang/test.yang diff --git a/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodecTest.java b/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodecTest.java new file mode 100644 index 0000000000..8eec43e8bf --- /dev/null +++ b/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodecTest.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017 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.mdsal.binding.dom.adapter; + +import java.io.File; +import java.io.FileNotFoundException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator; +import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry; +import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy; +import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext; +import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; +import org.opendaylight.yangtools.yang.data.impl.schema.Builders; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; +import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl; +import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream; +import javassist.ClassPool; + +public class BindingToNormalizedNodeCodecTest { + + @Test + public void fromNormalizedNodeTest() throws Exception { + final StreamWriterGenerator serializerGenerator = + new StreamWriterGenerator(JavassistUtils.forClassPool(ClassPool.getDefault())); + final BindingNormalizedNodeCodecRegistry codecRegistry = + new BindingNormalizedNodeCodecRegistry(serializerGenerator); + final GeneratedClassLoadingStrategy classLoadingStrategy = + GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(); + final SchemaContext schemaCtx = loadSchemaContext("/"); + final BindingRuntimeContext ctx = BindingRuntimeContext.create(classLoadingStrategy, schemaCtx); + codecRegistry.onBindingRuntimeContextUpdated(ctx); + final BindingToNormalizedNodeCodec codec = + new BindingToNormalizedNodeCodec(classLoadingStrategy, codecRegistry); + + final DataSchemaNode dataChildByName = + schemaCtx.getDataChildByName(QName.create("urn:test", "2017-01-01", "cont")); + final DataSchemaNode leaf = ((ContainerSchemaNode) dataChildByName) + .getDataChildByName(QName.create("urn:test", "2017-01-01", "vlan-id")); + + final DataContainerChild child = Builders.leafBuilder((LeafSchemaNode) leaf).withValue(2420).build(); + final ContainerNode data = + Builders.containerBuilder((ContainerSchemaNode) dataChildByName).withChild(child).build(); + + + final List pathArgs = new ArrayList<>(); + pathArgs.add(NodeIdentifier.create(QName.create("urn:test", "2017-01-01", "cont"))); + + final YangInstanceIdentifier path = YangInstanceIdentifier.create(pathArgs); + final Entry, DataObject> fromNormalizedNode = codec.fromNormalizedNode(path, data); + + final DataObject value = fromNormalizedNode.getValue(); + Assert.assertNotNull(value); + Assert.assertEquals("Cont", value.getImplementedInterface().getSimpleName()); + final Object objs[] = {}; + final Object invoked = value.getImplementedInterface().getDeclaredMethods()[0].invoke(value, objs); + final Field declaredField = invoked.getClass().getDeclaredField("_id"); + declaredField.setAccessible(true); + final Object id = declaredField.get(invoked); + final Field val = id.getClass().getDeclaredField("_value"); + val.setAccessible(true); + Assert.assertEquals(2420, val.get(id)); + } + + public static SchemaContext loadSchemaContext(final String... yangPath) + throws FileNotFoundException, ReactorException { + final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + + for (int i = 0; i < yangPath.length; i++) { + final String path = yangPath[i]; + final String pathToFile = BindingToNormalizedNodeCodecTest.class.getResource(path).getPath(); + final File testDir = new File(pathToFile); + final String[] fileList = testDir.list(); + if (fileList == null) { + throw new FileNotFoundException(pathToFile); + } + for (int j = 0; j < fileList.length; j++) { + final String fileName = fileList[j]; + final File file = new File(testDir, fileName); + if (file.isDirectory() == false) { + reactor.addSource(new YangStatementSourceImpl(new NamedFileInputStream(file, file.getPath()))); + } + } + } + return reactor.buildEffective(); + } +} diff --git a/binding/mdsal-binding-dom-adapter/src/test/resources/test.yang b/binding/mdsal-binding-dom-adapter/src/test/resources/test.yang new file mode 100644 index 0000000000..fec593d110 --- /dev/null +++ b/binding/mdsal-binding-dom-adapter/src/test/resources/test.yang @@ -0,0 +1,26 @@ +module test{ + namespace "urn:test"; + prefix tst; + + revision 2017-01-01; + + typedef id { + type uint16 { + range "1..4094"; + } + } + + container cont{ + leaf vlan-id { + type union { + type id; + type enumeration { + enum "any" { + value 4096; + } + } + } + mandatory true; + } + } +} \ No newline at end of file diff --git a/binding/mdsal-binding-test-model/src/main/java/org/opendaylight/yang/gen/v1/urn/test/rev170101/ContVlanIdBuilder.java b/binding/mdsal-binding-test-model/src/main/java/org/opendaylight/yang/gen/v1/urn/test/rev170101/ContVlanIdBuilder.java new file mode 100644 index 0000000000..bc623e1b00 --- /dev/null +++ b/binding/mdsal-binding-test-model/src/main/java/org/opendaylight/yang/gen/v1/urn/test/rev170101/ContVlanIdBuilder.java @@ -0,0 +1,20 @@ +package org.opendaylight.yang.gen.v1.urn.test.rev170101; +import org.opendaylight.yang.gen.v1.urn.test.rev170101.Cont.VlanId; + + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class ContVlanIdBuilder { + + public static VlanId getDefaultInstance(java.lang.String defaultValue) { + throw new java.lang.UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/binding/mdsal-binding-test-model/src/main/yang/test.yang b/binding/mdsal-binding-test-model/src/main/yang/test.yang new file mode 100644 index 0000000000..6a95fdd524 --- /dev/null +++ b/binding/mdsal-binding-test-model/src/main/yang/test.yang @@ -0,0 +1,26 @@ +module test{ + namespace "urn:test"; + prefix tst; + + revision 2017-01-01; + + typedef id { + type uint16 { + range "1..4094"; + } + } + + container cont{ + leaf vlan-id { + type union { + type id; + type enumeration { + enum "any" { + value 4096; + } + } + } + mandatory true; + } + } +} -- 2.36.6