ELAN L2GW Junit Test Cases 42/66242/19
authorYugandhar Reddy Kaku <yugandhar.reddy.kaku@ericsson.com>
Tue, 5 Dec 2017 13:35:12 +0000 (19:05 +0530)
committerVivekanandan Narasimhan <vivek.konnect@gmail.com>
Thu, 12 Apr 2018 09:11:51 +0000 (09:11 +0000)
1. verifyL2gw1Connection
   verify the dpn macs are programed in tor remote ucast
   verify dpn remote broadcast group includes tor endpoint
   verify tor1 mcast group includes dpns
2. verifyL2gwMac1InDpns
   verify tor mac is programed in dpn
3. verifyL2gw2Connection
   verify tor1 mac is programed in tor2
   verify tor1 mcast group includes tor2 tep
4. verifyL2gwMac2InTors
   verify new tor1 mac is programed in tor2
5. verifyL2gwMacDeleteInTors
   verify tor1 mac is deleted from tor2
6. verifyAddDpnAfterL2gwConnection
   verify tor macs are programed in new dpn
7. verifyDeleteDpnAfterL2gwConnection
   verify tor macs are removed from dpn
   verify tor mcast group does not contain deleted dpn
   verify dpn mac is removed from tor
8. verifyDeleteL2gw1Connection
   verify dpn bc group does not contain tor
   verify dpn macs are removed from tor

Change-Id: I648e246079d0c432037a4b6851275e7986ebf753
Signed-off-by: Yugandhar Reddy Kaku <yugandhar.reddy.kaku@ericsson.com>
elanmanager/impl/pom.xml
elanmanager/impl/src/test/java/org/opendaylight/netvirt/elan/l2gw/nodehandlertest/DataProvider.java
elanmanager/impl/src/test/java/org/opendaylight/netvirt/elan/l2gw/nodehandlertest/TestBuilders.java
elanmanager/impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/DpnNodeBuilders.java [new file with mode: 0644]
elanmanager/impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/ElanServiceTest.java
elanmanager/impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/ElanServiceTestBase.java
elanmanager/impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/ElanServiceTestModule.java
elanmanager/impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/L2gwBuilders.java [new file with mode: 0644]
elanmanager/impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/Verifications.java [new file with mode: 0644]
elanmanager/impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/utils/ElanEgressActionsHelper.java

index 02088f0939298f33cd0069fe224a1fdcd312e7d0..8290454e39488fe3d3817b67e9f2017cfe23d4bb 100644 (file)
@@ -57,6 +57,12 @@ this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
             <artifactId>diagstatus-api</artifactId>
             <version>${infrautils.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netvirt</groupId>
+            <artifactId>cache-impl</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.ops4j.pax.cdi</groupId>
             <artifactId>pax-cdi-api</artifactId>
@@ -175,6 +181,12 @@ this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
             <version>${genius.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.infrautils</groupId>
+            <artifactId>metrics-impl-test</artifactId>
+            <version>${infrautils.version}</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.infrautils</groupId>
             <artifactId>inject.guice.testutils</artifactId>
index 7048f331412072933f5940a22ebf98f453dd8df4..3dc741597d2f344cffaad2455b22bb82244a059b 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.netvirt.elan.l2gw.nodehandlertest;
 
+import com.google.common.collect.ImmutableList;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -88,6 +90,10 @@ public final class DataProvider {
         return portNames;
     }
 
+    public static List<String> getPortNameListTor2() {
+        return ImmutableList.of("s4-eth1", "s4-eth2");
+    }
+
     public static String getLogicalSwitchDataD1() {
         return logicalSwitchDataD1;
     }
index 0c0a29c953f339269eca95397bde906a7151a1a9..1c11ad6b0d20ca4854391e36e1deda3f36b9b90d 100644 (file)
@@ -9,9 +9,13 @@ package org.opendaylight.netvirt.elan.l2gw.nodehandlertest;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableList;
+
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.UUID;
+
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
@@ -168,6 +172,13 @@ public final class TestBuilders {
         return managers;
     }
 
+    public static List<Managers> buildManagers1() {
+        ManagersBuilder builder1 = new ManagersBuilder();
+        builder1.setKey(new ManagersKey(new Uri("test")));
+        builder1.setManagerOtherConfigs(Collections.emptyList());
+        return ImmutableList.of(builder1.build());
+    }
+
     public static ManagerOtherConfigs buildOtherConfig(String key, String val) {
         ManagerOtherConfigsBuilder otherConfigsBuilder = new ManagerOtherConfigsBuilder();
         ManagerOtherConfigsKey managerOtherConfigsKey = new ManagerOtherConfigsKey(key);
diff --git a/elanmanager/impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/DpnNodeBuilders.java b/elanmanager/impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/DpnNodeBuilders.java
new file mode 100644 (file)
index 0000000..f353f69
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2017 Ericsson India Global Services Pvt Ltd. 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.netvirt.elanmanager.tests;
+
+import java.math.BigInteger;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public final class DpnNodeBuilders {
+
+    private DpnNodeBuilders() {
+    }
+
+    public static org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
+        buildDpnNode(BigInteger dpnId) {
+
+        org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId nodeId =
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId("openflow:" + dpnId);
+        org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node nodeDpn =
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder().setId(nodeId)
+                        .setKey(new org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes
+                                .NodeKey(nodeId)).build();
+        return nodeDpn;
+    }
+
+    public static InstanceIdentifier<Group> createGroupIid(Group group, BigInteger dpId) {
+        long groupId = group.getGroupId().getValue().longValue();
+        return buildGroupInstanceIdentifier(groupId, buildDpnNode(dpId));
+    }
+
+    public static InstanceIdentifier<Group>
+        buildGroupInstanceIdentifier(long groupId,
+                                     org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
+                                             nodeDpn) {
+        InstanceIdentifier groupInstanceId =
+                InstanceIdentifier.builder(Nodes.class)
+                        .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
+                                nodeDpn.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
+                        new GroupKey(new GroupId(Long.valueOf(groupId)))).build();
+        return groupInstanceId;
+    }
+}
index 0174d4ad4c77a59a4f2ef3164c4d119cf5e82505..c12bf17e2c83110659bc2ec668f261eb06e5b05a 100644 (file)
@@ -7,35 +7,62 @@
  */
 package org.opendaylight.netvirt.elanmanager.tests;
 
+import static java.util.Arrays.asList;
 import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
 
 import com.google.common.base.Optional;
+
+import java.util.List;
 import javax.inject.Inject;
+
+import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.MethodRule;
+import org.mockito.Mockito;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.genius.datastoreutils.testutils.JobCoordinatorTestModule;
 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.genius.testutils.interfacemanager.TunnelInterfaceDetails;
+import org.opendaylight.genius.utils.batching.ResourceBatchingManager;
+import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils;
 import org.opendaylight.infrautils.caches.testutils.CacheModule;
 import org.opendaylight.infrautils.inject.guice.testutils.GuiceRule;
+import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.infrautils.jobcoordinator.internal.JobCoordinatorImpl;
+import org.opendaylight.infrautils.metrics.MetricProvider;
+import org.opendaylight.infrautils.metrics.testimpl.TestMetricProviderImpl;
 import org.opendaylight.infrautils.testutils.LogRule;
 import org.opendaylight.mdsal.binding.testutils.AssertDataObjects;
+import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
+import org.opendaylight.netvirt.elan.cache.ElanInstanceDpnsCache;
 import org.opendaylight.netvirt.elan.evpn.listeners.ElanMacEntryListener;
 import org.opendaylight.netvirt.elan.evpn.listeners.EvpnElanInstanceListener;
 import org.opendaylight.netvirt.elan.evpn.listeners.MacVrfEntryListener;
 import org.opendaylight.netvirt.elan.evpn.utils.EvpnUtils;
+import org.opendaylight.netvirt.elan.internal.ElanDpnInterfaceClusteredListener;
+import org.opendaylight.netvirt.elan.internal.ElanExtnTepConfigListener;
+import org.opendaylight.netvirt.elan.internal.ElanExtnTepListener;
+import org.opendaylight.netvirt.elan.internal.ElanInterfaceManager;
+import org.opendaylight.netvirt.elan.l2gw.listeners.HwvtepPhysicalSwitchListener;
+import org.opendaylight.netvirt.elan.l2gw.listeners.L2GatewayConnectionListener;
+import org.opendaylight.netvirt.elan.l2gw.listeners.LocalUcastMacListener;
+import org.opendaylight.netvirt.elan.l2gw.nodehandlertest.DataProvider;
+import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayUtils;
 import org.opendaylight.netvirt.elan.utils.ElanUtils;
 import org.opendaylight.netvirt.elanmanager.api.IElanService;
+import org.opendaylight.netvirt.elanmanager.api.IL2gwService;
 import org.opendaylight.netvirt.elanmanager.tests.utils.EvpnTestHelper;
+import org.opendaylight.netvirt.elanmanager.utils.ElanL2GwCacheUtils;
+import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayCache;
+import org.opendaylight.netvirt.neutronvpn.l2gw.L2GatewayListener;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Networks;
@@ -43,23 +70,26 @@ import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev1509
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 
-
-
 /**
  * End-to-end test of IElanService.
  *
  * @author Michael Vorburger
  * @author Riyazahmed Talikoti
  */
-@Ignore("This relies on flawed interface handling, see GENIUS-109")
 public class ElanServiceTest extends  ElanServiceTestBase {
 
     private static final Logger LOG = LoggerFactory.getLogger(ElanServiceTest.class);
@@ -86,15 +116,93 @@ public class ElanServiceTest extends  ElanServiceTestBase {
     private @Inject IBgpManager bgpManager;
     private @Inject IVpnManager vpnManager;
     private @Inject EvpnTestHelper evpnTestHelper;
-
-    @Before public void before() throws TransactionCommitFailedException {
+    private @Inject OdlInterfaceRpcService odlInterfaceRpcService;
+    private @Inject ElanL2GatewayUtils elanL2GatewayUtils;
+    private @Inject ElanInterfaceManager elanInterfaceManager;
+    private @Inject HwvtepPhysicalSwitchListener hwvtepPhysicalSwitchListener;
+    private @Inject L2GatewayConnectionListener l2GatewayConnectionListener;
+    private @Inject LocalUcastMacListener localUcastMacListener;
+    private @Inject ElanDpnInterfaceClusteredListener elanDpnInterfaceClusteredListener;
+    private @Inject EntityOwnershipService mockedEntityOwnershipService;
+    private @Inject L2GatewayCache l2GatewayCache;
+    private @Inject ElanUtils elanUtils;
+    private @Inject ElanInstanceDpnsCache elanInstanceDpnsCache;
+    private @Inject ElanExtnTepConfigListener elanExtnTepConfigListener;
+    private @Inject ElanExtnTepListener elanExtnTepListener;
+
+    private L2GatewayListener l2gwListener;
+    private MetricProvider metricProvider = new TestMetricProviderImpl();
+
+    private Verifications verifications;
+    private L2gwBuilders l2gwBuilders;
+
+    private SingleTransactionDataBroker singleTxdataBroker;
+
+    @Before public void before() throws Exception {
+
+        singleTxdataBroker = new SingleTransactionDataBroker(dataBroker);
+        verifications = new Verifications(singleTxdataBroker, odlInterfaceRpcService, EXTN_INTFS, getAwaiter());
+        l2gwBuilders = new L2gwBuilders(singleTxdataBroker);
+        JobCoordinator jobCoordinator = new JobCoordinatorImpl(metricProvider);
+
+        l2gwListener = new L2GatewayListener(dataBroker, mockedEntityOwnershipService,
+                Mockito.mock(ItmRpcService.class), Mockito.mock(IL2gwService.class), jobCoordinator, l2GatewayCache);
+        l2gwListener.init();
         setupItm();
+        l2gwBuilders.buildTorNode(TOR2_NODE_ID, PS2, TOR2_TEPIP);
+        l2gwBuilders.buildTorNode(TOR1_NODE_ID, PS1, TOR1_TEPIP);
+    }
+
+    @After public void after() throws Exception {
+        for (ResourceBatchingManager.ShardResource i : ResourceBatchingManager.ShardResource.values()) {
+            ResourceBatchingManager.getInstance().deregisterBatchableResource(i.name());
+        }
+
+        ElanL2GwCacheUtils.removeL2GatewayDeviceFromAllElanCache(TOR1_NODE_ID);
+        ElanL2GwCacheUtils.removeL2GatewayDeviceFromAllElanCache(TOR2_NODE_ID);
+
+        ElanL2GwCacheUtils.removeL2GatewayDeviceFromCache(ExpectedObjects.ELAN1, TOR1_NODE_ID);
+        ElanL2GwCacheUtils.removeL2GatewayDeviceFromCache(ExpectedObjects.ELAN1, TOR2_NODE_ID);
     }
 
     @Test public void elanServiceTestModule() {
         // Intentionally empty; the goal is just to first test the ElanServiceTestModule
     }
 
+    void createL2gwL2gwconn(InstanceIdentifier<Node> nodePath,
+                            String l2gwName,
+                            String deviceName,
+                            List<String> ports,
+                            String connectionName)
+            throws InterruptedException, TransactionCommitFailedException {
+
+        //Create l2gw
+        singleTxdataBroker.syncWrite(LogicalDatastoreType.CONFIGURATION,
+                l2gwBuilders.buildL2gwIid(l2gwName), l2gwBuilders.buildL2gw(l2gwName, deviceName, ports));
+        awaitForData(LogicalDatastoreType.CONFIGURATION, l2gwBuilders.buildL2gwIid(l2gwName));
+
+        //Create l2gwconn
+        singleTxdataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                l2gwBuilders.buildConnectionIid(connectionName), l2gwBuilders.buildConnection(connectionName,
+                        l2gwName, ExpectedObjects.ELAN1, 100));
+        awaitForData(LogicalDatastoreType.CONFIGURATION, l2gwBuilders.buildConnectionIid(connectionName));
+
+        //check for Config Logical Switch creation
+        InstanceIdentifier logicalSwitchesInstanceIdentifier =
+                HwvtepSouthboundUtils.createLogicalSwitchesInstanceIdentifier(
+                        nodePath.firstKeyOf(Node.class).getNodeId(),
+                        new HwvtepNodeName(ExpectedObjects.ELAN1));
+        awaitForData(LogicalDatastoreType.CONFIGURATION, logicalSwitchesInstanceIdentifier);
+
+        //create operational logical switch
+        Optional<LogicalSwitches> logicalSwitchesOptional =
+                MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, logicalSwitchesInstanceIdentifier);
+        LogicalSwitches logicalSwitches = logicalSwitchesOptional.isPresent() ? logicalSwitchesOptional.get() : null ;
+        MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                logicalSwitchesInstanceIdentifier, logicalSwitches);
+        awaitForData(LogicalDatastoreType.OPERATIONAL, logicalSwitchesInstanceIdentifier);
+    }
+
     @Test public void checkSMAC() throws Exception {
         // Create Elan instance
         createElanInstance(ExpectedObjects.ELAN1, ExpectedObjects.ELAN1_SEGMENT_ID);
@@ -200,6 +308,7 @@ public class ElanServiceTest extends  ElanServiceTestBase {
     @Test public void checkEvpnAdvRT2() throws Exception {
         createElanInstanceAndInterfaceAndAttachEvpn();
 
+
         AssertDataObjects.assertEqualBeans(
                 ExpectedObjects.checkEvpnAdvertiseRoute(ELAN1_SEGMENT_ID, DPN1MAC1, DPN1_TEPIP, DPN1IP1, RD),
                 readBgpNetworkFromDS(DPN1IP1));
@@ -318,4 +427,152 @@ public class ElanServiceTest extends  ElanServiceTestBase {
             return elanInstance.isPresent() && elanInstance.get().getElanTag() != null;
         });
     }
+
+    public void verifyL2gw1Connection() throws Exception {
+
+        //Create ELAN
+        createElanInstance(ExpectedObjects.ELAN1, ExpectedObjects.ELAN1_SEGMENT_ID);
+        awaitForElanTag(ExpectedObjects.ELAN1);
+
+        //Add Elan MAC1, MAC2 in DPN1
+        InterfaceInfo interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC1).getLeft();
+        addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN1IP1);
+        interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC2).getLeft();
+        addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN1IP2);
+
+        //Add Elan MAC1, MAC2 in DPN2
+        interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN2MAC1).getLeft();
+        addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN2IP1);
+        verifications.verifyLocalBcGroup(DPN2_ID, 1);
+
+        interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN2MAC2).getLeft();
+        addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN2IP2);
+        verifications.verifyLocalBcGroup(DPN2_ID, 2);
+
+        createL2gwL2gwconn(TOR1_NODE_IID, L2GW1, PS1, DataProvider.getPortNameListD1(), L2GW_CONN1);
+
+        verifications.verifyThatMcastMacTepsCreated(TOR1_NODE_IID, asList(DPN1_TEPIP, DPN2_TEPIP));
+        verifications.verifyThatUcastCreated(TOR1_NODE_IID, asList(DPN1MAC1, DPN1MAC2, DPN2MAC1, DPN2MAC2));
+        verifications.verifyThatDpnGroupUpdated(DPN1_ID, asList(DPN2_ID), asList(TOR1_TEPIP));
+        verifications.verifyThatDpnGroupUpdated(DPN2_ID, asList(DPN1_ID), asList(TOR1_TEPIP));
+    }
+
+    public void verifyL2gwMac1InDpns() throws Exception {
+        verifyL2gw1Connection();
+        l2gwBuilders.createLocalUcastMac(TOR1_NODE_IID, TOR1_MAC1, TOR1_IP1, TOR1_TEPIP);
+        verifications.verifyThatDmacFlowOfTORCreated(asList(DPN1_ID, DPN2_ID), TOR1_NODE_IID, asList(TOR1_MAC1));
+    }
+
+    public void verifyL2gw2Connection() throws Exception {
+        verifyL2gwMac1InDpns();
+        // TOR Node 2 creation
+        createL2gwL2gwconn(TOR2_NODE_IID, L2GW2, PS2, DataProvider.getPortNameListTor2(), L2GW_CONN2);
+        //check for remote mcast mac in tor2 against TEPs of dpn1, dpn2 and dpn3, tor1)
+        verifications.verifyThatMcastMacTepsCreated(TOR2_NODE_IID, asList(DPN1_TEPIP, DPN2_TEPIP, TOR1_TEPIP));
+        verifications.verifyThatMcastMacTepsCreated(TOR1_NODE_IID, asList(DPN1_TEPIP, DPN2_TEPIP, TOR2_TEPIP));
+        verifications.verifyThatUcastCreated(TOR2_NODE_IID, asList(DPN1MAC1, DPN2MAC1, DPN2MAC1, DPN2MAC2, TOR1_MAC1));
+    }
+
+    @Test
+    public void verifyL2gwMac2InTors() throws Exception {
+        verifyL2gw2Connection();
+        l2gwBuilders.createLocalUcastMac(TOR1_NODE_IID, TOR1_MAC2, TOR1_IP2, TOR1_TEPIP);
+        verifications.verifyThatUcastCreated(TOR2_NODE_IID, asList(TOR1_MAC2));
+    }
+
+    @Test
+    public void verifyL2gwMacDeleteInTors() throws Exception {
+        verifyL2gwMac2InTors();
+        LocalUcastMacs localUcastMacs1 = l2gwBuilders.createLocalUcastMac(
+                TOR1_NODE_IID, TOR1_MAC1, TOR1_IP1, TOR1_TEPIP);
+        singleTxdataBroker.syncDelete(LogicalDatastoreType.OPERATIONAL,
+                l2gwBuilders.buildMacIid(TOR1_NODE_IID, localUcastMacs1));
+        verifications.verifyThatDmacFlowOfTORDeleted(asList(DPN1_ID, DPN2_ID), TOR1_NODE_IID, asList(TOR1_MAC1));
+        verifications.verifyThatUcastDeleted(TOR2_NODE_IID, asList(TOR1_MAC1));
+    }
+
+    @Test
+    public void verifyAddDpnAfterL2gwConnection() throws Exception {
+        verifyL2gwMac2InTors();
+        //Add Elan MAC1, MAC2 in DPN3
+        InterfaceInfo interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN3MAC1).getLeft();
+        addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN3IP1);
+
+        //bc group of this dpn created
+        verifications.verifyThatDpnGroupUpdated(DPN3_ID, asList(DPN1_ID, DPN2_ID), asList(TOR1_NODE_ID, TOR2_NODE_ID));
+        //other tors macs be installed in this dpn
+        verifications.verifyThatDmacFlowOfTORCreated(asList(DPN3_ID), TOR1_NODE_IID, asList(TOR1_MAC1));
+        verifications.verifyThatDmacOfOtherDpnCreated(DPN3_ID, DPN1_ID, asList(DPN1MAC1, DPN1MAC2));
+        verifications.verifyThatDmacOfOtherDpnCreated(DPN3_ID, DPN2_ID, asList(DPN2MAC1, DPN2MAC2));
+
+        //bc group of the other dpns be updated
+        verifications.verifyThatDpnGroupUpdated(DPN1_ID, asList(DPN2_ID, DPN3_ID), asList(TOR1_NODE_ID, TOR2_NODE_ID));
+        verifications.verifyThatDpnGroupUpdated(DPN2_ID, asList(DPN1_ID, DPN3_ID), asList(TOR1_NODE_ID, TOR2_NODE_ID));
+
+        //mcast of tor should be updated
+        verifications.verifyThatMcastMacTepsCreated(TOR2_NODE_IID,
+                asList(DPN1_TEPIP, DPN2_TEPIP, DPN3_TEPIP, TOR1_TEPIP));
+        verifications.verifyThatMcastMacTepsCreated(TOR1_NODE_IID,
+                asList(DPN1_TEPIP, DPN2_TEPIP, DPN3_TEPIP, TOR2_TEPIP));
+
+        //this dpn mac should get installed in other dpns and tors
+        verifications.verifyThatUcastCreated(TOR1_NODE_IID, asList(DPN3MAC1));
+        verifications.verifyThatUcastCreated(TOR2_NODE_IID, asList(DPN3MAC1));
+        verifications.verifyThatDmacOfOtherDpnCreated(DPN1_ID, DPN3_ID, asList(DPN3MAC1));
+        verifications.verifyThatDmacOfOtherDpnCreated(DPN2_ID, DPN3_ID, asList(DPN3MAC1));
+    }
+
+    @Test
+    public void verifyDeleteDpnAfterL2gwConnection() throws Exception {
+        verifyAddDpnAfterL2gwConnection();
+        InterfaceInfo interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN3MAC1).getLeft();
+        deleteElanInterface(interfaceInfo);
+
+        //clean up of group of this dpn3
+        verifications.verifyThatDpnGroupDeleted(DPN3_ID);
+        //clean up dmacs of this dpn3
+        verifications.verifyThatDmacFlowOfTORDeleted(asList(DPN3_ID), TOR1_NODE_IID, asList(TOR1_MAC1));
+        verifications.verifyThatDmacOfOtherDPNDeleted(DPN3_ID, DPN1_ID, asList(DPN1MAC1, DPN1MAC2));
+        verifications.verifyThatDmacOfOtherDPNDeleted(DPN3_ID, DPN2_ID, asList(DPN2MAC1, DPN2MAC2));
+
+        //clean up of dmacs in the other dpns
+        verifications.verifyThatDmacOfOtherDPNDeleted(DPN1_ID, DPN3_ID, asList(DPN3MAC1));
+        verifications.verifyThatDmacOfOtherDPNDeleted(DPN2_ID, DPN3_ID, asList(DPN3MAC1));
+
+        //cleanup of bc group of other dpns
+        verifications.verifyThatDpnGroupUpdated(DPN1_ID, asList(DPN2_ID), asList(TOR1_NODE_ID, TOR2_NODE_ID));
+        verifications.verifyThatDpnGroupUpdated(DPN2_ID, asList(DPN1_ID), asList(TOR1_NODE_ID, TOR2_NODE_ID));
+
+        //dpn tep should be removed from tors
+        verifications.verifyThatMcastMacTepsDeleted(TOR2_NODE_IID, asList(DPN3_TEPIP));
+        verifications.verifyThatMcastMacTepsDeleted(TOR2_NODE_IID, asList(DPN3_TEPIP));
+
+        //dpn mac should be removed from tors
+        verifications.verifyThatUcastDeleted(TOR1_NODE_IID, asList(DPN3MAC1));
+        verifications.verifyThatUcastDeleted(TOR2_NODE_IID, asList(DPN3MAC1));
+    }
+
+    @Test
+    public void verifyDeleteL2gw1Connection() throws Exception {
+        verifyL2gw2Connection();
+        //delete tor1 l2gw connection
+        l2gwBuilders.deletel2GWConnection(L2GW_CONN1);
+
+        //deleted tors mcast & cast be cleared
+        verifications.verifyThatMcastMacTepsDeleted(TOR1_NODE_IID, asList(DPN1_TEPIP, DPN2_TEPIP, TOR2_TEPIP));
+        verifications.verifyThatUcastDeleted(TOR1_NODE_IID, asList(DPN1MAC1, DPN1MAC2, DPN2MAC1, DPN2MAC2));
+
+        //mcast of other tor be updated
+        verifications.verifyThatMcastMacTepsDeleted(TOR2_NODE_IID, asList(TOR1_TEPIP));
+
+        //ucast of deleted to be deleted in other tor
+        verifications.verifyThatUcastDeleted(TOR2_NODE_IID, asList(TOR1_MAC1));
+
+        //group of dpns be udpated
+        verifications.verifyThatDpnGroupUpdated(DPN1_ID, asList(DPN2_ID), asList(TOR2_NODE_ID));
+        verifications.verifyThatDpnGroupUpdated(DPN2_ID, asList(DPN1_ID), asList(TOR2_NODE_ID));
+
+        //ucast of deleted tor be deleted in other dpns
+        verifications.verifyThatDmacFlowOfTORDeleted(asList(DPN1_ID, DPN2_ID), TOR1_NODE_IID, asList(TOR1_MAC1));
+    }
 }
index e917cf2073211621ab5d3a3c4b35f6a570b5762b..89840ea598dddbee30595873affb20f9164a123b 100644 (file)
@@ -36,6 +36,7 @@ import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
 import org.opendaylight.netvirt.elanmanager.tests.utils.InterfaceHelper;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
@@ -52,6 +53,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
@@ -63,6 +65,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.elan._interface.StaticMacEntries;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.elan._interface.StaticMacEntriesBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
@@ -74,19 +80,24 @@ public class ElanServiceTestBase {
     protected  @Inject ElanInstanceManager elanInstanceManager;
     protected  @Inject ElanInstanceCache elanInstanceCache;
     protected @Inject SingleTransactionDataBroker singleTxdataBroker;
+    protected @Inject OdlInterfaceRpcService odlInterfaceRpcService;
     public static final String ELAN1 = "34701c04-1118-4c65-9425-78a80d49a211";
     public static final Long ELAN1_SEGMENT_ID = 100L;
 
     protected static final BigInteger DPN1_ID = new BigInteger("1");
     protected static final BigInteger DPN2_ID = new BigInteger("2");
+    protected static final BigInteger DPN3_ID = new BigInteger("3");
 
     protected static final String DPN1_ID_STR = "1";
     protected static final String DPN2_ID_STR = "2";
+    protected static final String DPN3_ID_STR = "3";
 
     protected static final String DPN1_TEPIP = "192.168.56.30";
     protected static final String DPN2_TEPIP = "192.168.56.40";
-    protected static final String TOR1_TEPIP = "192.168.56.50";
-    public static final String DCGW_TEPIP = "192.168.56.60";
+    protected static final String DPN3_TEPIP = "192.168.56.50";
+    protected static final String TOR1_TEPIP = "192.168.56.60";
+    protected static final String TOR2_TEPIP = "192.168.56.70";
+    public static final String DCGW_TEPIP = "192.168.56.80";
 
     protected static final String DPN1MAC1 = "10:00:00:00:00:01";
     protected static final String DPN1MAC2 = "10:00:00:00:00:02";
@@ -94,21 +105,42 @@ public class ElanServiceTestBase {
     protected static final String DPN2MAC1 = "10:00:00:00:00:03";
     protected static final String DPN2MAC2 = "10:00:00:00:00:04";
 
-    protected static final String TOR1MAC1 = "10:00:00:00:00:05";
-    protected static final String TOR1MAC2 = "10:00:00:00:00:06";
+    protected static final String DPN3MAC1 = "10:00:00:00:00:05";
+    protected static final String DPN3MAC2 = "10:00:00:00:00:06";
 
-    protected static final String DPN1TODPN2TNLMAC = "91:00:00:00:00:01";
-    protected static final String DPN1TOTOR1TNLMAC = "91:00:00:00:00:02";
-    protected static final String DPN1TODCGWTNLMAC = "91:00:00:00:00:03";
+    protected static final String TOR1_MAC1 = "10:00:00:00:00:07";
+    protected static final String TOR1_IP1 = "10.0.0.1";
+    protected static final String TOR1_MAC2 = "10:00:00:00:00:08";
+    protected static final String TOR1_IP2 = "10.0.0.2";
+
+    protected static final String TOR2_MAC1 = "10:00:00:00:00:09";
+    protected static final String TOR2_MAC2 = "10:00:00:00:00:10";
+
+    protected static final String DPN1_TO_DPN2TNL_MAC = "91:00:00:00:00:01";
+    protected static final String DPN1_TO_TOR1TNL_MAC = "91:00:00:00:00:02";
+    protected static final String DPN1_TO_DCGWTNL_MAC = "91:00:00:00:00:03";
+    protected static final String DPN1_TO_DPN3_TNL_MAC = "91:00:00:00:00:04";
+
+    protected static final String DPN2_TO_DPN1_TNL_MAC = "92:00:00:00:00:01";
+    protected static final String DPN2_TO_TOR1_TNL_MAC = "92:00:00:00:00:02";
+    protected static final String DPN2_TO_DCGW_TNL_MAC = "92:00:00:00:00:03";
+    protected static final String DPN2_TO_DPN3_TNL_MAC = "92:00:00:00:00:04";
+
+    protected static final String DPN3_TO_DPN1_TNL_MAC = "93:00:00:00:00:01";
+    protected static final String DPN3_TO_DPN2_TNL_MAC = "93:00:00:00:00:02";
+    protected static final String DPN3_TO_TOR1_TNL_MAC = "93:00:00:00:00:03";
+
+    protected static final String DPN1_TO_TOR2_TNL_MAC = "94:00:00:00:00:01";
+    protected static final String DPN2_TO_TOR2_TNL_MAC = "94:00:00:00:00:02";
+    protected static final String DPN3_TO_TOR2_TNL_MAC = "94:00:00:00:00:03";
 
-    protected static final String DPN2TODPN1TNLMAC = "92:00:00:00:00:01";
-    protected static final String DPN2TOTOR1TNLMAC = "92:00:00:00:00:02";
-    protected static final String DPN2TODCGWTNLMAC = "92:00:00:00:00:03";
 
     protected static final String DPN1IP1 = "10.0.0.11";
     protected static final String DPN1IP2 = "10.0.0.12";
     protected static final String DPN2IP1 = "10.0.0.13";
     protected static final String DPN2IP2 = "10.0.0.14";
+    protected static final String DPN3IP1 = "10.0.0.15";
+    protected static final String DPN3IP2 = "10.0.0.16";
 
     protected static final String EVPNRECVMAC1 = "10:00:00:00:00:51";
     protected static final String EVPNRECVMAC2 = "10:00:00:00:00:52";
@@ -116,7 +148,23 @@ public class ElanServiceTestBase {
     protected static final String EVPNRECVIP1 = "192.168.122.51";
     protected static final String EVPNRECVIP2 = "192.168.122.52";
 
-    protected static final String TOR1NODEID = "hwvtep://uuid/34701c04-1118-4c65-9425-78a80d49a211";
+    protected static final String TOR1_NODE_ID = "hwvtep://uuid/34701c04-1118-4c65-9425-78a80d49a211";
+    protected static final String TOR2_NODE_ID = "hwvtep://uuid/34701c04-1118-4c65-9425-78a80d49a212";
+
+    protected static final String L2GW1 = "l2gw1";
+    protected static final String L2GW2 = "l2gw2";
+    protected static final String L2GW_CONN1 = "l2gwConnection1";
+    protected static final String L2GW_CONN2 = "l2gwConnection2";
+    protected static final String PS1 = "ps1";
+    protected static final String PS2 = "ps2";
+
+    protected static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params
+            .xml.ns.yang.network.topology.rev131021.network.topology.topology.Node>
+            TOR1_NODE_IID = createInstanceIdentifier(TOR1_NODE_ID);
+    protected static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params
+            .xml.ns.yang.network.topology.rev131021.network.topology.topology.Node>
+            TOR2_NODE_IID = createInstanceIdentifier(TOR2_NODE_ID);
+
     protected static final String DCGWID = DCGW_TEPIP;
 
     public static final String RD = "100:1";
@@ -125,46 +173,89 @@ public class ElanServiceTestBase {
     protected static Map<String, Pair<InterfaceInfo, String>> ELAN_INTERFACES = new HashMap<>();
     protected static Map<String, TunnelInterfaceDetails> EXTN_INTFS = new HashMap<>();
 
-
     static {
         //Adding elan dpn macs
         /*ELAN1+":"+DPN1MAC1 ->
         (vlanInterfaceInfo(String interfaceName, BigInteger dpId, int portNo, int lportTag, String mac), vmPrefix)*/
         ELAN_INTERFACES.put(ELAN1 + ":" + DPN1MAC1 ,
-                new ImmutablePair(InterfaceHelper.buildVlanInterfaceInfo("23701c04-1118-4c65-9425-78a80d49a211",
+                new ImmutablePair(InterfaceHelper
+                        .buildVlanInterfaceInfo("23701c04-1118-4c65-9425-78a80d49a211",
                 DPN1_ID, 1, 10, DPN1MAC1), DPN1IP1));
 
         ELAN_INTERFACES.put(ELAN1 + ":" + DPN1MAC2 ,
-                new ImmutablePair(InterfaceHelper.buildVlanInterfaceInfo("23701c04-1218-4c65-9425-78a80d49a211",
+                new ImmutablePair(InterfaceHelper
+                        .buildVlanInterfaceInfo("23701c04-1218-4c65-9425-78a80d49a211",
                 DPN1_ID, 2, 11, DPN1MAC2), DPN1IP2));
 
         ELAN_INTERFACES.put(ELAN1 + ":" + DPN2MAC1 ,
-                new ImmutablePair(InterfaceHelper.buildVlanInterfaceInfo("23701c04-2118-4c65-9425-78a80d49a211",
-                DPN2_ID, 3, 12, DPN2MAC1), DPN2IP1));
+                new ImmutablePair(InterfaceHelper
+                        .buildVlanInterfaceInfo("23701c04-2118-4c65-9425-78a80d49a211",
+                        DPN2_ID, 3, 12, DPN2MAC1), DPN2IP1));
 
         ELAN_INTERFACES.put(ELAN1 + ":" + DPN2MAC2 ,
-                new ImmutablePair(InterfaceHelper.buildVlanInterfaceInfo("23701c04-2218-4c65-9425-78a80d49a211",
-                DPN2_ID, 4, 13, DPN2MAC2), DPN2IP2));
+                new ImmutablePair(InterfaceHelper
+                        .buildVlanInterfaceInfo("23701c04-2218-4c65-9425-78a80d49a211",
+                        DPN2_ID, 4, 13, DPN2MAC2), DPN2IP2));
+
+        ELAN_INTERFACES.put(ELAN1 + ":" + DPN3MAC1 ,
+                new ImmutablePair(InterfaceHelper
+                        .buildVlanInterfaceInfo("23701c04-3118-4c65-9425-78a80d49a211",
+                        DPN3_ID, 5, 14, DPN3MAC1), DPN3IP1));
+
+        ELAN_INTERFACES.put(ELAN1 + ":" + DPN3MAC2 ,
+                new ImmutablePair(InterfaceHelper
+                        .buildVlanInterfaceInfo("23701c04-3218-4c65-9425-78a80d49a211",
+                        DPN3_ID, 6, 15, DPN3MAC2), DPN3IP2));
 
         //Adding the external tunnel interfaces
         EXTN_INTFS.put(DPN1_ID_STR + ":" + DPN2_ID_STR, new TunnelInterfaceDetails(DPN1_TEPIP, DPN2_TEPIP, true,
-                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-10", DPN1_ID, 5, 14, DPN1TODPN2TNLMAC)));
+                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-10", DPN1_ID, 5, 14, DPN1_TO_DPN2TNL_MAC)));
 
-        EXTN_INTFS.put(DPN1_ID_STR + ":" + TOR1NODEID, new TunnelInterfaceDetails(DPN1_TEPIP, TOR1_TEPIP, true,
-                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-12", DPN1_ID, 6, 15, DPN1TOTOR1TNLMAC)));
+        EXTN_INTFS.put(DPN1_ID_STR + ":" + TOR1_NODE_ID, new TunnelInterfaceDetails(DPN1_TEPIP, TOR1_TEPIP, true,
+                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-12", DPN1_ID, 6, 15, DPN1_TO_TOR1TNL_MAC)));
+        EXTN_INTFS.put(DPN1_ID_STR + ":" + TOR1_TEPIP, EXTN_INTFS.get(DPN1_ID_STR + ":" + TOR1_NODE_ID));
 
         EXTN_INTFS.put(DPN2_ID_STR + ":" + DPN1_ID_STR, new TunnelInterfaceDetails(DPN2_TEPIP, DPN1_TEPIP, true,
-                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-11", DPN2_ID, 7, 16, DPN2TODPN1TNLMAC)));
+                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-11", DPN2_ID, 7, 16, DPN2_TO_DPN1_TNL_MAC)));
+
+        EXTN_INTFS.put(DPN2_ID_STR + ":" + TOR1_NODE_ID, new TunnelInterfaceDetails(DPN2_TEPIP, TOR1_TEPIP, true,
+                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-13", DPN2_ID, 8, 17, DPN2_TO_TOR1_TNL_MAC)));
+        EXTN_INTFS.put(DPN2_ID_STR + ":" + TOR1_TEPIP, EXTN_INTFS.get(DPN2_ID_STR + ":" + TOR1_NODE_ID));
+
+        EXTN_INTFS.put(DPN1_ID_STR + ":" + DPN3_ID_STR, new TunnelInterfaceDetails(DPN1_TEPIP, DPN3_TEPIP, true,
+                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-14", DPN1_ID, 9, 18, DPN1_TO_DPN3_TNL_MAC)));
+
+        EXTN_INTFS.put(DPN3_ID_STR + ":" + DPN1_ID_STR, new TunnelInterfaceDetails(DPN3_TEPIP, DPN1_TEPIP, true,
+                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-15", DPN3_ID, 10, 19, DPN3_TO_DPN1_TNL_MAC)));
 
-        EXTN_INTFS.put(DPN2_ID_STR + ":" + TOR1NODEID, new TunnelInterfaceDetails(DPN2_TEPIP, TOR1_TEPIP, true,
-                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-13", DPN2_ID, 8, 17, DPN2TOTOR1TNLMAC)));
+        EXTN_INTFS.put(DPN3_ID_STR + ":" + DPN2_ID_STR, new TunnelInterfaceDetails(DPN3_TEPIP, DPN2_TEPIP, true,
+                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-16", DPN3_ID, 11, 20, DPN3_TO_DPN2_TNL_MAC)));
 
+        EXTN_INTFS.put(DPN2_ID_STR + ":" + DPN3_ID_STR, new TunnelInterfaceDetails(DPN2_TEPIP, DPN3_TEPIP, true,
+                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-17", DPN2_ID, 12, 21, DPN2_TO_DPN3_TNL_MAC)));
+
+        EXTN_INTFS.put(DPN3_ID_STR + ":" + TOR1_NODE_ID, new TunnelInterfaceDetails(DPN3_TEPIP, TOR1_TEPIP, true,
+                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-18", DPN3_ID, 13, 22, DPN3_TO_TOR1_TNL_MAC)));
+        EXTN_INTFS.put(DPN3_ID_STR + ":" + TOR1_TEPIP, EXTN_INTFS.get(DPN3_ID_STR + ":" + TOR1_NODE_ID));
+
+        EXTN_INTFS.put(DPN1_ID_STR + ":" + TOR2_NODE_ID, new TunnelInterfaceDetails(DPN1_TEPIP, TOR2_TEPIP, true,
+                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-19", DPN1_ID, 14, 23, DPN1_TO_TOR2_TNL_MAC)));
+        EXTN_INTFS.put(DPN1_ID_STR + ":" + TOR2_TEPIP, EXTN_INTFS.get(DPN1_ID_STR + ":" + TOR2_NODE_ID));
+
+        EXTN_INTFS.put(DPN2_ID_STR + ":" + TOR2_NODE_ID, new TunnelInterfaceDetails(DPN2_TEPIP, TOR2_TEPIP, true,
+                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-20", DPN2_ID, 15, 24, DPN2_TO_TOR2_TNL_MAC)));
+        EXTN_INTFS.put(DPN2_ID_STR + ":" + TOR2_TEPIP, EXTN_INTFS.get(DPN2_ID_STR + ":" + TOR2_NODE_ID));
+
+        EXTN_INTFS.put(DPN3_ID_STR + ":" + TOR2_NODE_ID, new TunnelInterfaceDetails(DPN3_TEPIP, TOR2_TEPIP, true,
+                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-21", DPN3_ID, 16, 25, DPN3_TO_TOR2_TNL_MAC)));
+        EXTN_INTFS.put(DPN3_ID_STR + ":" + TOR2_TEPIP, EXTN_INTFS.get(DPN3_ID_STR + ":" + TOR2_NODE_ID));
 
         EXTN_INTFS.put(DPN1_ID_STR + ":" + DCGWID, new TunnelInterfaceDetails(DPN1_TEPIP, DCGW_TEPIP, true,
-                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-14", DPN1_ID, 9, 18, DPN1TODCGWTNLMAC)));
+                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-22", DPN1_ID, 17, 26, DPN1_TO_DCGWTNL_MAC)));
 
         EXTN_INTFS.put(DPN2_ID_STR + ":" + DCGWID, new TunnelInterfaceDetails(DPN2_TEPIP, DCGWID, true,
-                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-15", DPN2_ID, 10, 19, DPN2TODCGWTNLMAC)));
+                InterfaceHelper.buildVxlanInterfaceInfo("tun23701c04-23", DPN2_ID, 18, 27, DPN2_TO_DCGW_TNL_MAC)));
+
     }
 
     protected ConditionFactory getAwaiter() {
@@ -208,27 +299,82 @@ public class ElanServiceTestBase {
         return null;
     }
 
+    protected static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology
+            .rev131021.network.topology.topology.Node> createInstanceIdentifier(String nodeIdString) {
+        org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId nodeId
+                = new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network
+                .topology.rev131021.NodeId(new Uri(nodeIdString));
+        org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology
+                .topology.NodeKey nodeKey = new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang
+                .network.topology.rev131021.network.topology.topology.NodeKey(nodeId);
+        TopologyKey topoKey = new TopologyKey(new TopologyId(new Uri("hwvtep:1")));
+        return InstanceIdentifier.builder(NetworkTopology.class)
+                .child(Topology.class, topoKey)
+                .child(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang
+                        .network.topology.rev131021.network.topology.topology.Node.class, nodeKey)
+                .build();
+    }
+
+
     protected void setupItm() throws TransactionCommitFailedException {
         /*Add tap port and tunnel ports in DPN1 and DPN2*/
         interfaceMgr.addInterfaceInfo(ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC1).getLeft());
         interfaceMgr.addInterfaceInfo(ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC2).getLeft());
         interfaceMgr.addInterfaceInfo(ELAN_INTERFACES.get(ELAN1 + ":" + DPN2MAC1).getLeft());
         interfaceMgr.addInterfaceInfo(ELAN_INTERFACES.get(ELAN1 + ":" + DPN2MAC2).getLeft());
+        interfaceMgr.addInterfaceInfo(ELAN_INTERFACES.get(ELAN1 + ":" + DPN3MAC1).getLeft());
+        interfaceMgr.addInterfaceInfo(ELAN_INTERFACES.get(ELAN1 + ":" + DPN3MAC2).getLeft());
+
         interfaceMgr.addTunnelInterface(EXTN_INTFS.get(DPN1_ID_STR + ":" + DPN2_ID_STR));
         interfaceMgr.addTunnelInterface(EXTN_INTFS.get(DPN2_ID_STR + ":" + DPN1_ID_STR));
+        interfaceMgr.addTunnelInterface(EXTN_INTFS.get(DPN1_ID_STR + ":" + DPN3_ID_STR));
+        interfaceMgr.addTunnelInterface(EXTN_INTFS.get(DPN3_ID_STR + ":" + DPN1_ID_STR));
+        interfaceMgr.addTunnelInterface(EXTN_INTFS.get(DPN2_ID_STR + ":" + DPN3_ID_STR));
+        interfaceMgr.addTunnelInterface(EXTN_INTFS.get(DPN3_ID_STR + ":" + DPN2_ID_STR));
+
+        interfaceMgr.addTunnelInterface(EXTN_INTFS.get(DPN1_ID_STR + ":" + TOR1_NODE_ID));
+        interfaceMgr.addTunnelInterface(EXTN_INTFS.get(DPN2_ID_STR + ":" + TOR1_NODE_ID));
+        interfaceMgr.addTunnelInterface(EXTN_INTFS.get(DPN3_ID_STR + ":" + TOR1_NODE_ID));
+        interfaceMgr.addTunnelInterface(EXTN_INTFS.get(DPN1_ID_STR + ":" + TOR2_NODE_ID));
+        interfaceMgr.addTunnelInterface(EXTN_INTFS.get(DPN2_ID_STR + ":" + TOR2_NODE_ID));
+        interfaceMgr.addTunnelInterface(EXTN_INTFS.get(DPN3_ID_STR + ":" + TOR2_NODE_ID));
 
         /*Add DPN1 and DPN2 TEPs*/
         itmRpc.addDpn(DPN1_ID, DPN1_TEPIP);
         itmRpc.addDpn(DPN2_ID, DPN2_TEPIP);
+        itmRpc.addDpn(DPN3_ID, DPN3_TEPIP);
 
         /*add external interface*/
         itmRpc.addInterface(DPN1_ID,
                 DPN2_TEPIP, EXTN_INTFS.get(DPN1_ID_STR + ":" + DPN2_ID_STR).getInterfaceInfo().getInterfaceName());
         itmRpc.addInterface(DPN2_ID,
                 DPN1_TEPIP, EXTN_INTFS.get(DPN2_ID_STR + ":" + DPN1_ID_STR).getInterfaceInfo().getInterfaceName());
+        itmRpc.addInterface(DPN1_ID,
+                DPN3_TEPIP, EXTN_INTFS.get(DPN1_ID_STR + ":" + DPN3_ID_STR).getInterfaceInfo().getInterfaceName());
+        itmRpc.addInterface(DPN3_ID,
+                DPN1_TEPIP, EXTN_INTFS.get(DPN3_ID_STR + ":" + DPN1_ID_STR).getInterfaceInfo().getInterfaceName());
+        itmRpc.addInterface(DPN2_ID,
+                DPN3_TEPIP, EXTN_INTFS.get(DPN2_ID_STR + ":" + DPN3_ID_STR).getInterfaceInfo().getInterfaceName());
+        itmRpc.addInterface(DPN3_ID,
+                DPN2_TEPIP, EXTN_INTFS.get(DPN3_ID_STR + ":" + DPN2_ID_STR).getInterfaceInfo().getInterfaceName());
 
-        itmRpc.addExternalInterface(DPN1_ID,
+
+        itmRpc.addL2GwInterface(DPN1_ID,
                 DCGWID, EXTN_INTFS.get(DPN1_ID_STR + ":" + DCGWID).getInterfaceInfo().getInterfaceName());
+        itmRpc.addL2GwInterface(DPN1_ID,
+                TOR1_NODE_ID, EXTN_INTFS.get(DPN1_ID_STR + ":" + TOR1_NODE_ID).getInterfaceInfo().getInterfaceName());
+        itmRpc.addL2GwInterface(DPN2_ID,
+                TOR1_NODE_ID, EXTN_INTFS.get(DPN2_ID_STR + ":" + TOR1_NODE_ID).getInterfaceInfo().getInterfaceName());
+        itmRpc.addL2GwInterface(DPN3_ID,
+                TOR1_NODE_ID, EXTN_INTFS.get(DPN3_ID_STR + ":" + TOR1_NODE_ID).getInterfaceInfo().getInterfaceName());
+        itmRpc.addL2GwInterface(DPN1_ID,
+                TOR2_NODE_ID, EXTN_INTFS.get(DPN1_ID_STR + ":" + TOR2_NODE_ID).getInterfaceInfo().getInterfaceName());
+        itmRpc.addL2GwInterface(DPN2_ID,
+                TOR2_NODE_ID, EXTN_INTFS.get(DPN2_ID_STR + ":" + TOR2_NODE_ID).getInterfaceInfo().getInterfaceName());
+        itmRpc.addL2GwInterface(DPN3_ID,
+                TOR2_NODE_ID, EXTN_INTFS.get(DPN3_ID_STR + ":" + TOR2_NODE_ID).getInterfaceInfo().getInterfaceName());
+
+
     }
 
     protected InstanceIdentifier<Flow> getFlowIid(short tableId, FlowId flowid, BigInteger dpnId) {
index ff586b9989b0773d0807a9bdd1b88c60daed6086..15c2e17e94851ccc36d3130bdccbee35b69126f7 100644 (file)
@@ -9,6 +9,8 @@ package org.opendaylight.netvirt.elanmanager.tests;
 
 import static org.mockito.Mockito.CALLS_REAL_METHODS;
 
+import com.google.common.base.Optional;
+
 import org.mockito.Mockito;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.test.DataBrokerTestModule;
@@ -21,12 +23,17 @@ import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.BatchingU
 import org.opendaylight.genius.lockmanager.impl.LockManagerServiceImpl;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.genius.mdsalutil.internal.MDSALManager;
+import org.opendaylight.genius.srm.ServiceRecoveryRegistry;
 import org.opendaylight.genius.testutils.TestInterfaceManager;
 import org.opendaylight.genius.testutils.itm.ItmRpcTestImpl;
+import org.opendaylight.genius.utils.hwvtep.HwvtepHACache;
+import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
 import org.opendaylight.infrautils.diagstatus.DiagStatusService;
 import org.opendaylight.infrautils.inject.guice.testutils.AbstractGuiceJsr250Module;
 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
+import org.opendaylight.mdsal.eos.common.api.EntityOwnershipState;
 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
+import org.opendaylight.netvirt.cache.impl.l2gw.L2GatewayCacheImpl;
 import org.opendaylight.netvirt.elan.internal.ElanServiceProvider;
 import org.opendaylight.netvirt.elanmanager.api.IElanService;
 import org.opendaylight.netvirt.elanmanager.tests.utils.BgpManagerTestImpl;
@@ -34,6 +41,7 @@ import org.opendaylight.netvirt.elanmanager.tests.utils.ElanEgressActionsHelper;
 import org.opendaylight.netvirt.elanmanager.tests.utils.IdHelper;
 import org.opendaylight.netvirt.elanmanager.tests.utils.VpnManagerTestImpl;
 import org.opendaylight.netvirt.neutronvpn.NeutronvpnManagerImpl;
+import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayCache;
 import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
@@ -59,7 +67,14 @@ public class ElanServiceTestModule extends AbstractGuiceJsr250Module {
     @Override
     protected void configureBindings() {
         DataBroker dataBroker = DataBrokerTestModule.dataBroker();
-        bind(EntityOwnershipService.class).toInstance(Mockito.mock(EntityOwnershipService.class));
+        EntityOwnershipService mockedEntityOwnershipService = Mockito.mock(EntityOwnershipService.class);
+        EntityOwnershipState mockedEntityOwnershipState = EntityOwnershipState.IS_OWNER;
+        Mockito.when(mockedEntityOwnershipService.getOwnershipState(Mockito.any()))
+                .thenReturn(Optional.of(mockedEntityOwnershipState));
+        bind(EntityOwnershipService.class).toInstance(mockedEntityOwnershipService);
+        bind(L2GatewayCache.class).to(L2GatewayCacheImpl.class);
+        bind(HwvtepNodeHACache.class).to(HwvtepHACache.class);
+        bind(ServiceRecoveryRegistry.class).toInstance(Mockito.mock(ServiceRecoveryRegistry.class));
         bind(INeutronVpnManager.class).toInstance(Mockito.mock(NeutronvpnManagerImpl.class));
         IVpnManager ivpnManager = Mockito.mock(VpnManagerTestImpl.class, CALLS_REAL_METHODS);
         bind(IMdsalApiManager.class).toInstance(new MDSALManager(dataBroker,
@@ -80,14 +95,14 @@ public class ElanServiceTestModule extends AbstractGuiceJsr250Module {
 
         // Bindings to test infra (fakes & mocks)
 
-        TestInterfaceManager obj = TestInterfaceManager.newInstance(dataBroker);
+        TestInterfaceManager testInterfaceManager = TestInterfaceManager.newInstance(dataBroker);
         ItmRpcService itmRpcService = new ItmRpcTestImpl();
 
         bind(DataBroker.class).toInstance(dataBroker);
         bind(DataBroker.class).annotatedWith(OsgiService.class).toInstance(dataBroker);
         bind(IdManagerService.class).toInstance(Mockito.mock(IdHelper.class,  CALLS_REAL_METHODS));
-        bind(IInterfaceManager.class).toInstance(obj);
-        bind(TestInterfaceManager.class).toInstance(obj);
+        bind(IInterfaceManager.class).toInstance(testInterfaceManager);
+        bind(TestInterfaceManager.class).toInstance(testInterfaceManager);
         InterfaceMetaUtils interfaceMetaUtils = new InterfaceMetaUtils(dataBroker,
                 Mockito.mock(IdHelper.class,  CALLS_REAL_METHODS),
                 Mockito.mock(BatchingUtils.class));
@@ -99,7 +114,9 @@ public class ElanServiceTestModule extends AbstractGuiceJsr250Module {
                 interfaceMetaUtils,
                 Mockito.mock(BatchingUtils.class));
 
-        bind(OdlInterfaceRpcService.class).toInstance(ElanEgressActionsHelper.newInstance(interfaceManagerCommonUtils));
+
+        bind(OdlInterfaceRpcService.class).toInstance(ElanEgressActionsHelper.newInstance(interfaceManagerCommonUtils,
+                testInterfaceManager));
         SingleTransactionDataBroker singleTransactionDataBroker = new SingleTransactionDataBroker(dataBroker);
         bind(SingleTransactionDataBroker.class).toInstance(singleTransactionDataBroker);
         IBgpManager ibgpManager = BgpManagerTestImpl.newInstance(singleTransactionDataBroker);
diff --git a/elanmanager/impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/L2gwBuilders.java b/elanmanager/impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/L2gwBuilders.java
new file mode 100644 (file)
index 0000000..c743df2
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Copyright © 2017 Ericsson India Global Services Pvt Ltd. 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.netvirt.elanmanager.tests;
+
+import static org.opendaylight.netvirt.elan.l2gw.nodehandlertest.NodeConnectedHandlerUtils.getUUid;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.netvirt.elan.l2gw.nodehandlertest.GlobalAugmentationHelper;
+import org.opendaylight.netvirt.elan.l2gw.nodehandlertest.TestBuilders;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.attributes.Devices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.attributes.DevicesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.attributes.devices.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.attributes.devices.InterfacesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.L2gatewayConnections;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnectionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnectionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.L2gateways;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.l2gateways.L2gateway;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.l2gateways.L2gatewayBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.l2gateways.L2gatewayKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIpsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIpsKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class L2gwBuilders {
+
+    private SingleTransactionDataBroker singleTransactionDataBroker;
+
+    public L2gwBuilders(SingleTransactionDataBroker singleTransactionDataBroker) {
+        this.singleTransactionDataBroker = singleTransactionDataBroker;
+    }
+
+    public L2gatewayConnection buildConnection(String connectionName, String l2gwName, String elan,
+                                                      Integer segmentationId) {
+
+        final L2gatewayConnectionBuilder l2gatewayConnectionBuilder = new L2gatewayConnectionBuilder();
+
+        String uuidConnectionName = UUID.nameUUIDFromBytes(connectionName.getBytes()).toString();
+        l2gatewayConnectionBuilder.setUuid(new Uuid(uuidConnectionName));
+
+        String uuidL2gwName = UUID.nameUUIDFromBytes(l2gwName.getBytes()).toString();
+        l2gatewayConnectionBuilder.setL2gatewayId(new Uuid(uuidL2gwName));
+        l2gatewayConnectionBuilder.setNetworkId(new Uuid(elan));
+        l2gatewayConnectionBuilder.setSegmentId(segmentationId);
+        l2gatewayConnectionBuilder.setTenantId(new Uuid(ExpectedObjects.ELAN1));
+
+        String portName = "port";
+        String uuidPort = UUID.nameUUIDFromBytes(portName.getBytes()).toString();
+        l2gatewayConnectionBuilder.setPortId(new Uuid(uuidPort));
+        return l2gatewayConnectionBuilder.build();
+    }
+
+    public L2gateway buildL2gw(String l2gwName, String deviceName, List<String> intfNames) {
+        final L2gatewayBuilder l2gatewayBuilder = new L2gatewayBuilder();
+        String uuid = UUID.nameUUIDFromBytes(l2gwName.getBytes()).toString();
+        //String tenantUuid = UUID.fromString(ELAN1).toString();
+        l2gatewayBuilder.setUuid(new Uuid(uuid));
+        l2gatewayBuilder.setTenantId(new Uuid(ExpectedObjects.ELAN1));
+
+        final List<Devices> devices = new ArrayList<>();
+        final DevicesBuilder deviceBuilder = new DevicesBuilder();
+        final List<Interfaces> interfaces = new ArrayList<>();
+        for (String intfName : intfNames) {
+            final InterfacesBuilder interfacesBuilder = new InterfacesBuilder();
+            interfacesBuilder.setInterfaceName(intfName);
+            interfacesBuilder.setSegmentationIds(new ArrayList<>());
+            interfaces.add(interfacesBuilder.build());
+        }
+        deviceBuilder.setDeviceName(deviceName);
+        deviceBuilder.setUuid(new Uuid(uuid));
+        deviceBuilder.setInterfaces(interfaces);
+
+        devices.add(deviceBuilder.build());
+        l2gatewayBuilder.setDevices(devices);
+        return l2gatewayBuilder.build();
+    }
+
+    public InstanceIdentifier<L2gateway> buildL2gwIid(String l2gwName) {
+        String l2gwNameUuid = UUID.nameUUIDFromBytes(l2gwName.getBytes()).toString();
+        return InstanceIdentifier.create(Neutron.class).child(L2gateways.class)
+                .child(L2gateway.class, new L2gatewayKey(toUuid(l2gwNameUuid)));
+    }
+
+    public InstanceIdentifier<L2gatewayConnection> buildConnectionIid(String connectionName) {
+        String l2gwConnectionNameUuid = UUID.nameUUIDFromBytes(connectionName.getBytes()).toString();
+        return InstanceIdentifier.create(Neutron.class).child(L2gatewayConnections.class)
+                .child(L2gatewayConnection.class, new L2gatewayConnectionKey(toUuid(l2gwConnectionNameUuid)));
+    }
+
+    public Uuid toUuid(String name) {
+        return new Uuid(UUID.fromString(name).toString());
+    }
+
+    static InstanceIdentifier<Node> createInstanceIdentifier(String nodeIdString) {
+        org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId nodeId
+                = new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021
+                .NodeId(new Uri(nodeIdString));
+        org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology
+                .topology.NodeKey nodeKey = new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network
+                .topology.rev131021.network.topology.topology.NodeKey(nodeId);
+        TopologyKey topoKey = new TopologyKey(new TopologyId(new Uri("hwvtep:1")));
+        return InstanceIdentifier.builder(NetworkTopology.class)
+                .child(Topology.class, topoKey)
+                .child(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology
+                        .rev131021.network.topology.topology.Node.class, nodeKey)
+                .build();
+    }
+
+    public void buildTorNode(String torNodeId, String deviceName, String tepIp)
+            throws Exception {
+
+        InstanceIdentifier<Node> nodePath =
+                createInstanceIdentifier(torNodeId);
+        InstanceIdentifier<Node> psNodePath =
+                createInstanceIdentifier(torNodeId + "/physicalswitch/" + deviceName);
+
+        // Create PS node
+        NodeBuilder nodeBuilder = new NodeBuilder();
+        nodeBuilder.setNodeId(psNodePath.firstKeyOf(Node.class).getNodeId());
+        PhysicalSwitchAugmentationBuilder physicalSwitchAugmentationBuilder = new PhysicalSwitchAugmentationBuilder();
+        physicalSwitchAugmentationBuilder.setManagedBy(new HwvtepGlobalRef(nodePath));
+        physicalSwitchAugmentationBuilder.setPhysicalSwitchUuid(new Uuid(UUID.nameUUIDFromBytes(deviceName.getBytes())
+                .toString()));
+        physicalSwitchAugmentationBuilder.setHwvtepNodeName(new HwvtepNodeName(deviceName));
+        physicalSwitchAugmentationBuilder.setHwvtepNodeDescription("torNode");
+        List<TunnelIps> tunnelIps = new ArrayList<>();
+        IpAddress ip = new IpAddress(tepIp.toCharArray());
+        tunnelIps.add(new TunnelIpsBuilder().setKey(new TunnelIpsKey(ip)).setTunnelIpsKey(ip).build());
+        physicalSwitchAugmentationBuilder.setTunnelIps(tunnelIps);
+        nodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, physicalSwitchAugmentationBuilder.build());
+        singleTransactionDataBroker.syncWrite(LogicalDatastoreType.OPERATIONAL, psNodePath, nodeBuilder.build());
+
+        nodeBuilder = new NodeBuilder();
+        nodeBuilder.setNodeId(nodePath.firstKeyOf(Node.class).getNodeId());
+        HwvtepGlobalAugmentationBuilder builder = new HwvtepGlobalAugmentationBuilder();
+        builder.setDbVersion("1.6.0");
+        builder.setManagers(TestBuilders.buildManagers1());
+        GlobalAugmentationHelper.addSwitches(builder, psNodePath);
+        nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, builder.build());
+        singleTransactionDataBroker.syncWrite(LogicalDatastoreType.OPERATIONAL, nodePath, nodeBuilder.build());
+    }
+
+    public LocalUcastMacs createLocalUcastMac(InstanceIdentifier<Node> nodeId, String mac, String ipAddr,
+                                                     String tepIp) throws TransactionCommitFailedException {
+
+        NodeBuilder nodeBuilder = new NodeBuilder();
+        nodeBuilder.setNodeId(nodeId.firstKeyOf(Node.class).getNodeId());
+        final List<LocalUcastMacs> localUcastMacses = new ArrayList<>();
+        LocalUcastMacsBuilder localUcastMacsBuilder = new LocalUcastMacsBuilder();
+        localUcastMacsBuilder.setIpaddr(new IpAddress(ipAddr.toCharArray()));
+        localUcastMacsBuilder.setMacEntryKey(new MacAddress(mac));
+        localUcastMacsBuilder.setMacEntryUuid(getUUid(mac));
+        localUcastMacsBuilder.setLocatorRef(TestBuilders.buildLocatorRef(nodeId, tepIp));
+        localUcastMacsBuilder.setLogicalSwitchRef(TestBuilders.buildLogicalSwitchesRef(nodeId, ExpectedObjects.ELAN1));
+        LocalUcastMacs localUcastMacs = localUcastMacsBuilder.build();
+        localUcastMacses.add(localUcastMacs);
+        HwvtepGlobalAugmentationBuilder builder1 =
+                new HwvtepGlobalAugmentationBuilder().setLocalUcastMacs(localUcastMacses) ;
+        nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, builder1.build());
+        singleTransactionDataBroker.syncUpdate(LogicalDatastoreType.OPERATIONAL, nodeId, nodeBuilder.build());
+        return localUcastMacs;
+    }
+
+    public InstanceIdentifier<LocalUcastMacs> buildMacIid(InstanceIdentifier<Node> nodeIid, LocalUcastMacs mac) {
+        return nodeIid.augmentation(HwvtepGlobalAugmentation.class).child(LocalUcastMacs.class, mac.getKey());
+    }
+
+    public void deletel2GWConnection(String connectionName) throws TransactionCommitFailedException {
+        singleTransactionDataBroker.syncDelete(LogicalDatastoreType.CONFIGURATION, buildConnectionIid(connectionName));
+    }
+
+}
diff --git a/elanmanager/impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/Verifications.java b/elanmanager/impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/Verifications.java
new file mode 100644 (file)
index 0000000..9c364f0
--- /dev/null
@@ -0,0 +1,427 @@
+/*
+ * Copyright © 2017 Ericsson India Global Services Pvt Ltd. 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.netvirt.elanmanager.tests;
+
+import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
+
+import com.google.common.collect.Sets;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import org.awaitility.core.ConditionFactory;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
+import org.opendaylight.genius.testutils.interfacemanager.TunnelInterfaceDetails;
+import org.opendaylight.mdsal.binding.testutils.AssertDataObjects;
+import org.opendaylight.netvirt.elan.utils.ElanUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class Verifications {
+
+    private static final boolean CHECK_FOR_EXISTS = true;
+    private static final boolean CHECK_FOR_DELETED = false;
+    private static final Function<BigInteger, NodeId> GET_OPENFLOW_NODE_ID = (dpnId) -> new NodeId("openflow:" + dpnId);
+    private static final InstanceIdentifier<ElanInstance> ELAN_IID = InstanceIdentifier
+            .builder(ElanInstances.class)
+            .child(ElanInstance.class, new ElanInstanceKey(ExpectedObjects.ELAN1))
+            .build();
+    private static final BiPredicate<Group, Group> BUCKETS_SIZE_MIS_MATCHED = (actual, expected) -> {
+        return !(actual.getBuckets().getBucket().size() == expected.getBuckets().getBucket().size());
+    };
+
+    private final SingleTransactionDataBroker singleTxdataBroker;
+    private final OdlInterfaceRpcService odlInterfaceRpcService;
+    private final Map<String, TunnelInterfaceDetails> extnIntfs;
+    private final ConditionFactory awaiter;
+
+    public Verifications(final SingleTransactionDataBroker singleTxdataBroker,
+                         final OdlInterfaceRpcService odlInterfaceRpcService,
+                         final Map<String, TunnelInterfaceDetails> extnIntfs,
+                         final ConditionFactory awaiter) {
+        this.singleTxdataBroker = singleTxdataBroker;
+        this.odlInterfaceRpcService = odlInterfaceRpcService;
+        this.extnIntfs = extnIntfs;
+        this.awaiter = awaiter;
+    }
+
+    private void awaitForData(LogicalDatastoreType dsType, InstanceIdentifier<? extends DataObject> iid) {
+        awaiter.until(() -> singleTxdataBroker.syncReadOptional(dsType, iid).isPresent());
+    }
+
+    private void awaitForDataDelete(LogicalDatastoreType dsType, InstanceIdentifier<? extends DataObject> iid) {
+        awaiter.until(() -> !singleTxdataBroker.syncReadOptional(dsType, iid).isPresent());
+    }
+
+    public void verifyThatMcastMacTepsCreated(InstanceIdentifier<Node> torNodeId, List<String> tepIps) {
+        for (String tepIp : tepIps) {
+            awaiter.until(() -> checkForRemoteMcastMac(torNodeId, tepIp, CHECK_FOR_EXISTS));
+        }
+    }
+
+    public void verifyThatMcastMacTepsDeleted(InstanceIdentifier<Node> torNodeId, List<String> tepIps) {
+        for (String tepIp : tepIps) {
+            awaiter.until(() -> checkForRemoteMcastMac(torNodeId, tepIp, CHECK_FOR_DELETED));
+        }
+    }
+
+    private boolean checkForRemoteMcastMac(InstanceIdentifier<Node> torNodeId, String tepIp, boolean checkForExists) {
+        try {
+            Node node = singleTxdataBroker.syncRead(LogicalDatastoreType.CONFIGURATION, torNodeId);
+            HwvtepGlobalAugmentation augmentation = node.getAugmentation(HwvtepGlobalAugmentation.class);
+            if (augmentation == null || augmentation.getRemoteMcastMacs() == null
+                    || augmentation.getRemoteMcastMacs().isEmpty()) {
+                if (checkForExists) {
+                    return false;
+                } else {
+                    return true;
+                }
+            }
+            boolean remoteMcastFoundFlag = false;
+            for (RemoteMcastMacs remoteMcastMacs : augmentation.getRemoteMcastMacs()) {
+                for (LocatorSet locatorSet : remoteMcastMacs.getLocatorSet()) {
+                    TpId tpId = locatorSet.getLocatorRef().getValue().firstKeyOf(TerminationPoint.class).getTpId();
+                    if (tpId.getValue().contains(tepIp)) {
+                        remoteMcastFoundFlag = true;
+                        break;
+                    }
+                }
+            }
+            if (checkForExists) {
+                return (remoteMcastFoundFlag == true);
+            } else {
+                return (remoteMcastFoundFlag == false);
+            }
+        } catch (ReadFailedException e) {
+            return false;
+        }
+    }
+
+    public void verifyThatUcastCreated(InstanceIdentifier<Node> torNodeId, List<String> macs) {
+        for (String mac : macs) {
+            awaiter.until(() -> checkForRemoteUcastMac(torNodeId, mac, CHECK_FOR_EXISTS));
+        }
+    }
+
+    public void verifyThatUcastDeleted(InstanceIdentifier<Node> torNodeId, List<String> macs) {
+        for (String mac : macs) {
+            awaiter.until(() -> checkForRemoteUcastMac(torNodeId, mac, CHECK_FOR_DELETED));
+        }
+    }
+
+    public boolean checkForRemoteUcastMac(InstanceIdentifier<Node> torNodeId, String dpnMac, boolean checkForExists) {
+        try {
+            Node node = singleTxdataBroker.syncRead(LogicalDatastoreType.CONFIGURATION, torNodeId);
+            HwvtepGlobalAugmentation augmentation = node.getAugmentation(HwvtepGlobalAugmentation.class);
+            if (augmentation == null || augmentation.getRemoteUcastMacs() == null
+                    || augmentation.getRemoteUcastMacs().isEmpty()) {
+                if (checkForExists) {
+                    return false;
+                } else {
+                    return true;
+                }
+            }
+            boolean remoteUcastFoundFlag = false;
+            for (RemoteUcastMacs remoteUcastMacs : augmentation.getRemoteUcastMacs()) {
+                String mac = remoteUcastMacs.getMacEntryKey().getValue();
+                if (mac.equals(dpnMac)) {
+                    remoteUcastFoundFlag = true;
+                    break;
+                }
+            }
+            if (checkForExists) {
+                return (remoteUcastFoundFlag == true);
+            } else {
+                return (remoteUcastFoundFlag == false);
+            }
+        } catch (ReadFailedException e) {
+            return false;
+        }
+    }
+
+    private List<Bucket> buildRemoteBcGroupBuckets(ElanInstance elanInfo,
+                                                  List<BigInteger> otherDpns,
+                                                  List<String> otherTors,
+                                                  BigInteger dpnId,
+                                                  int bucketId)
+            throws ExecutionException, InterruptedException {
+        List<Bucket> listBucketInfo = new ArrayList<>();
+        if (otherDpns != null) {
+            for (BigInteger otherDpn : otherDpns) {
+                GetEgressActionsForInterfaceInput getEgressActInput = new GetEgressActionsForInterfaceInputBuilder()
+                        .setIntfName(extnIntfs.get(dpnId + ":" + otherDpn).getInterfaceInfo().getInterfaceName())
+                        .setTunnelKey(elanInfo.getElanTag()).build();
+                List<Action> actionsList =
+                        odlInterfaceRpcService.getEgressActionsForInterface(getEgressActInput).get().getResult()
+                                .getAction();
+                listBucketInfo.add(MDSALUtil.buildBucket(actionsList, MDSALUtil.GROUP_WEIGHT, bucketId,
+                        MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
+
+                bucketId++;
+            }
+        }
+
+        if (otherTors != null) {
+            for (String otherTor : otherTors) {
+                GetEgressActionsForInterfaceInput getEgressActInput = new GetEgressActionsForInterfaceInputBuilder()
+                        .setIntfName(extnIntfs.get(dpnId + ":" + otherTor).getInterfaceInfo().getInterfaceName())
+                        .setTunnelKey(elanInfo.getSegmentationId()).build();
+                List<Action> actionsList =
+                        odlInterfaceRpcService.getEgressActionsForInterface(getEgressActInput).get().getResult()
+                                .getAction();
+                listBucketInfo.add(MDSALUtil.buildBucket(actionsList, MDSALUtil.GROUP_WEIGHT, bucketId,
+                        MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
+
+                bucketId++;
+            }
+        }
+        return listBucketInfo;
+    }
+
+    private Group buildStandardElanBroadcastGroups(ElanInstance elanInfo, BigInteger dpnId, List<BigInteger> otherdpns,
+                                                  List<String> tepIps)
+            throws ExecutionException, InterruptedException {
+        List<Bucket> listBucket = new ArrayList<>();
+        int bucketId = 0;
+        int actionKey = 0;
+        Long elanTag = elanInfo.getElanTag();
+        List<Action> listAction = new ArrayList<>();
+        listAction.add(new ActionGroup(ElanUtils.getElanLocalBCGId(elanTag)).buildAction(++actionKey));
+        listBucket.add(MDSALUtil.buildBucket(listAction, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT,
+                MDSALUtil.WATCH_GROUP));
+        bucketId++;
+        listBucket.addAll(buildRemoteBcGroupBuckets(elanInfo, otherdpns, tepIps, dpnId, bucketId));
+        long groupId = ElanUtils.getElanRemoteBCGId(elanTag);
+        Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
+                MDSALUtil.buildBucketLists(listBucket));
+        return group;
+    }
+
+    private boolean validateGroup(ElanInstance actualElanInstances,
+                                 BigInteger dpnId,
+                                 List<BigInteger> otherdpns,
+                                 List<String> torips)
+            throws ExecutionException, InterruptedException, ReadFailedException, TransactionCommitFailedException {
+        Group expected = buildStandardElanBroadcastGroups(actualElanInstances, dpnId, otherdpns, torips);
+        InstanceIdentifier<Group> grpIid = DpnNodeBuilders.createGroupIid(expected, dpnId);
+        Group actual = singleTxdataBroker.syncRead(CONFIGURATION, grpIid);
+        singleTxdataBroker.syncWrite(CONFIGURATION, grpIid, expected);
+        expected = singleTxdataBroker.syncRead(CONFIGURATION, grpIid);
+
+        if (BUCKETS_SIZE_MIS_MATCHED.test(expected, actual)) {
+            AssertDataObjects.assertEqualBeans(expected, actual);
+        }
+
+        Set<Bucket> actualBuckets = modifyBucketId(actual.getBuckets().getBucket());
+        Set<Bucket> expectedBuckets = modifyBucketId(expected.getBuckets().getBucket());
+        Set<Bucket> diff = Sets.difference(actualBuckets, expectedBuckets);
+        if (diff != null && !diff.isEmpty()) {
+            AssertDataObjects.assertEqualBeans(expected, actual);
+        }
+        return true;
+    }
+
+    private Set<Bucket> modifyBucketId(List<Bucket> input) {
+        return input.stream()
+                .map(bucket -> new BucketBuilder(bucket).setBucketId(new BucketId(1L))
+                        .setKey(new BucketKey(new BucketId(1L))).build())
+                .collect(Collectors.toSet());
+    }
+
+    public void verifyThatDpnGroupUpdated(BigInteger dpnId, List<BigInteger> otherdpns, List<String> othertors)
+            throws ReadFailedException, TransactionCommitFailedException, ExecutionException, InterruptedException {
+        verifyDPNGroup(dpnId, otherdpns, othertors, CHECK_FOR_EXISTS);
+    }
+
+    public void verifyThatDpnGroupDeleted(BigInteger dpnId)
+            throws ReadFailedException, TransactionCommitFailedException, ExecutionException, InterruptedException {
+        verifyDPNGroup(dpnId, Collections.emptyList(), Collections.emptyList(), CHECK_FOR_DELETED);
+    }
+
+    public void verifyLocalBcGroup(BigInteger dpnId, int expectedNoBuckets)
+            throws ReadFailedException, TransactionCommitFailedException, ExecutionException, InterruptedException {
+        awaiter.until(() -> {
+            ElanInstance actualElanInstances = singleTxdataBroker.syncRead(CONFIGURATION, ELAN_IID);
+            InstanceIdentifier<Group> grpIid = buildLocalGroupIid(actualElanInstances, dpnId);
+            awaitForData(CONFIGURATION, grpIid);
+            Group localGroup = singleTxdataBroker.syncRead(CONFIGURATION, grpIid);
+            if (localGroup != null && localGroup.getBuckets() != null
+                    && localGroup.getBuckets().getBucket() != null) {
+                return localGroup.getBuckets().getBucket().size() == expectedNoBuckets;
+            }
+            return false;
+        });
+    }
+
+    public void verifyThatLocalBcGroupDeleted(BigInteger dpnId)
+            throws ReadFailedException, TransactionCommitFailedException, ExecutionException, InterruptedException {
+        ElanInstance actualElanInstances = singleTxdataBroker.syncRead(CONFIGURATION, ELAN_IID);
+        InstanceIdentifier<Group> grpIid = buildLocalGroupIid(actualElanInstances, dpnId);
+        awaitForDataDelete(CONFIGURATION, grpIid);
+    }
+
+    public void verifyDPNGroup(BigInteger dpnId,
+                               List<BigInteger> otherdpns,
+                               List<String> othertors,
+                               boolean checkForExists)
+            throws ReadFailedException, TransactionCommitFailedException, ExecutionException, InterruptedException {
+
+        ElanInstance actualElanInstances = singleTxdataBroker.syncRead(CONFIGURATION, ELAN_IID);
+        InstanceIdentifier<Group> grpIid = buildGroupIid(actualElanInstances, dpnId);
+
+        if (checkForExists) {
+            awaitForData(LogicalDatastoreType.CONFIGURATION, grpIid);
+            validateGroup(actualElanInstances, dpnId, otherdpns, othertors);
+        } else {
+            awaitForDataDelete(LogicalDatastoreType.CONFIGURATION, grpIid);
+        }
+    }
+
+    public void verifyThatDmacFlowOfTORCreated(List<BigInteger> dpns,
+                                               InstanceIdentifier<Node> torNodeId,
+                                               List<String> macs) throws ReadFailedException {
+        for (String mac : macs) {
+            for (BigInteger srcDpnId : dpns) {
+                verifyDmacFlowOfTOR(srcDpnId, torNodeId, mac, CHECK_FOR_EXISTS);
+            }
+        }
+    }
+
+    public void verifyThatDmacFlowOfTORDeleted(List<BigInteger> dpns,
+                                               InstanceIdentifier<Node> torNodeId,
+                                               List<String> macs) throws ReadFailedException {
+        for (String mac : macs) {
+            for (BigInteger srcDpnId : dpns) {
+                verifyDmacFlowOfTOR(srcDpnId, torNodeId, mac, CHECK_FOR_DELETED);
+            }
+        }
+    }
+
+    public void verifyDmacFlowOfTOR(BigInteger srcDpnId,
+                                    InstanceIdentifier<Node> torNodeIid,
+                                    String mac,
+                                    boolean checkForExists) throws ReadFailedException {
+
+        String torNodeId = torNodeIid.firstKeyOf(Node.class).getNodeId().getValue();
+        ElanInstance actualElanInstances = singleTxdataBroker.syncRead(CONFIGURATION, ELAN_IID);
+        FlowId flowId = new FlowId(
+                ElanUtils.getKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE,
+                        srcDpnId,
+                        torNodeId,
+                        mac,
+                        actualElanInstances.getElanTag(),
+                        false));
+
+        InstanceIdentifier<Flow> flowIid = getFlowIid(NwConstants.ELAN_DMAC_TABLE, flowId, srcDpnId);
+
+        if (checkForExists) {
+            awaitForData(LogicalDatastoreType.CONFIGURATION, flowIid);
+        } else {
+            awaitForDataDelete(LogicalDatastoreType.CONFIGURATION, flowIid);
+        }
+    }
+
+    public void  verifyThatDmacOfOtherDpnCreated(BigInteger srcDpnId, BigInteger dpnId, List<String> dpnMacs)
+            throws ReadFailedException, InterruptedException {
+        for (String dpnMac : dpnMacs) {
+            verifyDmacFlowOfOtherDPN(srcDpnId, dpnId, dpnMac, CHECK_FOR_EXISTS);
+        }
+    }
+
+    public void  verifyThatDmacOfOtherDPNDeleted(BigInteger srcDpnId, BigInteger dpnId, List<String> dpnMacs)
+            throws ReadFailedException, InterruptedException {
+        for (String dpnMac : dpnMacs) {
+            verifyDmacFlowOfOtherDPN(srcDpnId, dpnId, dpnMac, CHECK_FOR_DELETED);
+        }
+    }
+
+    private void  verifyDmacFlowOfOtherDPN(BigInteger srcDpnId, BigInteger dpnId, String dpnMac, boolean createFlag)
+            throws ReadFailedException, InterruptedException {
+        InstanceIdentifier<ElanInstance> elanInstanceIid = InstanceIdentifier.builder(ElanInstances.class)
+                .child(ElanInstance.class, new ElanInstanceKey(ExpectedObjects.ELAN1)).build();
+        ElanInstance actualElanInstances = singleTxdataBroker.syncRead(CONFIGURATION, elanInstanceIid);
+        FlowId flowId = new FlowId(
+                ElanUtils.getKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE,
+                        srcDpnId,
+                        dpnId,
+                        dpnMac,
+                        actualElanInstances.getElanTag()));
+        InstanceIdentifier<Flow> flowInstanceIidDst = getFlowIid(NwConstants.ELAN_DMAC_TABLE, flowId, srcDpnId);
+        if (createFlag) {
+            awaitForData(LogicalDatastoreType.CONFIGURATION, flowInstanceIidDst);
+        } else {
+            awaitForDataDelete(LogicalDatastoreType.CONFIGURATION, flowInstanceIidDst);
+        }
+    }
+
+    private InstanceIdentifier<Flow> getFlowIid(short tableId, FlowId flowid, BigInteger dpnId) {
+
+        FlowKey flowKey = new FlowKey(new FlowId(flowid));
+        NodeId nodeId = GET_OPENFLOW_NODE_ID.apply(dpnId);
+        org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node nodeDpn =
+                new NodeBuilder().setId(nodeId).setKey(new NodeKey(nodeId)).build();
+        return InstanceIdentifier.builder(Nodes.class)
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
+                        nodeDpn.getKey()).augmentation(FlowCapableNode.class)
+                .child(Table.class, new TableKey(tableId)).child(Flow.class, flowKey).build();
+    }
+
+    private InstanceIdentifier<Group> buildGroupIid(ElanInstance actualElanInstances, BigInteger dpnId) {
+        return DpnNodeBuilders.buildGroupInstanceIdentifier(
+                ElanUtils.getElanRemoteBCGId(actualElanInstances.getElanTag()), DpnNodeBuilders.buildDpnNode(dpnId));
+    }
+
+    private InstanceIdentifier<Group> buildLocalGroupIid(ElanInstance actualElanInstances, BigInteger dpnId) {
+        return DpnNodeBuilders.buildGroupInstanceIdentifier(
+                ElanUtils.getElanLocalBCGId(actualElanInstances.getElanTag()), DpnNodeBuilders.buildDpnNode(dpnId));
+    }
+}
index f1352c5d03cc390d079ada6b09710c5f393b0c11..a6a7f9744695d2cacf9acbfe13dbf47017ce55b2 100644 (file)
@@ -15,8 +15,12 @@ import java.util.concurrent.Future;
 import org.mockito.Mockito;
 import org.opendaylight.genius.interfacemanager.IfmUtil;
 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.genius.testutils.TestInterfaceManager;
 import org.opendaylight.genius.tools.mdsal.rpc.FutureRpcResults;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutputBuilder;
@@ -30,10 +34,13 @@ import org.slf4j.LoggerFactory;
 public abstract class ElanEgressActionsHelper implements OdlInterfaceRpcService {
     private static final Logger LOG = LoggerFactory.getLogger(ElanEgressActionsHelper.class);
     private InterfaceManagerCommonUtils interfaceManagerCommonUtils;
+    private TestInterfaceManager testInterfaceManager;
 
-    public static ElanEgressActionsHelper newInstance(InterfaceManagerCommonUtils interfaceManagerCommonUtils) {
+    public static ElanEgressActionsHelper newInstance(InterfaceManagerCommonUtils interfaceManagerCommonUtils,
+                                                      TestInterfaceManager testInterfaceManager) {
         ElanEgressActionsHelper instance = Mockito.mock(ElanEgressActionsHelper.class, realOrException());
         instance.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
+        instance.testInterfaceManager = testInterfaceManager;
         return instance;
     }
 
@@ -46,4 +53,13 @@ public abstract class ElanEgressActionsHelper implements OdlInterfaceRpcService
             return new GetEgressActionsForInterfaceOutputBuilder().setAction(actionsList);
         }).build();
     }
+
+    @Override
+    public Future<RpcResult<GetDpidFromInterfaceOutput>> getDpidFromInterface(
+            GetDpidFromInterfaceInput input) {
+        return FutureRpcResults.fromBuilder(LOG, input, () -> {
+            return new GetDpidFromInterfaceOutputBuilder().setDpid(
+                    testInterfaceManager.getDpnForInterface(input.getIntfName()));
+        }).build();
+    }
 }