ELAN L2GW Junit Test Cases
[netvirt.git] / elanmanager / impl / src / test / java / org / opendaylight / netvirt / elanmanager / tests / ElanServiceTest.java
1 /*
2  * Copyright (C) 2016, 2017 Red Hat Inc., and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.netvirt.elanmanager.tests;
9
10 import static java.util.Arrays.asList;
11 import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
12
13 import com.google.common.base.Optional;
14
15 import java.util.List;
16 import javax.inject.Inject;
17
18 import org.junit.After;
19 import org.junit.Before;
20 import org.junit.Rule;
21 import org.junit.Test;
22 import org.junit.rules.MethodRule;
23 import org.mockito.Mockito;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
26 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
27 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
28 import org.opendaylight.genius.datastoreutils.testutils.JobCoordinatorTestModule;
29 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
30 import org.opendaylight.genius.mdsalutil.MDSALUtil;
31 import org.opendaylight.genius.mdsalutil.NwConstants;
32 import org.opendaylight.genius.testutils.interfacemanager.TunnelInterfaceDetails;
33 import org.opendaylight.genius.utils.batching.ResourceBatchingManager;
34 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils;
35 import org.opendaylight.infrautils.caches.testutils.CacheModule;
36 import org.opendaylight.infrautils.inject.guice.testutils.GuiceRule;
37 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
38 import org.opendaylight.infrautils.jobcoordinator.internal.JobCoordinatorImpl;
39 import org.opendaylight.infrautils.metrics.MetricProvider;
40 import org.opendaylight.infrautils.metrics.testimpl.TestMetricProviderImpl;
41 import org.opendaylight.infrautils.testutils.LogRule;
42 import org.opendaylight.mdsal.binding.testutils.AssertDataObjects;
43 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
44 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
45 import org.opendaylight.netvirt.elan.cache.ElanInstanceDpnsCache;
46 import org.opendaylight.netvirt.elan.evpn.listeners.ElanMacEntryListener;
47 import org.opendaylight.netvirt.elan.evpn.listeners.EvpnElanInstanceListener;
48 import org.opendaylight.netvirt.elan.evpn.listeners.MacVrfEntryListener;
49 import org.opendaylight.netvirt.elan.evpn.utils.EvpnUtils;
50 import org.opendaylight.netvirt.elan.internal.ElanDpnInterfaceClusteredListener;
51 import org.opendaylight.netvirt.elan.internal.ElanExtnTepConfigListener;
52 import org.opendaylight.netvirt.elan.internal.ElanExtnTepListener;
53 import org.opendaylight.netvirt.elan.internal.ElanInterfaceManager;
54 import org.opendaylight.netvirt.elan.l2gw.listeners.HwvtepPhysicalSwitchListener;
55 import org.opendaylight.netvirt.elan.l2gw.listeners.L2GatewayConnectionListener;
56 import org.opendaylight.netvirt.elan.l2gw.listeners.LocalUcastMacListener;
57 import org.opendaylight.netvirt.elan.l2gw.nodehandlertest.DataProvider;
58 import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayUtils;
59 import org.opendaylight.netvirt.elan.utils.ElanUtils;
60 import org.opendaylight.netvirt.elanmanager.api.IElanService;
61 import org.opendaylight.netvirt.elanmanager.api.IL2gwService;
62 import org.opendaylight.netvirt.elanmanager.tests.utils.EvpnTestHelper;
63 import org.opendaylight.netvirt.elanmanager.utils.ElanL2GwCacheUtils;
64 import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayCache;
65 import org.opendaylight.netvirt.neutronvpn.l2gw.L2GatewayListener;
66 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
67 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp;
68 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Networks;
69 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksKey;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
81 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
82 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
83 import org.slf4j.Logger;
84 import org.slf4j.LoggerFactory;
85
86
87 /**
88  * End-to-end test of IElanService.
89  *
90  * @author Michael Vorburger
91  * @author Riyazahmed Talikoti
92  */
93 public class ElanServiceTest extends  ElanServiceTestBase {
94
95     private static final Logger LOG = LoggerFactory.getLogger(ElanServiceTest.class);
96
97     // TODO as-is, this test is flaky; as uncommenting will show
98     // Uncomment this to keep running this test indefinitely
99     // This is very useful to detect concurrency issues (such as https://bugs.opendaylight.org/show_bug.cgi?id=7538)
100     // public static @ClassRule RunUntilFailureClassRule classRepeater = new RunUntilFailureClassRule();
101     // public @Rule RunUntilFailureRule repeater = new RunUntilFailureRule(classRepeater);
102
103     public @Rule LogRule logRule = new LogRule();
104     public @Rule MethodRule guice = new GuiceRule(ElanServiceTestModule.class, JobCoordinatorTestModule.class,
105             CacheModule.class);
106     // TODO re-enable after we can await completion of listeners and DJC:
107     // Otherwise this too frequently causes spurious test failures, e.g. due to error
108     // logs Caused by: java.lang.RuntimeException: java.util.concurrent.ExecutionException: Operation was interrupted
109     // public @Rule LogCaptureRule logCaptureRule = new LogCaptureRule();
110     private @Inject IElanService elanService;
111     private @Inject IdManagerService idManager;
112     private @Inject EvpnElanInstanceListener evpnElanInstanceListener;
113     private @Inject ElanMacEntryListener elanMacEntryListener;
114     private @Inject MacVrfEntryListener macVrfEntryListener;
115     private @Inject EvpnUtils evpnUtils;
116     private @Inject IBgpManager bgpManager;
117     private @Inject IVpnManager vpnManager;
118     private @Inject EvpnTestHelper evpnTestHelper;
119     private @Inject OdlInterfaceRpcService odlInterfaceRpcService;
120     private @Inject ElanL2GatewayUtils elanL2GatewayUtils;
121     private @Inject ElanInterfaceManager elanInterfaceManager;
122     private @Inject HwvtepPhysicalSwitchListener hwvtepPhysicalSwitchListener;
123     private @Inject L2GatewayConnectionListener l2GatewayConnectionListener;
124     private @Inject LocalUcastMacListener localUcastMacListener;
125     private @Inject ElanDpnInterfaceClusteredListener elanDpnInterfaceClusteredListener;
126     private @Inject EntityOwnershipService mockedEntityOwnershipService;
127     private @Inject L2GatewayCache l2GatewayCache;
128     private @Inject ElanUtils elanUtils;
129     private @Inject ElanInstanceDpnsCache elanInstanceDpnsCache;
130     private @Inject ElanExtnTepConfigListener elanExtnTepConfigListener;
131     private @Inject ElanExtnTepListener elanExtnTepListener;
132
133     private L2GatewayListener l2gwListener;
134     private MetricProvider metricProvider = new TestMetricProviderImpl();
135
136     private Verifications verifications;
137     private L2gwBuilders l2gwBuilders;
138
139     private SingleTransactionDataBroker singleTxdataBroker;
140
141     @Before public void before() throws Exception {
142
143         singleTxdataBroker = new SingleTransactionDataBroker(dataBroker);
144         verifications = new Verifications(singleTxdataBroker, odlInterfaceRpcService, EXTN_INTFS, getAwaiter());
145         l2gwBuilders = new L2gwBuilders(singleTxdataBroker);
146         JobCoordinator jobCoordinator = new JobCoordinatorImpl(metricProvider);
147
148         l2gwListener = new L2GatewayListener(dataBroker, mockedEntityOwnershipService,
149                 Mockito.mock(ItmRpcService.class), Mockito.mock(IL2gwService.class), jobCoordinator, l2GatewayCache);
150         l2gwListener.init();
151         setupItm();
152         l2gwBuilders.buildTorNode(TOR2_NODE_ID, PS2, TOR2_TEPIP);
153         l2gwBuilders.buildTorNode(TOR1_NODE_ID, PS1, TOR1_TEPIP);
154     }
155
156     @After public void after() throws Exception {
157         for (ResourceBatchingManager.ShardResource i : ResourceBatchingManager.ShardResource.values()) {
158             ResourceBatchingManager.getInstance().deregisterBatchableResource(i.name());
159         }
160
161         ElanL2GwCacheUtils.removeL2GatewayDeviceFromAllElanCache(TOR1_NODE_ID);
162         ElanL2GwCacheUtils.removeL2GatewayDeviceFromAllElanCache(TOR2_NODE_ID);
163
164         ElanL2GwCacheUtils.removeL2GatewayDeviceFromCache(ExpectedObjects.ELAN1, TOR1_NODE_ID);
165         ElanL2GwCacheUtils.removeL2GatewayDeviceFromCache(ExpectedObjects.ELAN1, TOR2_NODE_ID);
166     }
167
168     @Test public void elanServiceTestModule() {
169         // Intentionally empty; the goal is just to first test the ElanServiceTestModule
170     }
171
172     void createL2gwL2gwconn(InstanceIdentifier<Node> nodePath,
173                             String l2gwName,
174                             String deviceName,
175                             List<String> ports,
176                             String connectionName)
177             throws InterruptedException, TransactionCommitFailedException {
178
179         //Create l2gw
180         singleTxdataBroker.syncWrite(LogicalDatastoreType.CONFIGURATION,
181                 l2gwBuilders.buildL2gwIid(l2gwName), l2gwBuilders.buildL2gw(l2gwName, deviceName, ports));
182         awaitForData(LogicalDatastoreType.CONFIGURATION, l2gwBuilders.buildL2gwIid(l2gwName));
183
184         //Create l2gwconn
185         singleTxdataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
186                 l2gwBuilders.buildConnectionIid(connectionName), l2gwBuilders.buildConnection(connectionName,
187                         l2gwName, ExpectedObjects.ELAN1, 100));
188         awaitForData(LogicalDatastoreType.CONFIGURATION, l2gwBuilders.buildConnectionIid(connectionName));
189
190         //check for Config Logical Switch creation
191         InstanceIdentifier logicalSwitchesInstanceIdentifier =
192                 HwvtepSouthboundUtils.createLogicalSwitchesInstanceIdentifier(
193                         nodePath.firstKeyOf(Node.class).getNodeId(),
194                         new HwvtepNodeName(ExpectedObjects.ELAN1));
195         awaitForData(LogicalDatastoreType.CONFIGURATION, logicalSwitchesInstanceIdentifier);
196
197         //create operational logical switch
198         Optional<LogicalSwitches> logicalSwitchesOptional =
199                 MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, logicalSwitchesInstanceIdentifier);
200         LogicalSwitches logicalSwitches = logicalSwitchesOptional.isPresent() ? logicalSwitchesOptional.get() : null ;
201         MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
202                 logicalSwitchesInstanceIdentifier, logicalSwitches);
203         awaitForData(LogicalDatastoreType.OPERATIONAL, logicalSwitchesInstanceIdentifier);
204     }
205
206     @Test public void checkSMAC() throws Exception {
207         // Create Elan instance
208         createElanInstance(ExpectedObjects.ELAN1, ExpectedObjects.ELAN1_SEGMENT_ID);
209         awaitForElanTag(ExpectedObjects.ELAN1);
210
211         // Add Elan interface
212         InterfaceInfo interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC1).getLeft();
213         addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN1IP1);
214
215         // Read Elan instance
216         InstanceIdentifier<ElanInstance> elanInstanceIid = InstanceIdentifier.builder(ElanInstances.class)
217                 .child(ElanInstance.class, new ElanInstanceKey(ExpectedObjects.ELAN1)).build();
218         ElanInstance actualElanInstances = singleTxdataBroker.syncRead(CONFIGURATION, elanInstanceIid);
219
220         // Read and Compare SMAC flow
221         String flowId =  new StringBuffer()
222                 .append(NwConstants.ELAN_SMAC_TABLE)
223                 .append(actualElanInstances.getElanTag())
224                 .append(DPN1_ID)
225                 .append(interfaceInfo.getInterfaceTag())
226                 .append(interfaceInfo.getMacAddress())
227                 .toString();
228         InstanceIdentifier<Flow> flowInstanceIidSrc = getFlowIid(NwConstants.ELAN_SMAC_TABLE,
229                 new FlowId(flowId), DPN1_ID);
230         awaitForData(LogicalDatastoreType.CONFIGURATION, flowInstanceIidSrc);
231
232         Flow flowSrc = singleTxdataBroker.syncRead(CONFIGURATION, flowInstanceIidSrc);
233         flowSrc = getFlowWithoutCookie(flowSrc);
234
235         Flow expected = ExpectedObjects.checkSmac(flowId, interfaceInfo, actualElanInstances);
236         AssertDataObjects.assertEqualBeans(expected, flowSrc);
237     }
238
239     @Test public void checkDmacSameDPN() throws Exception {
240         // Create Elan instance
241         createElanInstance(ExpectedObjects.ELAN1, ExpectedObjects.ELAN1_SEGMENT_ID);
242         awaitForElanTag(ExpectedObjects.ELAN1);
243
244         // Add Elan interface in DPN1
245         InterfaceInfo interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC1).getLeft();
246         addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN1IP1);
247
248         // Read Elan instance
249         InstanceIdentifier<ElanInstance> elanInstanceIid = InstanceIdentifier.builder(ElanInstances.class)
250                 .child(ElanInstance.class, new ElanInstanceKey(ExpectedObjects.ELAN1)).build();
251         ElanInstance actualElanInstances = singleTxdataBroker.syncRead(CONFIGURATION, elanInstanceIid);
252
253         // Read DMAC Flow in DPN1
254         String flowId =  new StringBuffer()
255                 .append(NwConstants.ELAN_DMAC_TABLE)
256                 .append(actualElanInstances.getElanTag())
257                 .append(DPN1_ID)
258                 .append(interfaceInfo.getInterfaceTag())
259                 .append(interfaceInfo.getMacAddress())
260                 .toString();
261         InstanceIdentifier<Flow> flowInstanceIidDst = getFlowIid(NwConstants.ELAN_DMAC_TABLE,
262                 new FlowId(flowId), DPN1_ID);
263         awaitForData(LogicalDatastoreType.CONFIGURATION, flowInstanceIidDst);
264
265         Flow flowDst = singleTxdataBroker.syncRead(CONFIGURATION, flowInstanceIidDst);
266         flowDst = getFlowWithoutCookie(flowDst);
267
268         Flow expected = ExpectedObjects.checkDmacOfSameDpn(flowId, interfaceInfo, actualElanInstances);
269         AssertDataObjects.assertEqualBeans(getSortedActions(expected), getSortedActions(flowDst));
270     }
271
272     @Test public void checkDmacOfOtherDPN() throws Exception {
273         // Create Elan instance
274         createElanInstance(ExpectedObjects.ELAN1, ExpectedObjects.ELAN1_SEGMENT_ID);
275         awaitForElanTag(ExpectedObjects.ELAN1);
276
277         InterfaceInfo interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC1).getLeft();
278         addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN1IP1);
279
280         // Read Elan instance
281         InstanceIdentifier<ElanInstance> elanInstanceIid = InstanceIdentifier.builder(ElanInstances.class)
282                 .child(ElanInstance.class, new ElanInstanceKey(ExpectedObjects.ELAN1)).build();
283         ElanInstance actualElanInstances = singleTxdataBroker.syncRead(CONFIGURATION, elanInstanceIid);
284
285         interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN2MAC1).getLeft();
286         addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN2IP1);
287
288         // Read and Compare DMAC flow in DPN1 for MAC1 of DPN2
289         String flowId = ElanUtils.getKnownDynamicmacFlowRef((short)51,
290                         DPN1_ID,
291                         DPN2_ID,
292                         interfaceInfo.getMacAddress().toString(),
293                         actualElanInstances.getElanTag());
294
295         InstanceIdentifier<Flow> flowInstanceIidDst = getFlowIid(NwConstants.ELAN_DMAC_TABLE,
296                 new FlowId(flowId), DPN1_ID);
297         awaitForData(LogicalDatastoreType.CONFIGURATION, flowInstanceIidDst);
298
299         Flow flowDst = singleTxdataBroker.syncRead(CONFIGURATION, flowInstanceIidDst);
300         flowDst = getFlowWithoutCookie(flowDst);
301
302         TunnelInterfaceDetails tepDetails = EXTN_INTFS.get(DPN1_ID_STR + ":" + DPN2_ID_STR);
303         Flow expected = ExpectedObjects.checkDmacOfOtherDPN(flowId, interfaceInfo, tepDetails,
304                 actualElanInstances);
305         AssertDataObjects.assertEqualBeans(getSortedActions(expected), getSortedActions(flowDst));
306     }
307
308     @Test public void checkEvpnAdvRT2() throws Exception {
309         createElanInstanceAndInterfaceAndAttachEvpn();
310
311
312         AssertDataObjects.assertEqualBeans(
313                 ExpectedObjects.checkEvpnAdvertiseRoute(ELAN1_SEGMENT_ID, DPN1MAC1, DPN1_TEPIP, DPN1IP1, RD),
314                 readBgpNetworkFromDS(DPN1IP1));
315     }
316
317     @Test public void checkEvpnAdvRT2NewInterface() throws Exception {
318         createElanInstanceAndInterfaceAndAttachEvpn();
319
320         // Add Elan interface
321         addElanInterface(ExpectedObjects.ELAN1, ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC2).getLeft(), DPN1IP2);
322
323         AssertDataObjects.assertEqualBeans(
324                 ExpectedObjects.checkEvpnAdvertiseRoute(ELAN1_SEGMENT_ID, DPN1MAC2, DPN1_TEPIP, DPN1IP2, RD),
325                 readBgpNetworkFromDS(DPN1IP2));
326     }
327
328     @Test public void checkEvpnWithdrawRT2DelIntf() throws Exception {
329         createElanInstanceAndInterfaceAndAttachEvpn();
330
331         InstanceIdentifier<Networks> iid = evpnTestHelper.buildBgpNetworkIid(DPN1IP1);
332         awaitForData(LogicalDatastoreType.CONFIGURATION, iid);
333
334         evpnTestHelper.deleteRdtoNetworks();
335
336         deleteElanInterface(ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC1).getLeft());
337         awaitForDataDelete(LogicalDatastoreType.CONFIGURATION, iid);
338     }
339
340     @Test public void checkEvpnWithdrawRouteDetachEvpn() throws Exception {
341         createElanInstanceAndInterfaceAndAttachEvpn();
342         addElanInterface(ExpectedObjects.ELAN1, ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC2).getLeft(), DPN1IP2);
343
344         awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP1));
345         awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP2));
346
347         evpnTestHelper.detachEvpnToNetwork(ExpectedObjects.ELAN1);
348
349         awaitForDataDelete(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP1));
350         awaitForDataDelete(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP2));
351     }
352
353     @Test public void checkEvpnInstalDmacFlow() throws Exception {
354         createElanInstanceAndInterfaceAndAttachEvpn();
355         addElanInterface(ExpectedObjects.ELAN1, ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC2).getLeft(), DPN1IP2);
356
357         // Verify advertise RT2 route success for both MAC's
358         awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP1));
359         awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP2));
360
361         // RT2 received from Peer
362         evpnTestHelper.handleEvpnRt2Recvd(EVPNRECVMAC1, EVPNRECVIP1);
363         evpnTestHelper.handleEvpnRt2Recvd(EVPNRECVMAC2, EVPNRECVIP2);
364
365         // verify successful installation of DMAC flow for recvd rt2
366         awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildMacVrfEntryIid(EVPNRECVMAC1));
367         awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildMacVrfEntryIid(EVPNRECVMAC2));
368     }
369
370     @Test public void checkEvpnUnInstalDmacFlow() throws Exception {
371         createElanInstanceAndInterfaceAndAttachEvpn();
372         addElanInterface(ExpectedObjects.ELAN1, ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC2).getLeft(), DPN1IP2);
373
374         // Verify advertise RT2 route success for both MAC's
375         awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP1));
376         awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP2));
377
378         // RT2 received from Peer
379         evpnTestHelper.handleEvpnRt2Recvd(EVPNRECVMAC1, EVPNRECVIP1);
380         evpnTestHelper.handleEvpnRt2Recvd(EVPNRECVMAC2, EVPNRECVIP2);
381
382         // verify successful installation of DMAC flow for recvd rt2
383         awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildMacVrfEntryIid(EVPNRECVMAC1));
384         awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildMacVrfEntryIid(EVPNRECVMAC2));
385
386         // withdraw RT2 received from Peer
387         evpnTestHelper.deleteMacVrfEntryToDS(RD, EVPNRECVMAC1);
388         evpnTestHelper.deleteMacVrfEntryToDS(RD, EVPNRECVMAC2);
389
390         // verify successful un-installation of DMAC flow for recvd rt2
391         awaitForDataDelete(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildMacVrfEntryIid(EVPNRECVMAC1));
392         awaitForDataDelete(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildMacVrfEntryIid(EVPNRECVMAC2));
393     }
394
395     public void createElanInstanceAndInterfaceAndAttachEvpn() throws ReadFailedException,
396             TransactionCommitFailedException {
397         // Create Elan instance
398         createElanInstance(ExpectedObjects.ELAN1, ExpectedObjects.ELAN1_SEGMENT_ID);
399         awaitForElanTag(ExpectedObjects.ELAN1);
400
401         // Read Elan Instance
402         InstanceIdentifier<ElanInstance> elanInstanceIid = InstanceIdentifier.builder(ElanInstances.class)
403                 .child(ElanInstance.class, new ElanInstanceKey(ExpectedObjects.ELAN1)).build();
404         ElanInstance elanInstance = singleTxdataBroker.syncRead(CONFIGURATION, elanInstanceIid);
405
406         // Add Elan interface
407         addElanInterface(ExpectedObjects.ELAN1, ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC1).getLeft(), DPN1IP1);
408
409         // Attach EVPN to networks
410         evpnTestHelper.attachEvpnToNetwork(elanInstance);
411     }
412
413     public Networks readBgpNetworkFromDS(String prefix) throws ReadFailedException {
414         InstanceIdentifier<Networks> iid = InstanceIdentifier.builder(Bgp.class)
415                 .child(Networks.class, new NetworksKey(prefix, RD))
416                 .build();
417         awaitForData(LogicalDatastoreType.CONFIGURATION, iid);
418
419         return singleTxdataBroker.syncRead(CONFIGURATION, iid);
420     }
421
422     private void awaitForElanTag(String elanName) {
423         InstanceIdentifier<ElanInstance> elanInstanceIid = InstanceIdentifier.builder(ElanInstances.class)
424                 .child(ElanInstance.class, new ElanInstanceKey(elanName)).build();
425         getAwaiter().until(() -> {
426             Optional<ElanInstance> elanInstance = MDSALUtil.read(dataBroker, CONFIGURATION, elanInstanceIid);
427             return elanInstance.isPresent() && elanInstance.get().getElanTag() != null;
428         });
429     }
430
431     public void verifyL2gw1Connection() throws Exception {
432
433         //Create ELAN
434         createElanInstance(ExpectedObjects.ELAN1, ExpectedObjects.ELAN1_SEGMENT_ID);
435         awaitForElanTag(ExpectedObjects.ELAN1);
436
437         //Add Elan MAC1, MAC2 in DPN1
438         InterfaceInfo interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC1).getLeft();
439         addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN1IP1);
440         interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC2).getLeft();
441         addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN1IP2);
442
443         //Add Elan MAC1, MAC2 in DPN2
444         interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN2MAC1).getLeft();
445         addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN2IP1);
446         verifications.verifyLocalBcGroup(DPN2_ID, 1);
447
448         interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN2MAC2).getLeft();
449         addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN2IP2);
450         verifications.verifyLocalBcGroup(DPN2_ID, 2);
451
452         createL2gwL2gwconn(TOR1_NODE_IID, L2GW1, PS1, DataProvider.getPortNameListD1(), L2GW_CONN1);
453
454         verifications.verifyThatMcastMacTepsCreated(TOR1_NODE_IID, asList(DPN1_TEPIP, DPN2_TEPIP));
455         verifications.verifyThatUcastCreated(TOR1_NODE_IID, asList(DPN1MAC1, DPN1MAC2, DPN2MAC1, DPN2MAC2));
456         verifications.verifyThatDpnGroupUpdated(DPN1_ID, asList(DPN2_ID), asList(TOR1_TEPIP));
457         verifications.verifyThatDpnGroupUpdated(DPN2_ID, asList(DPN1_ID), asList(TOR1_TEPIP));
458     }
459
460     public void verifyL2gwMac1InDpns() throws Exception {
461         verifyL2gw1Connection();
462         l2gwBuilders.createLocalUcastMac(TOR1_NODE_IID, TOR1_MAC1, TOR1_IP1, TOR1_TEPIP);
463         verifications.verifyThatDmacFlowOfTORCreated(asList(DPN1_ID, DPN2_ID), TOR1_NODE_IID, asList(TOR1_MAC1));
464     }
465
466     public void verifyL2gw2Connection() throws Exception {
467         verifyL2gwMac1InDpns();
468         // TOR Node 2 creation
469         createL2gwL2gwconn(TOR2_NODE_IID, L2GW2, PS2, DataProvider.getPortNameListTor2(), L2GW_CONN2);
470         //check for remote mcast mac in tor2 against TEPs of dpn1, dpn2 and dpn3, tor1)
471         verifications.verifyThatMcastMacTepsCreated(TOR2_NODE_IID, asList(DPN1_TEPIP, DPN2_TEPIP, TOR1_TEPIP));
472         verifications.verifyThatMcastMacTepsCreated(TOR1_NODE_IID, asList(DPN1_TEPIP, DPN2_TEPIP, TOR2_TEPIP));
473         verifications.verifyThatUcastCreated(TOR2_NODE_IID, asList(DPN1MAC1, DPN2MAC1, DPN2MAC1, DPN2MAC2, TOR1_MAC1));
474     }
475
476     @Test
477     public void verifyL2gwMac2InTors() throws Exception {
478         verifyL2gw2Connection();
479         l2gwBuilders.createLocalUcastMac(TOR1_NODE_IID, TOR1_MAC2, TOR1_IP2, TOR1_TEPIP);
480         verifications.verifyThatUcastCreated(TOR2_NODE_IID, asList(TOR1_MAC2));
481     }
482
483     @Test
484     public void verifyL2gwMacDeleteInTors() throws Exception {
485         verifyL2gwMac2InTors();
486         LocalUcastMacs localUcastMacs1 = l2gwBuilders.createLocalUcastMac(
487                 TOR1_NODE_IID, TOR1_MAC1, TOR1_IP1, TOR1_TEPIP);
488         singleTxdataBroker.syncDelete(LogicalDatastoreType.OPERATIONAL,
489                 l2gwBuilders.buildMacIid(TOR1_NODE_IID, localUcastMacs1));
490         verifications.verifyThatDmacFlowOfTORDeleted(asList(DPN1_ID, DPN2_ID), TOR1_NODE_IID, asList(TOR1_MAC1));
491         verifications.verifyThatUcastDeleted(TOR2_NODE_IID, asList(TOR1_MAC1));
492     }
493
494     @Test
495     public void verifyAddDpnAfterL2gwConnection() throws Exception {
496         verifyL2gwMac2InTors();
497         //Add Elan MAC1, MAC2 in DPN3
498         InterfaceInfo interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN3MAC1).getLeft();
499         addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN3IP1);
500
501         //bc group of this dpn created
502         verifications.verifyThatDpnGroupUpdated(DPN3_ID, asList(DPN1_ID, DPN2_ID), asList(TOR1_NODE_ID, TOR2_NODE_ID));
503         //other tors macs be installed in this dpn
504         verifications.verifyThatDmacFlowOfTORCreated(asList(DPN3_ID), TOR1_NODE_IID, asList(TOR1_MAC1));
505         verifications.verifyThatDmacOfOtherDpnCreated(DPN3_ID, DPN1_ID, asList(DPN1MAC1, DPN1MAC2));
506         verifications.verifyThatDmacOfOtherDpnCreated(DPN3_ID, DPN2_ID, asList(DPN2MAC1, DPN2MAC2));
507
508         //bc group of the other dpns be updated
509         verifications.verifyThatDpnGroupUpdated(DPN1_ID, asList(DPN2_ID, DPN3_ID), asList(TOR1_NODE_ID, TOR2_NODE_ID));
510         verifications.verifyThatDpnGroupUpdated(DPN2_ID, asList(DPN1_ID, DPN3_ID), asList(TOR1_NODE_ID, TOR2_NODE_ID));
511
512         //mcast of tor should be updated
513         verifications.verifyThatMcastMacTepsCreated(TOR2_NODE_IID,
514                 asList(DPN1_TEPIP, DPN2_TEPIP, DPN3_TEPIP, TOR1_TEPIP));
515         verifications.verifyThatMcastMacTepsCreated(TOR1_NODE_IID,
516                 asList(DPN1_TEPIP, DPN2_TEPIP, DPN3_TEPIP, TOR2_TEPIP));
517
518         //this dpn mac should get installed in other dpns and tors
519         verifications.verifyThatUcastCreated(TOR1_NODE_IID, asList(DPN3MAC1));
520         verifications.verifyThatUcastCreated(TOR2_NODE_IID, asList(DPN3MAC1));
521         verifications.verifyThatDmacOfOtherDpnCreated(DPN1_ID, DPN3_ID, asList(DPN3MAC1));
522         verifications.verifyThatDmacOfOtherDpnCreated(DPN2_ID, DPN3_ID, asList(DPN3MAC1));
523     }
524
525     @Test
526     public void verifyDeleteDpnAfterL2gwConnection() throws Exception {
527         verifyAddDpnAfterL2gwConnection();
528         InterfaceInfo interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN3MAC1).getLeft();
529         deleteElanInterface(interfaceInfo);
530
531         //clean up of group of this dpn3
532         verifications.verifyThatDpnGroupDeleted(DPN3_ID);
533         //clean up dmacs of this dpn3
534         verifications.verifyThatDmacFlowOfTORDeleted(asList(DPN3_ID), TOR1_NODE_IID, asList(TOR1_MAC1));
535         verifications.verifyThatDmacOfOtherDPNDeleted(DPN3_ID, DPN1_ID, asList(DPN1MAC1, DPN1MAC2));
536         verifications.verifyThatDmacOfOtherDPNDeleted(DPN3_ID, DPN2_ID, asList(DPN2MAC1, DPN2MAC2));
537
538         //clean up of dmacs in the other dpns
539         verifications.verifyThatDmacOfOtherDPNDeleted(DPN1_ID, DPN3_ID, asList(DPN3MAC1));
540         verifications.verifyThatDmacOfOtherDPNDeleted(DPN2_ID, DPN3_ID, asList(DPN3MAC1));
541
542         //cleanup of bc group of other dpns
543         verifications.verifyThatDpnGroupUpdated(DPN1_ID, asList(DPN2_ID), asList(TOR1_NODE_ID, TOR2_NODE_ID));
544         verifications.verifyThatDpnGroupUpdated(DPN2_ID, asList(DPN1_ID), asList(TOR1_NODE_ID, TOR2_NODE_ID));
545
546         //dpn tep should be removed from tors
547         verifications.verifyThatMcastMacTepsDeleted(TOR2_NODE_IID, asList(DPN3_TEPIP));
548         verifications.verifyThatMcastMacTepsDeleted(TOR2_NODE_IID, asList(DPN3_TEPIP));
549
550         //dpn mac should be removed from tors
551         verifications.verifyThatUcastDeleted(TOR1_NODE_IID, asList(DPN3MAC1));
552         verifications.verifyThatUcastDeleted(TOR2_NODE_IID, asList(DPN3MAC1));
553     }
554
555     @Test
556     public void verifyDeleteL2gw1Connection() throws Exception {
557         verifyL2gw2Connection();
558         //delete tor1 l2gw connection
559         l2gwBuilders.deletel2GWConnection(L2GW_CONN1);
560
561         //deleted tors mcast & cast be cleared
562         verifications.verifyThatMcastMacTepsDeleted(TOR1_NODE_IID, asList(DPN1_TEPIP, DPN2_TEPIP, TOR2_TEPIP));
563         verifications.verifyThatUcastDeleted(TOR1_NODE_IID, asList(DPN1MAC1, DPN1MAC2, DPN2MAC1, DPN2MAC2));
564
565         //mcast of other tor be updated
566         verifications.verifyThatMcastMacTepsDeleted(TOR2_NODE_IID, asList(TOR1_TEPIP));
567
568         //ucast of deleted to be deleted in other tor
569         verifications.verifyThatUcastDeleted(TOR2_NODE_IID, asList(TOR1_MAC1));
570
571         //group of dpns be udpated
572         verifications.verifyThatDpnGroupUpdated(DPN1_ID, asList(DPN2_ID), asList(TOR2_NODE_ID));
573         verifications.verifyThatDpnGroupUpdated(DPN2_ID, asList(DPN1_ID), asList(TOR2_NODE_ID));
574
575         //ucast of deleted tor be deleted in other dpns
576         verifications.verifyThatDmacFlowOfTORDeleted(asList(DPN1_ID, DPN2_ID), TOR1_NODE_IID, asList(TOR1_MAC1));
577     }
578 }