2 * Copyright (C) 2016, 2017 Red Hat Inc., and others. All rights reserved.
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
8 package org.opendaylight.netvirt.elanmanager.tests;
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;
14 import com.google.common.base.Optional;
16 import java.util.List;
17 import javax.inject.Inject;
19 import org.junit.After;
20 import org.junit.Before;
21 import org.junit.Rule;
22 import org.junit.Test;
23 import org.junit.rules.MethodRule;
24 import org.mockito.Mockito;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
27 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
28 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
29 import org.opendaylight.genius.datastoreutils.testutils.JobCoordinatorTestModule;
30 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
31 import org.opendaylight.genius.mdsalutil.MDSALUtil;
32 import org.opendaylight.genius.mdsalutil.NwConstants;
33 import org.opendaylight.genius.mdsalutil.cache.InstanceIdDataObjectCache;
34 import org.opendaylight.genius.testutils.interfacemanager.TunnelInterfaceDetails;
35 import org.opendaylight.genius.utils.batching.ResourceBatchingManager;
36 import org.opendaylight.infrautils.caches.CacheProvider;
37 import org.opendaylight.infrautils.caches.testutils.CacheModule;
38 import org.opendaylight.infrautils.inject.guice.testutils.GuiceRule;
39 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
40 import org.opendaylight.infrautils.jobcoordinator.internal.JobCoordinatorImpl;
41 import org.opendaylight.infrautils.metrics.MetricProvider;
42 import org.opendaylight.infrautils.metrics.testimpl.TestMetricProviderImpl;
43 import org.opendaylight.infrautils.testutils.LogRule;
44 import org.opendaylight.mdsal.binding.testutils.AssertDataObjects;
45 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
46 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
47 import org.opendaylight.netvirt.elan.cache.ElanInstanceDpnsCache;
48 import org.opendaylight.netvirt.elan.evpn.listeners.ElanMacEntryListener;
49 import org.opendaylight.netvirt.elan.evpn.listeners.EvpnElanInstanceListener;
50 import org.opendaylight.netvirt.elan.evpn.listeners.MacVrfEntryListener;
51 import org.opendaylight.netvirt.elan.evpn.utils.EvpnUtils;
52 import org.opendaylight.netvirt.elan.internal.ElanDpnInterfaceClusteredListener;
53 import org.opendaylight.netvirt.elan.internal.ElanExtnTepConfigListener;
54 import org.opendaylight.netvirt.elan.internal.ElanExtnTepListener;
55 import org.opendaylight.netvirt.elan.internal.ElanInterfaceManager;
56 import org.opendaylight.netvirt.elan.l2gw.listeners.HwvtepPhysicalSwitchListener;
57 import org.opendaylight.netvirt.elan.l2gw.listeners.L2GatewayConnectionListener;
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.utils.ElanL2GatewayUtils;
62 import org.opendaylight.netvirt.elan.utils.ElanUtils;
63 import org.opendaylight.netvirt.elanmanager.api.IElanService;
64 import org.opendaylight.netvirt.elanmanager.api.IL2gwService;
65 import org.opendaylight.netvirt.elanmanager.tests.utils.EvpnTestHelper;
66 import org.opendaylight.netvirt.elanmanager.utils.ElanL2GwCacheUtils;
67 import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayCache;
68 import org.opendaylight.netvirt.neutronvpn.l2gw.L2GatewayListener;
69 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
70 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp;
71 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Networks;
72 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksKey;
73 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
85 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
86 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
87 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
88 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
89 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
90 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
91 import org.slf4j.Logger;
92 import org.slf4j.LoggerFactory;
96 * End-to-end test of IElanService.
98 * @author Michael Vorburger
99 * @author Riyazahmed Talikoti
101 public class ElanServiceTest extends ElanServiceTestBase {
103 private static final Logger LOG = LoggerFactory.getLogger(ElanServiceTest.class);
105 // TODO as-is, this test is flaky; as uncommenting will show
106 // Uncomment this to keep running this test indefinitely
107 // This is very useful to detect concurrency issues (such as https://bugs.opendaylight.org/show_bug.cgi?id=7538)
108 // public static @ClassRule RunUntilFailureClassRule classRepeater = new RunUntilFailureClassRule();
109 // public @Rule RunUntilFailureRule repeater = new RunUntilFailureRule(classRepeater);
111 public @Rule LogRule logRule = new LogRule();
112 public @Rule MethodRule guice = new GuiceRule(ElanServiceTestModule.class, JobCoordinatorTestModule.class,
114 // TODO re-enable after we can await completion of listeners and DJC:
115 // Otherwise this too frequently causes spurious test failures, e.g. due to error
116 // logs Caused by: java.lang.RuntimeException: java.util.concurrent.ExecutionException: Operation was interrupted
117 // public @Rule LogCaptureRule logCaptureRule = new LogCaptureRule();
118 private @Inject IElanService elanService;
119 private @Inject IdManagerService idManager;
120 private @Inject EvpnElanInstanceListener evpnElanInstanceListener;
121 private @Inject ElanMacEntryListener elanMacEntryListener;
122 private @Inject MacVrfEntryListener macVrfEntryListener;
123 private @Inject EvpnUtils evpnUtils;
124 private @Inject IBgpManager bgpManager;
125 private @Inject IVpnManager vpnManager;
126 private @Inject EvpnTestHelper evpnTestHelper;
127 private @Inject OdlInterfaceRpcService odlInterfaceRpcService;
128 private @Inject ElanL2GatewayUtils elanL2GatewayUtils;
129 private @Inject ElanInterfaceManager elanInterfaceManager;
130 private @Inject HwvtepPhysicalSwitchListener hwvtepPhysicalSwitchListener;
131 private @Inject L2GatewayConnectionListener l2GatewayConnectionListener;
132 private @Inject LocalUcastMacListener localUcastMacListener;
133 private @Inject ElanDpnInterfaceClusteredListener elanDpnInterfaceClusteredListener;
134 private @Inject EntityOwnershipService mockedEntityOwnershipService;
135 private @Inject L2GatewayCache l2GatewayCache;
136 private @Inject ElanUtils elanUtils;
137 private @Inject ElanInstanceDpnsCache elanInstanceDpnsCache;
138 private @Inject ElanExtnTepConfigListener elanExtnTepConfigListener;
139 private @Inject ElanExtnTepListener elanExtnTepListener;
140 private @Inject CacheProvider cacheProvider;
142 private L2GatewayListener l2gwListener;
143 private MetricProvider metricProvider = new TestMetricProviderImpl();
145 private Verifications verifications;
146 private L2gwBuilders l2gwBuilders;
148 private SingleTransactionDataBroker singleTxdataBroker;
150 private InstanceIdDataObjectCache<LogicalSwitches> logicalSwitchCache;
152 @Before public void before() throws Exception {
153 singleTxdataBroker = new SingleTransactionDataBroker(dataBroker);
154 logicalSwitchCache = new InstanceIdDataObjectCache<LogicalSwitches>(
155 LogicalSwitches.class, dataBroker, CONFIGURATION,
156 InstanceIdentifier.builder(NetworkTopology.class)
157 .child(Topology.class, new TopologyKey(new TopologyId(new Uri("hwvtep:1"))))
158 .child(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang
159 .network.topology.rev131021.network.topology.topology.Node.class)
160 .augmentation(HwvtepGlobalAugmentation.class)
161 .child(LogicalSwitches.class).build(), cacheProvider) {
162 protected void added(InstanceIdentifier<LogicalSwitches> path, LogicalSwitches dataObject) {
165 singleTxdataBroker.syncWrite(OPERATIONAL, path, dataObject);
166 } catch (TransactionCommitFailedException e) {
167 LOG.error("Failed to write to oper ds");
172 verifications = new Verifications(singleTxdataBroker, odlInterfaceRpcService, EXTN_INTFS, getAwaiter());
173 l2gwBuilders = new L2gwBuilders(singleTxdataBroker);
174 JobCoordinator jobCoordinator = new JobCoordinatorImpl(metricProvider);
176 l2gwListener = new L2GatewayListener(dataBroker, mockedEntityOwnershipService,
177 Mockito.mock(ItmRpcService.class), Mockito.mock(IL2gwService.class), jobCoordinator, l2GatewayCache);
180 l2gwBuilders.buildTorNode(TOR2_NODE_ID, PS2, TOR2_TEPIP);
181 l2gwBuilders.buildTorNode(TOR1_NODE_ID, PS1, TOR1_TEPIP);
184 @After public void after() throws Exception {
185 for (ResourceBatchingManager.ShardResource i : ResourceBatchingManager.ShardResource.values()) {
186 ResourceBatchingManager.getInstance().deregisterBatchableResource(i.name());
189 ElanL2GwCacheUtils.removeL2GatewayDeviceFromAllElanCache(TOR1_NODE_ID);
190 ElanL2GwCacheUtils.removeL2GatewayDeviceFromAllElanCache(TOR2_NODE_ID);
192 ElanL2GwCacheUtils.removeL2GatewayDeviceFromCache(ExpectedObjects.ELAN1, TOR1_NODE_ID);
193 ElanL2GwCacheUtils.removeL2GatewayDeviceFromCache(ExpectedObjects.ELAN1, TOR2_NODE_ID);
196 @Test public void elanServiceTestModule() {
197 // Intentionally empty; the goal is just to first test the ElanServiceTestModule
200 void createL2gwAndConnection(InstanceIdentifier<Node> nodePath,
204 String connectionName)
205 throws InterruptedException, TransactionCommitFailedException {
208 singleTxdataBroker.syncWrite(LogicalDatastoreType.CONFIGURATION,
209 l2gwBuilders.buildL2gwIid(l2gwName), l2gwBuilders.buildL2gw(l2gwName, deviceName, ports));
210 awaitForData(LogicalDatastoreType.CONFIGURATION, l2gwBuilders.buildL2gwIid(l2gwName));
213 singleTxdataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
214 l2gwBuilders.buildConnectionIid(connectionName), l2gwBuilders.buildConnection(connectionName,
215 l2gwName, ExpectedObjects.ELAN1, 100));
216 awaitForData(LogicalDatastoreType.CONFIGURATION, l2gwBuilders.buildConnectionIid(connectionName));
219 @Test public void checkSMAC() throws Exception {
220 // Create Elan instance
221 createElanInstance(ExpectedObjects.ELAN1, ExpectedObjects.ELAN1_SEGMENT_ID);
222 awaitForElanTag(ExpectedObjects.ELAN1);
224 // Add Elan interface
225 InterfaceInfo interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC1).getLeft();
226 addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN1IP1);
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);
233 // Read and Compare SMAC flow
234 String flowId = new StringBuffer()
235 .append(NwConstants.ELAN_SMAC_TABLE)
236 .append(actualElanInstances.getElanTag())
238 .append(interfaceInfo.getInterfaceTag())
239 .append(interfaceInfo.getMacAddress())
241 InstanceIdentifier<Flow> flowInstanceIidSrc = getFlowIid(NwConstants.ELAN_SMAC_TABLE,
242 new FlowId(flowId), DPN1_ID);
243 awaitForData(LogicalDatastoreType.CONFIGURATION, flowInstanceIidSrc);
245 Flow flowSrc = singleTxdataBroker.syncRead(CONFIGURATION, flowInstanceIidSrc);
246 flowSrc = getFlowWithoutCookie(flowSrc);
248 Flow expected = ExpectedObjects.checkSmac(flowId, interfaceInfo, actualElanInstances);
249 AssertDataObjects.assertEqualBeans(expected, flowSrc);
252 @Test public void checkDmacSameDPN() throws Exception {
253 // Create Elan instance
254 createElanInstance(ExpectedObjects.ELAN1, ExpectedObjects.ELAN1_SEGMENT_ID);
255 awaitForElanTag(ExpectedObjects.ELAN1);
257 // Add Elan interface in DPN1
258 InterfaceInfo interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC1).getLeft();
259 addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN1IP1);
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);
266 // Read DMAC Flow in DPN1
267 String flowId = new StringBuffer()
268 .append(NwConstants.ELAN_DMAC_TABLE)
269 .append(actualElanInstances.getElanTag())
271 .append(interfaceInfo.getInterfaceTag())
272 .append(interfaceInfo.getMacAddress())
274 InstanceIdentifier<Flow> flowInstanceIidDst = getFlowIid(NwConstants.ELAN_DMAC_TABLE,
275 new FlowId(flowId), DPN1_ID);
276 awaitForData(LogicalDatastoreType.CONFIGURATION, flowInstanceIidDst);
278 Flow flowDst = singleTxdataBroker.syncRead(CONFIGURATION, flowInstanceIidDst);
279 flowDst = getFlowWithoutCookie(flowDst);
281 Flow expected = ExpectedObjects.checkDmacOfSameDpn(flowId, interfaceInfo, actualElanInstances);
282 AssertDataObjects.assertEqualBeans(getSortedActions(expected), getSortedActions(flowDst));
285 @Test public void checkDmacOfOtherDPN() throws Exception {
286 // Create Elan instance
287 createElanInstance(ExpectedObjects.ELAN1, ExpectedObjects.ELAN1_SEGMENT_ID);
288 awaitForElanTag(ExpectedObjects.ELAN1);
290 InterfaceInfo interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC1).getLeft();
291 addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN1IP1);
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);
298 interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN2MAC1).getLeft();
299 addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN2IP1);
301 // Read and Compare DMAC flow in DPN1 for MAC1 of DPN2
302 String flowId = ElanUtils.getKnownDynamicmacFlowRef((short)51,
305 interfaceInfo.getMacAddress().toString(),
306 actualElanInstances.getElanTag());
308 InstanceIdentifier<Flow> flowInstanceIidDst = getFlowIid(NwConstants.ELAN_DMAC_TABLE,
309 new FlowId(flowId), DPN1_ID);
310 awaitForData(LogicalDatastoreType.CONFIGURATION, flowInstanceIidDst);
312 Flow flowDst = singleTxdataBroker.syncRead(CONFIGURATION, flowInstanceIidDst);
313 flowDst = getFlowWithoutCookie(flowDst);
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));
321 @Test public void checkEvpnAdvRT2() throws Exception {
322 createElanInstanceAndInterfaceAndAttachEvpn();
325 AssertDataObjects.assertEqualBeans(
326 ExpectedObjects.checkEvpnAdvertiseRoute(ELAN1_SEGMENT_ID, DPN1MAC1, DPN1_TEPIP, DPN1IP1, RD),
327 readBgpNetworkFromDS(DPN1IP1));
330 @Test public void checkEvpnAdvRT2NewInterface() throws Exception {
331 createElanInstanceAndInterfaceAndAttachEvpn();
333 // Add Elan interface
334 addElanInterface(ExpectedObjects.ELAN1, ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC2).getLeft(), DPN1IP2);
336 AssertDataObjects.assertEqualBeans(
337 ExpectedObjects.checkEvpnAdvertiseRoute(ELAN1_SEGMENT_ID, DPN1MAC2, DPN1_TEPIP, DPN1IP2, RD),
338 readBgpNetworkFromDS(DPN1IP2));
341 @Test public void checkEvpnWithdrawRT2DelIntf() throws Exception {
342 createElanInstanceAndInterfaceAndAttachEvpn();
344 InstanceIdentifier<Networks> iid = evpnTestHelper.buildBgpNetworkIid(DPN1IP1);
345 awaitForData(LogicalDatastoreType.CONFIGURATION, iid);
347 evpnTestHelper.deleteRdtoNetworks();
349 deleteElanInterface(ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC1).getLeft());
350 awaitForDataDelete(LogicalDatastoreType.CONFIGURATION, iid);
353 @Test public void checkEvpnWithdrawRouteDetachEvpn() throws Exception {
354 createElanInstanceAndInterfaceAndAttachEvpn();
355 addElanInterface(ExpectedObjects.ELAN1, ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC2).getLeft(), DPN1IP2);
357 awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP1));
358 awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP2));
360 evpnTestHelper.detachEvpnToNetwork(ExpectedObjects.ELAN1);
362 awaitForDataDelete(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP1));
363 awaitForDataDelete(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP2));
366 @Test public void checkEvpnInstalDmacFlow() throws Exception {
367 createElanInstanceAndInterfaceAndAttachEvpn();
368 addElanInterface(ExpectedObjects.ELAN1, ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC2).getLeft(), DPN1IP2);
370 // Verify advertise RT2 route success for both MAC's
371 awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP1));
372 awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP2));
374 // RT2 received from Peer
375 evpnTestHelper.handleEvpnRt2Recvd(EVPNRECVMAC1, EVPNRECVIP1);
376 evpnTestHelper.handleEvpnRt2Recvd(EVPNRECVMAC2, EVPNRECVIP2);
378 // verify successful installation of DMAC flow for recvd rt2
379 awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildMacVrfEntryIid(EVPNRECVMAC1));
380 awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildMacVrfEntryIid(EVPNRECVMAC2));
383 @Test public void checkEvpnUnInstalDmacFlow() throws Exception {
384 createElanInstanceAndInterfaceAndAttachEvpn();
385 addElanInterface(ExpectedObjects.ELAN1, ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC2).getLeft(), DPN1IP2);
387 // Verify advertise RT2 route success for both MAC's
388 awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP1));
389 awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildBgpNetworkIid(DPN1IP2));
391 // RT2 received from Peer
392 evpnTestHelper.handleEvpnRt2Recvd(EVPNRECVMAC1, EVPNRECVIP1);
393 evpnTestHelper.handleEvpnRt2Recvd(EVPNRECVMAC2, EVPNRECVIP2);
395 // verify successful installation of DMAC flow for recvd rt2
396 awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildMacVrfEntryIid(EVPNRECVMAC1));
397 awaitForData(LogicalDatastoreType.CONFIGURATION, evpnTestHelper.buildMacVrfEntryIid(EVPNRECVMAC2));
399 // withdraw RT2 received from Peer
400 evpnTestHelper.deleteMacVrfEntryToDS(RD, EVPNRECVMAC1);
401 evpnTestHelper.deleteMacVrfEntryToDS(RD, EVPNRECVMAC2);
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));
408 public void createElanInstanceAndInterfaceAndAttachEvpn() throws ReadFailedException,
409 TransactionCommitFailedException {
410 // Create Elan instance
411 createElanInstance(ExpectedObjects.ELAN1, ExpectedObjects.ELAN1_SEGMENT_ID);
412 awaitForElanTag(ExpectedObjects.ELAN1);
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);
419 // Add Elan interface
420 addElanInterface(ExpectedObjects.ELAN1, ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC1).getLeft(), DPN1IP1);
422 // Attach EVPN to networks
423 evpnTestHelper.attachEvpnToNetwork(elanInstance);
426 public Networks readBgpNetworkFromDS(String prefix) throws ReadFailedException {
427 InstanceIdentifier<Networks> iid = InstanceIdentifier.builder(Bgp.class)
428 .child(Networks.class, new NetworksKey(prefix, RD))
430 awaitForData(LogicalDatastoreType.CONFIGURATION, iid);
432 return singleTxdataBroker.syncRead(CONFIGURATION, iid);
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;
444 public void verifyL2gw1Connection() throws Exception {
447 createElanInstance(ExpectedObjects.ELAN1, ExpectedObjects.ELAN1_SEGMENT_ID);
448 awaitForElanTag(ExpectedObjects.ELAN1);
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);
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);
461 interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN2MAC2).getLeft();
462 addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN2IP2);
463 verifications.verifyLocalBcGroup(DPN2_ID, 2);
465 createL2gwAndConnection(TOR1_NODE_IID, L2GW1, PS1, DataProvider.getPortNameListD1(), L2GW_CONN1);
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));
474 public void verifyL2gwPreProvisioning() throws Exception {
476 createElanInstance(ExpectedObjects.ELAN1, ExpectedObjects.ELAN1_SEGMENT_ID);
477 addElanInterface(ExpectedObjects.ELAN1, ELAN_INTERFACES.get(ELAN1 + ":" + DPN1MAC1).getLeft(), DPN1IP1);
479 singleTxdataBroker.syncDelete(OPERATIONAL, TOR1_NODE_IID);
480 singleTxdataBroker.syncDelete(OPERATIONAL,
481 PhysicalSwitchHelper.getPhysicalSwitchInstanceIdentifier(TOR1_NODE_IID, PS1));
483 createL2gwAndConnection(TOR1_NODE_IID, L2GW1, PS1, DataProvider.getPortNameListD1(), L2GW_CONN1);
485 l2gwBuilders.buildTorNode(TOR1_NODE_ID, PS1, TOR1_TEPIP);
487 verifications.verifyThatMcastMacTepsCreated(TOR1_NODE_IID, asList(DPN1_TEPIP));
488 verifications.verifyThatUcastCreated(TOR1_NODE_IID, asList(DPN1MAC1));
491 public void verifyL2gwMac1InDpns() throws Exception {
492 verifyL2gw1Connection();
493 l2gwBuilders.createLocalUcastMac(TOR1_NODE_IID, TOR1_MAC1, TOR1_IP1, TOR1_TEPIP);
494 verifications.verifyThatDmacFlowOfTORCreated(asList(DPN1_ID, DPN2_ID), TOR1_NODE_IID, asList(TOR1_MAC1));
497 public void verifyL2gw2Connection() throws Exception {
498 verifyL2gwMac1InDpns();
499 // TOR Node 2 creation
500 createL2gwAndConnection(TOR2_NODE_IID, L2GW2, PS2, DataProvider.getPortNameListTor2(), L2GW_CONN2);
501 //check for remote mcast mac in tor2 against TEPs of dpn1, dpn2 and dpn3, tor1)
502 verifications.verifyThatMcastMacTepsCreated(TOR2_NODE_IID, asList(DPN1_TEPIP, DPN2_TEPIP, TOR1_TEPIP));
503 verifications.verifyThatMcastMacTepsCreated(TOR1_NODE_IID, asList(DPN1_TEPIP, DPN2_TEPIP, TOR2_TEPIP));
504 verifications.verifyThatUcastCreated(TOR2_NODE_IID, asList(DPN1MAC1, DPN2MAC1, DPN2MAC1, DPN2MAC2, TOR1_MAC1));
508 public void verifyL2gwMac2InTors() throws Exception {
509 verifyL2gw2Connection();
510 l2gwBuilders.createLocalUcastMac(TOR1_NODE_IID, TOR1_MAC2, TOR1_IP2, TOR1_TEPIP);
511 verifications.verifyThatUcastCreated(TOR2_NODE_IID, asList(TOR1_MAC2));
515 public void verifyL2gwMacDeleteInTors() throws Exception {
516 verifyL2gwMac2InTors();
517 LocalUcastMacs localUcastMacs1 = l2gwBuilders.createLocalUcastMac(
518 TOR1_NODE_IID, TOR1_MAC1, TOR1_IP1, TOR1_TEPIP);
519 singleTxdataBroker.syncDelete(LogicalDatastoreType.OPERATIONAL,
520 l2gwBuilders.buildMacIid(TOR1_NODE_IID, localUcastMacs1));
521 verifications.verifyThatDmacFlowOfTORDeleted(asList(DPN1_ID, DPN2_ID), TOR1_NODE_IID, asList(TOR1_MAC1));
522 verifications.verifyThatUcastDeleted(TOR2_NODE_IID, asList(TOR1_MAC1));
526 public void verifyAddDpnAfterL2gwConnection() throws Exception {
527 verifyL2gwMac2InTors();
528 //Add Elan MAC1, MAC2 in DPN3
529 InterfaceInfo interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN3MAC1).getLeft();
530 addElanInterface(ExpectedObjects.ELAN1, interfaceInfo, DPN3IP1);
532 //bc group of this dpn created
533 verifications.verifyThatDpnGroupUpdated(DPN3_ID, asList(DPN1_ID, DPN2_ID), asList(TOR1_NODE_ID, TOR2_NODE_ID));
534 //other tors macs be installed in this dpn
535 verifications.verifyThatDmacFlowOfTORCreated(asList(DPN3_ID), TOR1_NODE_IID, asList(TOR1_MAC1));
536 verifications.verifyThatDmacOfOtherDpnCreated(DPN3_ID, DPN1_ID, asList(DPN1MAC1, DPN1MAC2));
537 verifications.verifyThatDmacOfOtherDpnCreated(DPN3_ID, DPN2_ID, asList(DPN2MAC1, DPN2MAC2));
539 //bc group of the other dpns be updated
540 verifications.verifyThatDpnGroupUpdated(DPN1_ID, asList(DPN2_ID, DPN3_ID), asList(TOR1_NODE_ID, TOR2_NODE_ID));
541 verifications.verifyThatDpnGroupUpdated(DPN2_ID, asList(DPN1_ID, DPN3_ID), asList(TOR1_NODE_ID, TOR2_NODE_ID));
543 //mcast of tor should be updated
544 verifications.verifyThatMcastMacTepsCreated(TOR2_NODE_IID,
545 asList(DPN1_TEPIP, DPN2_TEPIP, DPN3_TEPIP, TOR1_TEPIP));
546 verifications.verifyThatMcastMacTepsCreated(TOR1_NODE_IID,
547 asList(DPN1_TEPIP, DPN2_TEPIP, DPN3_TEPIP, TOR2_TEPIP));
549 //this dpn mac should get installed in other dpns and tors
550 verifications.verifyThatUcastCreated(TOR1_NODE_IID, asList(DPN3MAC1));
551 verifications.verifyThatUcastCreated(TOR2_NODE_IID, asList(DPN3MAC1));
552 verifications.verifyThatDmacOfOtherDpnCreated(DPN1_ID, DPN3_ID, asList(DPN3MAC1));
553 verifications.verifyThatDmacOfOtherDpnCreated(DPN2_ID, DPN3_ID, asList(DPN3MAC1));
557 public void verifyDeleteDpnAfterL2gwConnection() throws Exception {
558 verifyAddDpnAfterL2gwConnection();
559 InterfaceInfo interfaceInfo = ELAN_INTERFACES.get(ELAN1 + ":" + DPN3MAC1).getLeft();
560 deleteElanInterface(interfaceInfo);
562 //clean up of group of this dpn3
563 verifications.verifyThatDpnGroupDeleted(DPN3_ID);
564 //clean up dmacs of this dpn3
565 verifications.verifyThatDmacFlowOfTORDeleted(asList(DPN3_ID), TOR1_NODE_IID, asList(TOR1_MAC1));
566 verifications.verifyThatDmacOfOtherDPNDeleted(DPN3_ID, DPN1_ID, asList(DPN1MAC1, DPN1MAC2));
567 verifications.verifyThatDmacOfOtherDPNDeleted(DPN3_ID, DPN2_ID, asList(DPN2MAC1, DPN2MAC2));
569 //clean up of dmacs in the other dpns
570 verifications.verifyThatDmacOfOtherDPNDeleted(DPN1_ID, DPN3_ID, asList(DPN3MAC1));
571 verifications.verifyThatDmacOfOtherDPNDeleted(DPN2_ID, DPN3_ID, asList(DPN3MAC1));
573 //cleanup of bc group of other dpns
574 verifications.verifyThatDpnGroupUpdated(DPN1_ID, asList(DPN2_ID), asList(TOR1_NODE_ID, TOR2_NODE_ID));
575 verifications.verifyThatDpnGroupUpdated(DPN2_ID, asList(DPN1_ID), asList(TOR1_NODE_ID, TOR2_NODE_ID));
577 //dpn tep should be removed from tors
578 verifications.verifyThatMcastMacTepsDeleted(TOR2_NODE_IID, asList(DPN3_TEPIP));
579 verifications.verifyThatMcastMacTepsDeleted(TOR2_NODE_IID, asList(DPN3_TEPIP));
581 //dpn mac should be removed from tors
582 verifications.verifyThatUcastDeleted(TOR1_NODE_IID, asList(DPN3MAC1));
583 verifications.verifyThatUcastDeleted(TOR2_NODE_IID, asList(DPN3MAC1));
587 public void verifyDeleteL2gw1Connection() throws Exception {
588 verifyL2gw2Connection();
589 //delete tor1 l2gw connection
590 l2gwBuilders.deletel2GWConnection(L2GW_CONN1);
592 //deleted tors mcast & cast be cleared
593 verifications.verifyThatMcastMacTepsDeleted(TOR1_NODE_IID, asList(DPN1_TEPIP, DPN2_TEPIP, TOR2_TEPIP));
594 verifications.verifyThatUcastDeleted(TOR1_NODE_IID, asList(DPN1MAC1, DPN1MAC2, DPN2MAC1, DPN2MAC2));
596 //mcast of other tor be updated
597 verifications.verifyThatMcastMacTepsDeleted(TOR2_NODE_IID, asList(TOR1_TEPIP));
599 //ucast of deleted to be deleted in other tor
600 verifications.verifyThatUcastDeleted(TOR2_NODE_IID, asList(TOR1_MAC1));
602 //group of dpns be udpated
603 verifications.verifyThatDpnGroupUpdated(DPN1_ID, asList(DPN2_ID), asList(TOR2_NODE_ID));
604 verifications.verifyThatDpnGroupUpdated(DPN2_ID, asList(DPN1_ID), asList(TOR2_NODE_ID));
606 //ucast of deleted tor be deleted in other dpns
607 verifications.verifyThatDmacFlowOfTORDeleted(asList(DPN1_ID, DPN2_ID), TOR1_NODE_IID, asList(TOR1_MAC1));