X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-binding-broker%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fbinding%2Ftest%2FRuntimeCodeGeneratorTest.java;h=9ba65339710b50c5e3a1e453fa5b5ff3805484f3;hp=95ac22c6b37c31dbd7bbb65fafd35f5e78e3b5d6;hb=04da6ab70e5cefc3df74fa2f49d20085e5e76cc0;hpb=e41b96adc85177b252b3a47816f9f9f6b5571362 diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java index 95ac22c6b3..9ba6533971 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java @@ -1,44 +1,57 @@ +/* + * Copyright (c) 2014 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.controller.sal.binding.test; -import static org.junit.Assert.*; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.util.ArrayList; +import java.util.List; import javassist.ClassPool; import org.junit.Before; import org.junit.Test; - -import static org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper.*; - +import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter; +import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable; import org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator; -import org.opendaylight.controller.sal.binding.spi.RpcRouter; -import org.opendaylight.controller.sal.binding.spi.RpcRoutingTable; +import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory; +import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker; +import org.opendaylight.controller.sal.binding.test.mock.BarListener; +import org.opendaylight.controller.sal.binding.test.mock.BarUpdate; +import org.opendaylight.controller.sal.binding.test.mock.FlowDelete; +import org.opendaylight.controller.sal.binding.test.mock.FooListener; import org.opendaylight.controller.sal.binding.test.mock.FooService; +import org.opendaylight.controller.sal.binding.test.mock.FooUpdate; import org.opendaylight.controller.sal.binding.test.mock.ReferencableObject; import org.opendaylight.controller.sal.binding.test.mock.ReferencableObjectKey; import org.opendaylight.controller.sal.binding.test.mock.SimpleInput; import org.opendaylight.yangtools.yang.binding.Augmentation; import org.opendaylight.yangtools.yang.binding.BaseIdentity; +import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; - -import static org.mockito.Mockito.*; - public class RuntimeCodeGeneratorTest { private RuntimeCodeGenerator codeGenerator; + private NotificationInvokerFactory invokerFactory; - @Before public void initialize() { this.codeGenerator = new RuntimeCodeGenerator(ClassPool.getDefault()); + this.invokerFactory = codeGenerator.getInvokerFactory(); } - + @Test public void testGenerateDirectProxy() { FooService product = codeGenerator.getDirectProxyFor(FooService.class); @@ -47,98 +60,157 @@ public class RuntimeCodeGeneratorTest { @Test public void testGenerateRouter() throws Exception { - RpcRouter product = codeGenerator.getRouterFor(FooService.class); + RpcRouter product = codeGenerator.getRouterFor(FooService.class,"test"); assertNotNull(product); assertNotNull(product.getInvocationProxy()); - - assertEquals("2 fields should be generated.",2,product.getInvocationProxy().getClass().getFields().length); - + + assertEquals("2 fields should be generated.", 2, product.getInvocationProxy().getClass().getFields().length); + verifyRouting(product); } - private void verifyRouting(RpcRouter product) { - assertNotNull("Routing table should be initialized",product.getRoutingTable(BaseIdentity.class)); - + @Test + public void testInvoker() throws Exception { + + FooListenerImpl fooListener = new FooListenerImpl(); + + NotificationInvoker invokerFoo = invokerFactory.invokerFor(fooListener); + + + assertSame(fooListener,invokerFoo.getDelegate()); + assertNotNull(invokerFoo.getSupportedNotifications()); + assertEquals(1, invokerFoo.getSupportedNotifications().size()); + assertNotNull(invokerFoo.getInvocationProxy()); + + FooUpdateImpl fooOne = new FooUpdateImpl(); + invokerFoo.getInvocationProxy().onNotification(fooOne); + + assertEquals(1, fooListener.receivedFoos.size()); + assertSame(fooOne, fooListener.receivedFoos.get(0)); + + CompositeListenerImpl composite = new CompositeListenerImpl(); + + NotificationInvoker invokerComposite = invokerFactory.invokerFor(composite); + + assertNotNull(invokerComposite.getSupportedNotifications()); + assertEquals(3, invokerComposite.getSupportedNotifications().size()); + assertNotNull(invokerComposite.getInvocationProxy()); + + invokerComposite.getInvocationProxy().onNotification(fooOne); + + assertEquals(1, composite.receivedFoos.size()); + assertSame(fooOne, composite.receivedFoos.get(0)); + + assertEquals(0, composite.receivedBars.size()); + + BarUpdateImpl barOne = new BarUpdateImpl(); + + invokerComposite.getInvocationProxy().onNotification(barOne); + + assertEquals(1, composite.receivedFoos.size()); + assertEquals(1, composite.receivedBars.size()); + assertSame(barOne, composite.receivedBars.get(0)); + + } + + private void verifyRouting(final RpcRouter product) { + assertNotNull("Routing table should be initialized", product.getRoutingTable(BaseIdentity.class)); + RpcRoutingTable routingTable = product.getRoutingTable(BaseIdentity.class); - + int servicesCount = 2; int instancesPerService = 3; - - InstanceIdentifier[][] identifiers = identifiers(servicesCount,instancesPerService); - FooService service[] = new FooService[] { - mock(FooService.class, "Instance 0"), - mock(FooService.class,"Instance 1") - }; - - for(int i = 0;i[][] identifiers = identifiers(servicesCount, instancesPerService); + FooService service[] = new FooService[] { mock(FooService.class, "Instance 0"), + mock(FooService.class, "Instance 1") }; + + for (int i = 0; i < service.length; i++) { for (InstanceIdentifier instance : identifiers[i]) { routingTable.updateRoute(instance, service[i]); } } - - assertEquals("All instances should be registered.", servicesCount*instancesPerService, routingTable.getRoutes().size()); - - SimpleInput[] instance_0_input = new SimpleInputImpl[] { - new SimpleInputImpl(identifiers[0][0]), - new SimpleInputImpl(identifiers[0][1]), - new SimpleInputImpl(identifiers[0][2]) - }; - - SimpleInput[] instance_1_input = new SimpleInputImpl[] { - new SimpleInputImpl(identifiers[1][0]), - new SimpleInputImpl(identifiers[1][1]), - new SimpleInputImpl(identifiers[1][2]) - }; - + + assertEquals("All instances should be registered.", servicesCount * instancesPerService, routingTable + .getRoutes().size()); + + SimpleInput[] instance_0_input = new SimpleInputImpl[] { new SimpleInputImpl(identifiers[0][0]), + new SimpleInputImpl(identifiers[0][1]), new SimpleInputImpl(identifiers[0][2]) }; + + SimpleInput[] instance_1_input = new SimpleInputImpl[] { new SimpleInputImpl(identifiers[1][0]), + new SimpleInputImpl(identifiers[1][1]), new SimpleInputImpl(identifiers[1][2]) }; + // We test sending mock messages - + product.getInvocationProxy().simple(instance_0_input[0]); verify(service[0]).simple(instance_0_input[0]); - + product.getInvocationProxy().simple(instance_0_input[1]); product.getInvocationProxy().simple(instance_0_input[2]); - + verify(service[0]).simple(instance_0_input[1]); verify(service[0]).simple(instance_0_input[2]); - - + product.getInvocationProxy().simple(instance_1_input[0]); - + // We should have call to instance 1 verify(service[1]).simple(instance_1_input[0]); + + /* + * Generated RPC service should throw illegalArgumentException + * with message if rpc input is null. + */ + try { + product.getInvocationProxy().simple(null); + fail("Generated RPC router should throw IllegalArgumentException on null input"); + } catch (IllegalArgumentException e){ + assertNotNull(e.getMessage()); + } + + + /* + * Generated RPC service should throw illegalArgumentException + * with message if rpc route is null. + */ + try { + SimpleInput withoutValue = new SimpleInputImpl(null); + product.getInvocationProxy().simple(withoutValue); + fail("Generated RPC router should throw IllegalArgumentException on null value for route"); + } catch (IllegalArgumentException e){ + assertNotNull(e.getMessage()); + } + } - private InstanceIdentifier[][] identifiers(int serviceSize, int instancesPerService) { + private InstanceIdentifier[][] identifiers(final int serviceSize, final int instancesPerService) { InstanceIdentifier[][] ret = new InstanceIdentifier[serviceSize][]; int service = 0; - for (int i = 0;i[] instanceIdentifiers = new InstanceIdentifier[instancesPerService]; ret[i] = instanceIdentifiers; - for(int id = 0;id referencableIdentifier(int i) { - ReferencableObjectKey key = new ReferencableObjectKey(i); - IdentifiableItem pathArg = new IdentifiableItem<>(ReferencableObject.class,key); - return new InstanceIdentifier(Arrays.asList(pathArg), ReferencableObject.class); + private InstanceIdentifier referencableIdentifier(final int i) { + return InstanceIdentifier.builder(ReferencableObject.class, new ReferencableObjectKey(i)).build(); } private static class SimpleInputImpl implements SimpleInput { private final InstanceIdentifier identifier; - public SimpleInputImpl(InstanceIdentifier _identifier) { + public SimpleInputImpl(final InstanceIdentifier _identifier) { this.identifier = _identifier; } @Override - public > E getAugmentation(Class augmentationType) { + public > E getAugmentation(final Class augmentationType) { return null; } @@ -152,4 +224,51 @@ public class RuntimeCodeGeneratorTest { return SimpleInput.class; } } + + private static class FooUpdateImpl implements FooUpdate { + @Override + public Class getImplementedInterface() { + return FooUpdate.class; + } + } + + private static class BarUpdateImpl implements BarUpdate { + @Override + public Class getImplementedInterface() { + return BarUpdate.class; + } + + @Override + public InstanceIdentifier getInheritedIdentifier() { + return null; + } + } + + private static class FooListenerImpl implements FooListener { + + List receivedFoos = new ArrayList<>(); + + @Override + public void onFooUpdate(final FooUpdate notification) { + receivedFoos.add(notification); + } + + } + + private static class CompositeListenerImpl extends FooListenerImpl implements BarListener { + + List receivedBars = new ArrayList<>(); + List receivedDeletes = new ArrayList<>(); + + @Override + public void onBarUpdate(final BarUpdate notification) { + receivedBars.add(notification); + } + + @Override + public void onFlowDelete(final FlowDelete notification) { + receivedDeletes.add(notification); + } + + } }