BUG-4989: Introduce RIBSupport test abstraction 33/39933/9
authorClaudio D. Gasparini <cgaspari@cisco.com>
Tue, 7 Jun 2016 10:03:32 +0000 (12:03 +0200)
committerMilos Fabian <milfabia@cisco.com>
Mon, 13 Jun 2016 06:58:15 +0000 (06:58 +0000)
Introduce RIBSupport test abstraction to do a wide test over Ribsupport on extension.

Change-Id: I6865a7f04a537c19ba88bfff99725b85f0493cdf
Signed-off-by: Claudio D. Gasparini <cgaspari@cisco.com>
bgp/rib-spi/pom.xml
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/AbstractRIBSupport.java
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/MultiPathAbstractRIBSupport.java
bgp/rib-spi/src/test/java/org/opendaylight/protocol/bgp/rib/spi/AbstractRIBSupportTest.java

index 63691b6f01bd9cd87f8730711c8a658cd750d1ca..c9b64dc6f0d1c895af1d551c348dee8e55df0cfa 100644 (file)
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-util</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-broker-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
index 3618db5e4f9e09b3ee137486e45d9c53743d516c..d82c24e0a7591d16f2531edc24c8d04c1c3b3442 100644 (file)
@@ -133,7 +133,7 @@ public abstract class AbstractRIBSupport implements RIBSupport {
         return this.emptyRoutes;
     }
 
-    protected final QName routeQName() {
+    public final QName routeQName() {
         return this.routeQname;
     }
 
@@ -141,6 +141,14 @@ public abstract class AbstractRIBSupport implements RIBSupport {
         return this.routesListIdentifier;
     }
 
+    public final Class<? extends AddressFamily> getAfi() {
+        return afiClass;
+    }
+
+    public final Class<? extends SubsequentAddressFamily> getSafi() {
+        return safiClass;
+    }
+
     /**
      * Build MpReachNlri object from DOM representation.
      *
@@ -150,8 +158,8 @@ public abstract class AbstractRIBSupport implements RIBSupport {
      */
     private MpReachNlri buildReach(final Collection<MapEntryNode> routes, final CNextHop hop) {
         final MpReachNlriBuilder mb = new MpReachNlriBuilder();
-        mb.setAfi(this.afiClass);
-        mb.setSafi(this.safiClass);
+        mb.setAfi(this.getAfi());
+        mb.setSafi(this.getSafi());
         mb.setCNextHop(hop);
         mb.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(buildDestination(routes)).build());
         return mb.build();
@@ -165,8 +173,8 @@ public abstract class AbstractRIBSupport implements RIBSupport {
      */
     private MpUnreachNlri buildUnreach(final Collection<MapEntryNode> routes) {
         final MpUnreachNlriBuilder mb = new MpUnreachNlriBuilder();
-        mb.setAfi(this.afiClass);
-        mb.setSafi(this.safiClass);
+        mb.setAfi(this.getAfi());
+        mb.setSafi(this.getSafi());
         mb.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(buildWithdrawnDestination(routes)).build());
         return mb.build();
     }
@@ -352,9 +360,9 @@ public abstract class AbstractRIBSupport implements RIBSupport {
         }
     }
 
-    private static class DeleteRoute implements ApplyRoute {
+    private static final class DeleteRoute implements ApplyRoute {
         @Override
-        public void apply(final DOMDataWriteTransaction tx, final YangInstanceIdentifier base, final NodeIdentifierWithPredicates routeKey,
+        public final void apply(final DOMDataWriteTransaction tx, final YangInstanceIdentifier base, final NodeIdentifierWithPredicates routeKey,
             final DataContainerNode<?> route, final ContainerNode attributes) {
             tx.delete(LogicalDatastoreType.OPERATIONAL, base.node(routeKey));
         }
index 3abebeed011530d6fc715f912c2b278749d28317..3cf305ece593f14d794ab3824bbd2cebe990c1c5 100644 (file)
@@ -53,15 +53,15 @@ public abstract class MultiPathAbstractRIBSupport extends AbstractRIBSupport {
         this.pathIdNid = new NodeIdentifier(this.pathIdQname);
     }
 
-    protected final NodeIdentifier routePathIdNid() {
+    public final NodeIdentifier routePathIdNid() {
         return this.pathIdNid;
     }
 
-    protected QName pathIdQName() {
+    protected final QName pathIdQName() {
         return this.pathIdQname;
     }
 
-    protected QName routeKeyQName() {
+    public final QName routeKeyQName() {
         return this.routeKeyQname;
     }
 
@@ -81,7 +81,7 @@ public abstract class MultiPathAbstractRIBSupport extends AbstractRIBSupport {
     }
 
     @Override
-    public PathArgument createRouteKeyPathArgument(PathArgument routeKey) {
+    public final PathArgument createRouteKeyPathArgument(final PathArgument routeKey) {
         final ImmutableMap<QName, Object> keyValues = ImmutableMap.of(routeKeyQName(), PathIdUtil.getObjectKey(routeKey, routeKeyQName()));
         return new NodeIdentifierWithPredicates(routeQName(), keyValues);
     }
index db73b21989dfd68a91736149681334a7893a9943..ce0a8883447418888e9b8abf2c009c3fe429f0e7 100644 (file)
 /*
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ * 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.protocol.bgp.rib.spi;
 
-/**
- * TODO: Remove, instead use Common Rib Support test
- */
-public class AbstractRIBSupportTest {
-   /* private final ContainerNode ipv4p = ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(Ipv4Prefixes.QNAME)).build();
-    private final ContainerNode destination = ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(DestinationIpv4.QNAME)).addChild(this.ipv4p).build();
-    private final ChoiceNode choiceNode = ImmutableChoiceNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(DestinationType.QNAME)).addChild(this.destination).build();
-    static ContainerNode dest;
-
-    private final RIBSupport testSupport = new AbstractRIBSupport(Ipv4RoutesCase.class, Ipv4Routes.class, Ipv4Route.class,
-        Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class, DestinationIpv4.QNAME) {
-        @Override
-        public ImmutableCollection<Class<? extends DataObject>> cacheableAttributeObjects() {
-            return null;
-        }
-
-        @Override
-        public ImmutableCollection<Class<? extends DataObject>> cacheableNlriObjects() {
-            return null;
-        }
-
-        @Nonnull
-        @Override
-        protected DestinationType buildDestination(@Nonnull final Collection<MapEntryNode> routes) {
-            return null;
-        }
-
-        @Nonnull
-        @Override
-        protected DestinationType buildWithdrawnDestination(@Nonnull final Collection<MapEntryNode> routes) {
-            return null;
-        }
-
-        @Override
-        protected void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath, final ContainerNode destination, final ContainerNode attributes, final ApplyRoute applyFunction) {
-
-        }
-
-        @Override
-        public boolean isComplexRoute() {
-            return false;
-        }
-    };
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import javassist.ClassPool;
+import org.junit.After;
+import org.junit.Before;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Update;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Attributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.DestinationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRib;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.Rib;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.RibKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.LocRib;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
+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.impl.ModuleInfoBackedContext;
+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.binding.util.BindingReflections;
+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.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public abstract class AbstractRIBSupportTest {
+    protected final static long PATH_ID = 1;
+    protected static final Attributes ATTRIBUTES = new AttributesBuilder().build();
+    private static final InstanceIdentifier<LocRib> RIB = InstanceIdentifier.builder(BgpRib.class).child(Rib.class, new RibKey(new RibId("rib"))).child(LocRib.class).build();
+    private static final InstanceIdentifier<Attributes> ATTRIBUTES_IID = InstanceIdentifier.create(Update.class).child(Attributes.class);
+    private static final InstanceIdentifier<MpUnreachNlri> MP_UNREACH_IID = ATTRIBUTES_IID.augmentation(Attributes2.class).child(MpUnreachNlri.class);
+    private static final InstanceIdentifier<MpReachNlri> MP_REACH_IID = ATTRIBUTES_IID.augmentation(Attributes1.class).child(MpReachNlri.class);
 
     @Mock
-    private DOMDataWriteTransaction tx;
+    protected DOMDataWriteTransaction tx;
+    protected List<InstanceIdentifier<?>> deletedRoutes;
+    protected List<Map.Entry<InstanceIdentifier<?>, DataObject>> insertedRoutes;
+
+    private BindingToNormalizedNodeCodec mappingService;
+    private AbstractRIBSupport abstractRIBSupport;
+    private ModuleInfoBackedContext moduleInfoBackedContext;
+
+    protected final void setUpTestCustomizer(final AbstractRIBSupport ribSupport) throws Exception {
+        this.abstractRIBSupport = ribSupport;
+        this.moduleInfoBackedContext.registerModuleInfo(BindingReflections.getModuleInfo(this.abstractRIBSupport.routesContainerClass()));
+        this.mappingService.onGlobalContextUpdated(this.moduleInfoBackedContext.tryToCreateSchemaContext().get());
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        Mockito.doAnswer(new Answer<Object>() {
+            @Override
+            public Object answer(final InvocationOnMock invocation) throws Throwable {
+                final Object[] args = invocation.getArguments();
+                AbstractRIBSupportTest.this.insertedRoutes.add(mappingService.fromNormalizedNode((YangInstanceIdentifier) args[1], (NormalizedNode<?, ?>) args[2]));
+                return args[1];
+            }
+        }).when(this.tx).put(Mockito.any(LogicalDatastoreType.class), Mockito.any(YangInstanceIdentifier.class), Mockito.any(NormalizedNode.class));
+
+        Mockito.doAnswer(new Answer<Object>() {
+            @Override
+            public Object answer(final InvocationOnMock invocation) throws Throwable {
+                final Object[] args = invocation.getArguments();
+                AbstractRIBSupportTest.this.deletedRoutes.add(mappingService.fromYangInstanceIdentifier((YangInstanceIdentifier) args[1]));
+                return args[1];
+            }
+        }).when(this.tx).delete(Mockito.any(LogicalDatastoreType.class), Mockito.any(YangInstanceIdentifier.class));
+        this.deletedRoutes = new ArrayList<>();
+        this.insertedRoutes = new ArrayList<>();
+
+        this.mappingService = new BindingToNormalizedNodeCodec(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(),
+            new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator.create(JavassistUtils.forClassPool(ClassPool.getDefault()))));
+        this.moduleInfoBackedContext = ModuleInfoBackedContext.create();
+    }
+
+    protected final ContainerNode createNlriWithDrawnRoute(final DestinationType destUnreach) {
+        final MpUnreachNlri mpReach = new MpUnreachNlriBuilder().setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(destUnreach).build()).build();
+        final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> result = this.mappingService.toNormalizedNode(MP_UNREACH_IID, mpReach);
+        return (ContainerNode) result.getValue();
+    }
+
+    protected final ContainerNode createNlriAdvertiseRoute(final DestinationType destReach) {
+        final MpReachNlri mpReach = new MpReachNlriBuilder().setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(destReach).build()).build();
+        final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> result = this.mappingService.toNormalizedNode(MP_REACH_IID, mpReach);
+        return (ContainerNode) result.getValue();
+    }
+
+    protected final ContainerNode createAttributes() {
+        return (ContainerNode) this.mappingService.toNormalizedNode(ATTRIBUTES_IID, ATTRIBUTES).getValue();
+    }
 
-    @Test
-    public void testRouteAttributesIdentifier() {
-        assertEquals(new NodeIdentifier(QName.create(Ipv4Routes.QNAME, Attributes.QNAME.getLocalName())), this.testSupport.routeAttributesIdentifier());
+    protected final ChoiceNode createRoutes(final Routes routes) {
+        final Tables tables = new TablesBuilder().setKey(getTablesKey()).setRoutes(routes).build();
+        return (ChoiceNode) ((MapEntryNode) this.mappingService.toNormalizedNode(tablesIId(), tables).getValue())
+            .getChild(new NodeIdentifier(BindingReflections.findQName(Routes.class))).get();
     }
 
-    @Test
-    public void testChangedRoutes() {
-        final QName TEST_QNAME = QName.create("urn:opendaylight:params:xml:ns:yang:bgp-inet:test", "2015-03-05", "test");
-        final YangInstanceIdentifier writePath = YangInstanceIdentifier.of(TEST_QNAME);
+    private TablesKey getTablesKey() {
+        return new TablesKey(this.abstractRIBSupport.getAfi(), this.abstractRIBSupport.getSafi());
+    }
 
-        final YangInstanceIdentifier.NodeWithValue nodeIdentifier = new YangInstanceIdentifier.NodeWithValue(Ipv4Route.QNAME, "route");
-        final LeafSetEntryNode<Object> routeEntry = ImmutableLeafSetEntryNodeBuilder.create().withNodeIdentifier(nodeIdentifier).withValue("route").build();
-        final LeafSetNode<Object> route = ImmutableLeafSetNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(Ipv4Route.QNAME)).withChild(routeEntry).build();
-        ContainerNode routes = ImmutableContainerNodeBuilder.create().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(Ipv4Routes.QNAME))
-            .withChild(route).build();
+    private InstanceIdentifier<Tables> tablesIId() {
+        return RIB.child(Tables.class, getTablesKey());
+    }
 
-        final ContainerNode routesContainer = ImmutableContainerNodeBuilder.create().addChild(routes).
-            withNodeIdentifier(new NodeIdentifier(TEST_QNAME)).build();
-        final DataTreeCandidate candidate = DataTreeCandidates.fromNormalizedNode(writePath, routesContainer);
-        final Collection<DataTreeCandidateNode> output = this.testSupport.changedRoutes(candidate.getRootNode());
+    private InstanceIdentifier<DataObject> routesIId() {
+        final InstanceIdentifier<Tables> tables = tablesIId();
+        return tables.child((Class) this.abstractRIBSupport.routesContainerClass());
+    }
 
-        Assert.assertFalse(output.isEmpty());
-        assertEquals(nodeIdentifier.toString(), output.iterator().next().getIdentifier().toString());
+    protected final YangInstanceIdentifier getTablePath() {
+        final InstanceIdentifier<Tables> tables = tablesIId();
+        return this.mappingService.toYangInstanceIdentifier(tables);
     }
 
+    protected final YangInstanceIdentifier getRoutePath() {
+        final InstanceIdentifier<DataObject> routesIId = routesIId();
+        return this.mappingService.toYangInstanceIdentifier(routesIId).node(BindingReflections.findQName(this.abstractRIBSupport.routesListClass()));
+    }
 
-    @Test
-    public void testRoutePath() {
-        final YangInstanceIdentifier routePath = YangInstanceIdentifier.of(Routes.QNAME);
-        final NodeIdentifier routeId = new NodeIdentifier(Ipv4Route.QNAME);
-        final String result = "/(urn:opendaylight:params:xml:ns:yang:bgp-rib?revision=2013-09-25)routes/(urn:opendaylight:params:xml:ns:yang:bgp-inet?revision=2015-03-05)ipv4-routes/ipv4-route/ipv4-route";
-        assertEquals(result, this.testSupport.routePath(routePath, routeId).toString());
+    protected final Collection<MapEntryNode> createRoutes(final DataObject routes) {
+        Preconditions.checkArgument(routes.getImplementedInterface().equals(this.abstractRIBSupport.routesContainerClass()));
+        final InstanceIdentifier<DataObject> routesIId = routesIId();
+        final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNode = this.mappingService.toNormalizedNode(routesIId, routes);
+        return ((MapNode) ((ContainerNode) normalizedNode.getValue())
+            .getChild(new NodeIdentifier(BindingReflections.findQName(this.abstractRIBSupport.routesListClass()))).get()).getValue();
     }
 
-    @Test
-    public void testDeleteRoutes() {
-        final ContainerNode advertised = ImmutableContainerNodeBuilder.create().addChild(this.choiceNode).withNodeIdentifier(new NodeIdentifier(WithdrawnRoutes.QNAME)).build();
-        final ContainerNode nlri = ImmutableContainerNodeBuilder.create().addChild(advertised).withNodeIdentifier(new NodeIdentifier(Nlri.QNAME)).build();
-        this.testSupport.deleteRoutes(null, null, nlri);
-        assertEquals(dest, this.destination);
+    protected final NodeIdentifierWithPredicates createRouteNIWP(final DataObject routes) {
+        final Collection<MapEntryNode> map = createRoutes(routes);
+        return (Iterables.getOnlyElement(map)).getIdentifier();
     }
 
-    @Test
-    public void testPutRoutes() {
-        final ContainerNode advertised = ImmutableContainerNodeBuilder.create().addChild(this.choiceNode).withNodeIdentifier(new NodeIdentifier(AdvertizedRoutes.QNAME)).build();
-        final ContainerNode nlri = ImmutableContainerNodeBuilder.create().addChild(advertised).withNodeIdentifier(new NodeIdentifier(Nlri.QNAME)).build();
-        this.testSupport.putRoutes(null, null, nlri, null);
-        assertEquals(dest, this.destination);
-    }*/
-}
+    @After
+    public final void tearDown() throws InterruptedException, ExecutionException {
+        this.mappingService.close();
+    }
+}
\ No newline at end of file