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