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