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