From f6e06ce83d0886838c07243cbe8e04761971860f Mon Sep 17 00:00:00 2001 From: Tarun Thakur Date: Thu, 12 Jan 2017 20:37:35 +0530 Subject: [PATCH] ITM Tep Auto Config Unit test using Guice. Added cases for: - Change for def-tz-enabled and def-tz-tunnel-type config paramters - Default-TZ creation and deletion based on def-tz-enabled flag - TEP addition and deletion into/from default-TZ - TZ creation and TEP addition into TZ - TZ deletion and TEP deletion from TZ - TEP addition and deletion into/from default-TZ via southbound - TEP addition and deletion into/from northbound configured TZ via southbound - TEP addition and deletion into/from NotHostedList via southbound - Move TEP from one TZ to other TZ by changing tzname parameter in ExternalsIds list in Ovsdb node from southbound - Update TEP for its bridge by changing dpn-br-name parameter in ExternalsIds list in Ovsdb node from southbound Fixed errors due to new change of (1) dpn-br-name to br-name and (2) 'weight' param inside vteps in itm.yang Fixed checkstyle issues. Change-Id: Iea4279a992bf80a95d04e39f08cc59188327c9b5 Signed-off-by: Tarun Thakur --- itm/itm-impl/pom.xml | 11 +- .../genius/itm/impl/ItmUtils.java | 8 +- .../itm/tests/ItmTepAutoConfigTest.java | 676 ++++++++++++++++++ .../itm/tests/ItmTepAutoConfigTestUtil.java | 90 +++ .../genius/itm/tests/ItmTestConstants.java | 25 + .../genius/itm/tests/ItmTestModule.java | 12 +- .../genius/itm/tests/OvsdbTestUtil.java | 185 +++++ .../ExpectedDefTransportZoneObjects.xtend | 64 ++ ...ctedTepNotHostedTransportZoneObjects.xtend | 34 + .../xtend/ExpectedTransportZoneObjects.xtend | 72 ++ 10 files changed, 1170 insertions(+), 7 deletions(-) create mode 100644 itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTepAutoConfigTest.java create mode 100644 itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTepAutoConfigTestUtil.java create mode 100644 itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/OvsdbTestUtil.java create mode 100644 itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/xtend/ExpectedDefTransportZoneObjects.xtend create mode 100644 itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/xtend/ExpectedTepNotHostedTransportZoneObjects.xtend create mode 100644 itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/xtend/ExpectedTransportZoneObjects.xtend diff --git a/itm/itm-impl/pom.xml b/itm/itm-impl/pom.xml index d83c440bb..8cde3f0e3 100644 --- a/itm/itm-impl/pom.xml +++ b/itm/itm-impl/pom.xml @@ -74,8 +74,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html idmanager-api ${genius.version} - - + org.opendaylight.genius testutils @@ -130,8 +129,14 @@ and is available at http://www.eclipse.org/legal/epl-v10.html powermock-module-junit4 test + + org.opendaylight.ovsdb + utils.southbound-utils + ${genius.ovsdb.version} + test + - + diff --git a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/impl/ItmUtils.java b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/impl/ItmUtils.java index bb40d9157..e1bc1f765 100644 --- a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/impl/ItmUtils.java +++ b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/impl/ItmUtils.java @@ -31,6 +31,7 @@ import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker; import org.opendaylight.genius.interfacemanager.globals.IfmConstants; import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager; import org.opendaylight.genius.itm.api.IITMProvider; @@ -1236,6 +1237,7 @@ public class ItmUtils { * * @param tzName transport zone name * @param dataBroker data broker handle to perform operations on datastore + * @return the TransportZone object in Config DS */ // FIXME: Better is to implement cache to avoid datastore read. public static TransportZone getTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) { @@ -1379,7 +1381,11 @@ public class ItmUtils { .child(TransportZone.class, new TransportZoneKey(tzName)).build(); LOG.debug("Removing {} transport-zone from config DS.", tzName); - ItmUtils.asyncDelete(LogicalDatastoreType.CONFIGURATION, path, dataBroker, ItmUtils.DEFAULT_CALLBACK); + try { + SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, path); + } catch (TransactionCommitFailedException e) { + LOG.error("deleteTransportZoneFromConfigDS failed. {} could not be deleted.", tzName, e); + } } } diff --git a/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTepAutoConfigTest.java b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTepAutoConfigTest.java new file mode 100644 index 000000000..e13a66ff9 --- /dev/null +++ b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTepAutoConfigTest.java @@ -0,0 +1,676 @@ +/* + * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.genius.itm.tests; + +import static org.opendaylight.mdsal.binding.testutils.AssertDataObjects.assertEqualBeans; + +import com.google.common.base.Optional; +import com.google.common.util.concurrent.CheckedFuture; +import java.util.ArrayList; +import java.util.List; +import javax.inject.Inject; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.MethodRule; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker; +import org.opendaylight.genius.itm.cli.TepCommandHelper; +import org.opendaylight.genius.itm.globals.ITMConstants; +import org.opendaylight.genius.itm.impl.ItmUtils; +import org.opendaylight.genius.itm.tests.xtend.ExpectedDefTransportZoneObjects; +import org.opendaylight.genius.itm.tests.xtend.ExpectedTepNotHostedTransportZoneObjects; +import org.opendaylight.genius.itm.tests.xtend.ExpectedTransportZoneObjects; +import org.opendaylight.infrautils.inject.guice.testutils.GuiceRule; +import org.opendaylight.infrautils.testutils.LogRule; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZonesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZone; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Component tests for ITM TEP Auto Config feature. + */ +public class ItmTepAutoConfigTest { + + public @Rule LogRule logRule = new LogRule(); + public @Rule MethodRule guice = new GuiceRule(ItmTestModule.class); + + TransportZone transportZone; + TransportZones transportZones; + + // list objects + List transportZoneList = new ArrayList<>(); + + // InstanceIdentifier objects building + + // TransportZones Iid + InstanceIdentifier tzonesPath = InstanceIdentifier.builder(TransportZones.class).build(); + + @Inject DataBroker dataBroker; + + @Before + public void start() throws InterruptedException { + transportZone = new TransportZoneBuilder().setZoneName(ItmTestConstants.TZ_NAME) + .setTunnelType(ItmTestConstants.TUNNEL_TYPE_VXLAN).setKey(new TransportZoneKey(ItmTestConstants.TZ_NAME)) + .build(); + transportZoneList.add(transportZone); + transportZones = new TransportZonesBuilder().setTransportZone(transportZoneList).build(); + } + + // Common method created for code-reuse + private InstanceIdentifier processDefTzOnItmConfig(boolean defTzEnabledFlag, + String defTzTunnelType) throws Exception { + ItmConfig itmConfigObj = null; + if (defTzTunnelType != null) { + // set def-tz-enabled flag and def-tz-tunnel-type + itmConfigObj = new ItmConfigBuilder().setDefTzEnabled(defTzEnabledFlag) + .setDefTzTunnelType(defTzTunnelType).build(); + } else { + // set def-tz-enabled flag only + itmConfigObj = new ItmConfigBuilder().setDefTzEnabled(defTzEnabledFlag).build(); + } + // Create TepCommandHelper object which creates/deletes default-TZ based + // on def-tz-enabled flag + TepCommandHelper tepCmdHelper = new TepCommandHelper(dataBroker, itmConfigObj); + tepCmdHelper.start(); + + InstanceIdentifier tzonePath = ItmTepAutoConfigTestUtil.getTzIid( + ITMConstants.DEFAULT_TRANSPORT_ZONE); + + return tzonePath; + } + + @Test + public void defTzEnabledFalseConfigTest() throws Exception { + InstanceIdentifier iid = InstanceIdentifier.create(ItmConfig.class); + + // set def-tz-enabled flag to false + ItmConfig itmConfigObj = new ItmConfigBuilder().setDefTzEnabled(false).build(); + + // write into config DS + CheckedFuture futures = + ItmTepAutoConfigTestUtil.writeItmConfig(iid, itmConfigObj, dataBroker); + futures.get(); + + // read from config DS + boolean defTzEnabled = SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional( + dataBroker, LogicalDatastoreType.CONFIGURATION, iid).get().isDefTzEnabled(); + Assert.assertEquals(defTzEnabled, false); + } + + @Test + public void defTzEnabledTrueConfigTest() throws Exception { + InstanceIdentifier iid = InstanceIdentifier.create(ItmConfig.class); + + // set def-tz-enabled flag to true + ItmConfig itmConfigObj = new ItmConfigBuilder().setDefTzEnabled(true).build(); + + // write into config DS + CheckedFuture futures = + ItmTepAutoConfigTestUtil.writeItmConfig(iid, itmConfigObj, dataBroker); + futures.get(); + + // read from config DS + boolean defTzEnabled = SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional( + dataBroker, LogicalDatastoreType.CONFIGURATION, iid).get().isDefTzEnabled(); + Assert.assertEquals(defTzEnabled, true); + } + + @Test + public void defTzCreationTestWithDefTzEnabledTrueAndVxlanTunnelType() throws Exception { + // set def-tz-enabled flag to true + boolean defTzEnabledFlag = true; + // set def-tz-tunnel-type to VXLAN + String defTzTunnelType = ITMConstants.TUNNEL_TYPE_VXLAN; + + InstanceIdentifier tzonePath = processDefTzOnItmConfig(defTzEnabledFlag, + defTzTunnelType); + Assert.assertNotNull(tzonePath); + + assertEqualBeans(ExpectedDefTransportZoneObjects.newDefTzWithVxlanTunnelType(), + dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, tzonePath).checkedGet().get()); + } + + @Test + public void defTzCreationTestWithDefTzEnabledTrueAndGreTunnelType() throws Exception { + // set def-tz-enabled flag to true + boolean defTzEnabledFlag = true; + // set def-tz-tunnel-type to GRE + String defTzTunnelType = ITMConstants.TUNNEL_TYPE_GRE; + + InstanceIdentifier tzonePath = processDefTzOnItmConfig(defTzEnabledFlag, + defTzTunnelType); + Assert.assertNotNull(tzonePath); + + assertEqualBeans(ExpectedDefTransportZoneObjects.newDefTzWithGreTunnelType(), + dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, tzonePath).checkedGet().get()); + } + + @Test + public void defTzCreationFailedTestWithDefTzEnabledFalse() throws Exception { + // set def-tz-enabled flag to false + boolean defTzEnabledFlag = false; + // set def-tz-tunnel-type to GRE + String defTzTunnelType = null; + + InstanceIdentifier tzonePath = processDefTzOnItmConfig(defTzEnabledFlag, + defTzTunnelType); + Assert.assertNotNull(tzonePath); + + Assert.assertEquals(Optional.absent(), dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, tzonePath).get()); + } + + @Test + public void defTzRecreationTestOnTunnelTypeChange() throws Exception { + // set def-tz-enabled flag to true + boolean defTzEnabledFlag = true; + // set def-tz-tunnel-type to VXLAN + String defTzTunnelType = ITMConstants.TUNNEL_TYPE_VXLAN; + + InstanceIdentifier tzonePath = processDefTzOnItmConfig(defTzEnabledFlag, + defTzTunnelType); + Assert.assertNotNull(tzonePath); + + // check default-TZ is created with VXLAN tunnel type + assertEqualBeans(ExpectedDefTransportZoneObjects.newDefTzWithVxlanTunnelType().getTunnelType(), + dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, tzonePath) + .checkedGet().get().getTunnelType()); + + // now, change def-tz-tunnel-type to GRE + defTzTunnelType = ITMConstants.TUNNEL_TYPE_GRE; + + tzonePath = processDefTzOnItmConfig(defTzEnabledFlag, defTzTunnelType); + Assert.assertNotNull(tzonePath); + + // check default-TZ is re-created with GRE tunnel type + assertEqualBeans(ExpectedDefTransportZoneObjects.newDefTzWithGreTunnelType().getTunnelType(), + dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, tzonePath) + .checkedGet().get().getTunnelType()); + } + + @Test + public void defTzDeletionTest() throws Exception { + // create default-TZ first by setting def-tz-enabled flag to true + ItmConfig itmConfigObj = new ItmConfigBuilder().setDefTzEnabled(true) + .setDefTzTunnelType(ITMConstants.TUNNEL_TYPE_GRE).build(); + + TepCommandHelper tepCmdHelper = new TepCommandHelper(dataBroker, itmConfigObj); + tepCmdHelper.start(); + + // Create TepCommandHelper object which creates/deletes default-TZ based on def-tz-enabled flag + InstanceIdentifier tzonePath = ItmTepAutoConfigTestUtil.getTzIid( + ITMConstants.DEFAULT_TRANSPORT_ZONE); + Assert.assertNotNull(tzonePath); + + assertEqualBeans(ExpectedDefTransportZoneObjects.newDefTzWithGreTunnelType(), + dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, tzonePath).checkedGet().get()); + + // now delete default-TZ first by setting def-tz-enabled flag to false + itmConfigObj = new ItmConfigBuilder().setDefTzEnabled(false).build(); + + // Create TepCommandHelper object which creates/deletes default-TZ based on def-tz-enabled flag + tepCmdHelper = new TepCommandHelper(dataBroker, itmConfigObj); + tepCmdHelper.start(); + + Assert.assertEquals(Optional.absent(), dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, tzonePath).get()); + } + + @Test + public void testAddDeleteTepForDefTz() throws Exception { + // create default-TZ first by setting def-tz-enabled flag to true + ItmConfig itmConfigObj = new ItmConfigBuilder().setDefTzEnabled(true) + .setDefTzTunnelType(ITMConstants.TUNNEL_TYPE_VXLAN).build(); + + TepCommandHelper tepCmdHelper = new TepCommandHelper(dataBroker, itmConfigObj); + tepCmdHelper.start(); + + InstanceIdentifier tzonePath = ItmTepAutoConfigTestUtil.getTzIid( + ITMConstants.DEFAULT_TRANSPORT_ZONE); + Assert.assertNotNull(tzonePath); + + IpPrefix subnetMaskObj = ItmUtils.getDummySubnet(); + + // add TEP into default-TZ + CheckedFuture futures = + ItmTepAutoConfigTestUtil.addTep(ItmTestConstants.DEF_TZ_TEP_IP, + ItmTestConstants.DEF_BR_DPID, + ITMConstants.DEFAULT_TRANSPORT_ZONE, false, dataBroker); + futures.get(); + + InstanceIdentifier vtepPath = ItmTepAutoConfigTestUtil.getTepIid(subnetMaskObj, + ITMConstants.DEFAULT_TRANSPORT_ZONE, ItmTestConstants.INT_DEF_BR_DPID, + ITMConstants.DUMMY_PORT); + Assert.assertNotNull(vtepPath); + + // check TEP is added into default-TZ + assertEqualBeans(ExpectedDefTransportZoneObjects.newDefTzWithTep(), dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, tzonePath).checkedGet().get()); + + // remove tep from default-TZ + futures = ItmTepAutoConfigTestUtil.deleteTep(ItmTestConstants.DEF_TZ_TEP_IP, + ItmTestConstants.DEF_BR_DPID, ITMConstants.DEFAULT_TRANSPORT_ZONE, dataBroker); + futures.get(); + + // check TEP is deleted from default-TZ + Assert.assertEquals(Optional.absent(), dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, vtepPath).get()); + } + + @Test + public void testAddDeleteTepForTz() throws Exception { + // create TZ + ItmUtils.syncWrite(LogicalDatastoreType.CONFIGURATION, tzonesPath, transportZones, dataBroker); + + InstanceIdentifier tzonePath = ItmTepAutoConfigTestUtil.getTzIid( + ItmTestConstants.TZ_NAME); + Assert.assertNotNull(tzonePath); + + // check TZ is created + Assert.assertEquals(ItmTestConstants.TZ_NAME, dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, tzonePath).checkedGet().get().getZoneName()); + + // add tep + CheckedFuture futures = + ItmTepAutoConfigTestUtil.addTep(ItmTestConstants.NB_TZ_TEP_IP, + ItmTestConstants.DEF_BR_DPID, ItmTestConstants.TZ_NAME, false, dataBroker); + futures.get(); + + IpPrefix subnetMaskObj = ItmUtils.getDummySubnet(); + + InstanceIdentifier vtepPath = ItmTepAutoConfigTestUtil.getTepIid(subnetMaskObj, + ItmTestConstants.TZ_NAME, ItmTestConstants.INT_DEF_BR_DPID, ITMConstants.DUMMY_PORT); + Assert.assertNotNull(vtepPath); + + // check TEP is added into TZ that is already created. + assertEqualBeans(ExpectedTransportZoneObjects.newTransportZone(), + dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, tzonePath).checkedGet().get()); + + // remove tep + futures = ItmTepAutoConfigTestUtil.deleteTep(ItmTestConstants.NB_TZ_TEP_IP, + ItmTestConstants.DEF_BR_DPID, ItmTestConstants.TZ_NAME, dataBroker); + futures.get(); + + // check TEP is deleted + Assert.assertEquals(Optional.absent(), dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, vtepPath).get()); + + // for safe side, check TZ is present + Assert.assertEquals(ItmTestConstants.TZ_NAME, dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, tzonePath).checkedGet().get().getZoneName()); + } + + @Test + public void tepAddDeleteFromDefTzViaSouthboundTest() throws Exception { + String tepIp = ItmTestConstants.DEF_TZ_TEP_IP; + // create Network topology node with tep-ip set into ExternalIds list + // OvsdbNodeListener would be automatically listen on Node to add TEP + ConnectionInfo connInfo = OvsdbTestUtil.getConnectionInfo(ItmTestConstants.OVSDB_CONN_PORT, + ItmTestConstants.LOCALHOST_IP); + CheckedFuture future = + OvsdbTestUtil.createNode(connInfo,tepIp,ITMConstants.DEFAULT_TRANSPORT_ZONE,dataBroker); + future.get(); + + // add bridge into node + future = OvsdbTestUtil.addBridgeIntoNode(connInfo, ItmTestConstants.DEF_BR_NAME, + ItmTestConstants.DEF_BR_DPID, dataBroker); + future.get(); + // wait for OvsdbNodeListener to perform config DS update through transaction + Thread.sleep(1000); + + InstanceIdentifier tzonePath = ItmTepAutoConfigTestUtil.getTzIid( + ITMConstants.DEFAULT_TRANSPORT_ZONE); + Assert.assertNotNull(tzonePath); + + // check TEP is added into default-TZ + assertEqualBeans(ExpectedDefTransportZoneObjects.newDefTzWithTep(), + dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, tzonePath) + .checkedGet().get()); + + // test TEP delete now, + // pass tep-ip with NULL value, tep-ip paramtere in external_ids will not be set. + tepIp = null; + future = OvsdbTestUtil.updateNode(connInfo, tepIp, ITMConstants.DEFAULT_TRANSPORT_ZONE, + null, dataBroker); + future.get(); + // wait for OvsdbNodeListener to perform config DS update through transaction + Thread.sleep(1000); + + IpPrefix subnetMaskObj = ItmUtils.getDummySubnet(); + + InstanceIdentifier vtepPath = ItmTepAutoConfigTestUtil.getTepIid(subnetMaskObj, + ITMConstants.DEFAULT_TRANSPORT_ZONE, ItmTestConstants.INT_DEF_BR_DPID, + ITMConstants.DUMMY_PORT); + Assert.assertNotNull(vtepPath); + + // check TEP is deleted from default-TZ when TEP-Ip is removed from southbound + Assert.assertEquals(Optional.absent(), dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, vtepPath).get()); + } + + @Test + public void tepAddDeleteFromNbTzViaSouthboundTest() throws Exception { + // create Transport-zone in advance + ItmUtils.syncWrite(LogicalDatastoreType.CONFIGURATION, tzonesPath, transportZones, + dataBroker); + + String tepIp = ItmTestConstants.NB_TZ_TEP_IP; + // create Network topology node with tep-ip set into ExternalIds list + // OvsdbNodeListener would be automatically listen on Node to add TEP + ConnectionInfo connInfo = OvsdbTestUtil.getConnectionInfo(ItmTestConstants.OVSDB_CONN_PORT, + ItmTestConstants.LOCALHOST_IP); + CheckedFuture future = OvsdbTestUtil.createNode( + connInfo, tepIp, ItmTestConstants.TZ_NAME, dataBroker); + future.get(); + + // add bridge into node + future = OvsdbTestUtil.addBridgeIntoNode(connInfo, ItmTestConstants.DEF_BR_NAME, + ItmTestConstants.DEF_BR_DPID, dataBroker); + future.get(); + // wait for OvsdbNodeListener to perform config DS update through transaction + Thread.sleep(1000); + + InstanceIdentifier tzonePath = ItmTepAutoConfigTestUtil.getTzIid( + ItmTestConstants.TZ_NAME); + Assert.assertNotNull(tzonePath); + + // check TEP is added into NB configured TZ + assertEqualBeans(ExpectedTransportZoneObjects.newTransportZone(), + dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, tzonePath) + .checkedGet().get()); + + IpPrefix subnetMaskObj = ItmUtils.getDummySubnet(); + + InstanceIdentifier vtepPath = ItmTepAutoConfigTestUtil.getTepIid(subnetMaskObj, + ItmTestConstants.TZ_NAME, ItmTestConstants.INT_DEF_BR_DPID, ITMConstants.DUMMY_PORT); + Assert.assertNotNull(vtepPath); + + // test TEP delete now, + // pass tep-ip with NULL value, tep-ip paramtere in external_ids will not be set. + tepIp = null; + future = OvsdbTestUtil.updateNode(connInfo, tepIp, ItmTestConstants.TZ_NAME, null, dataBroker); + future.get(); + // wait for OvsdbNodeListener to perform config DS update through transaction + Thread.sleep(1000); + + // check TEP is deleted from default-TZ when TEP-Ip is removed from southbound + Assert.assertEquals(Optional.absent(), dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, vtepPath).get()); + } + + @Test + public void tzAddDeleteToNotHostedViaSouthboundTest() throws Exception { + // create Network topology node + ConnectionInfo connInfo = OvsdbTestUtil.getConnectionInfo(ItmTestConstants.OVSDB_CONN_PORT, + ItmTestConstants.LOCALHOST_IP); + CheckedFuture future = OvsdbTestUtil.createNode( + connInfo, ItmTestConstants.NOT_HOSTED_TZ_TEP_IP, ItmTestConstants.NOT_HOSTED_TZ_NAME, + dataBroker); + future.get(); + + // add bridge into node + future = OvsdbTestUtil.addBridgeIntoNode(connInfo, ItmTestConstants.DEF_BR_NAME, + ItmTestConstants.NOT_HOSTED_DEF_BR_DPID, dataBroker); + future.get(); + // wait for OvsdbNodeListener to perform config DS update through transaction + Thread.sleep(1000); + + InstanceIdentifier notHostedtzPath = ItmTepAutoConfigTestUtil + .getTepNotHostedInTZIid(ItmTestConstants.NOT_HOSTED_TZ_NAME); + Assert.assertNotNull(notHostedtzPath); + + // check not hosted + assertEqualBeans(ExpectedTepNotHostedTransportZoneObjects.newTepNotHostedTransportZone(), + dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, + notHostedtzPath).checkedGet().get()); + + future = OvsdbTestUtil.updateNode(connInfo, ItmTestConstants.NOT_HOSTED_TZ_TEP_IP, null, + ItmTestConstants.DEF_BR_NAME, dataBroker); + future.get(); + // wait for OvsdbNodeListener to perform config DS update through transaction + Thread.sleep(1000); + + Assert.assertEquals(Optional.absent(),dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, notHostedtzPath).get()); + } + + @Test + public void tepUpdateForTzTest() throws Exception { + String tepIp = ItmTestConstants.DEF_TZ_TEP_IP; + // create Network topology node with tep-ip set into ExternalIds list + // OvsdbNodeListener would be automatically listen on Node to add TEP + ConnectionInfo connInfo = OvsdbTestUtil.getConnectionInfo(ItmTestConstants.OVSDB_CONN_PORT, + ItmTestConstants.LOCALHOST_IP); + CheckedFuture future = OvsdbTestUtil.createNode( + connInfo, tepIp, ITMConstants.DEFAULT_TRANSPORT_ZONE, dataBroker); + future.get(); + + // add bridge into node + future = OvsdbTestUtil.addBridgeIntoNode(connInfo, ItmTestConstants.DEF_BR_NAME, + ItmTestConstants.DEF_BR_DPID, dataBroker); + future.get(); + // wait for OvsdbNodeListener to perform config DS update through transaction + Thread.sleep(1000); + + // iid for default-TZ + InstanceIdentifier defTzonePath = ItmTepAutoConfigTestUtil.getTzIid( + ITMConstants.DEFAULT_TRANSPORT_ZONE); + Assert.assertNotNull(defTzonePath); + + // check TEP is added into default-TZ + assertEqualBeans(ExpectedDefTransportZoneObjects.newDefTzWithTep(), + dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, defTzonePath) + .checkedGet().get()); + + IpPrefix subnetMaskObj = ItmUtils.getDummySubnet(); + InstanceIdentifier oldVTepPath = ItmTepAutoConfigTestUtil.getTepIid(subnetMaskObj, + ITMConstants.DEFAULT_TRANSPORT_ZONE, ItmTestConstants.INT_DEF_BR_DPID, + ITMConstants.DUMMY_PORT); + Assert.assertNotNull(oldVTepPath); + + // create Transport-zone TZA + ItmUtils.syncWrite(LogicalDatastoreType.CONFIGURATION, tzonesPath, transportZones, + dataBroker); + + // iid for TZA configured from NB + InstanceIdentifier tzaTzonePath = ItmTepAutoConfigTestUtil.getTzIid( + ItmTestConstants.TZ_NAME); + Assert.assertNotNull(tzaTzonePath); + + // update OVSDB node with tzname=TZA in ExternalIds list + String tzName = ItmTestConstants.TZ_NAME; + OvsdbTestUtil.updateNode(connInfo, tepIp, tzName, null, dataBroker); + future.get(); + // wait for OvsdbNodeListener to perform config DS update through transaction + Thread.sleep(1000); + + // check old TEP which was in default-TZ is deleted + Assert.assertEquals(Optional.absent(), dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, oldVTepPath).get()); + + // check TEP is updated and now it is added into TZA transport-zone when tzname is updated + // to TZA from southbound + assertEqualBeans(ExpectedTransportZoneObjects.updatedTransportZone(), + dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION,tzaTzonePath) + .checkedGet().get()); + } + + @Test + public void tepUpdateForBrNameTest() throws Exception { + // create Transport-zone in advance + ItmUtils.syncWrite(LogicalDatastoreType.CONFIGURATION, tzonesPath, transportZones, dataBroker); + + String tepIp = ItmTestConstants.NB_TZ_TEP_IP; + // prepare OVSDB node with tep-ip set into ExternalIds list + // OvsdbNodeListener would be automatically listen on Node to add TEP + ConnectionInfo connInfo = OvsdbTestUtil.getConnectionInfo(ItmTestConstants.OVSDB_CONN_PORT, + ItmTestConstants.LOCALHOST_IP); + CheckedFuture future = OvsdbTestUtil.createNode( + connInfo, tepIp, ItmTestConstants.TZ_NAME, dataBroker); + future.get(); + + // add bridge into node + future = OvsdbTestUtil.addBridgeIntoNode(connInfo, ItmTestConstants.DEF_BR_NAME, + ItmTestConstants.DEF_BR_DPID, dataBroker); + future.get(); + // wait for OvsdbNodeListener to perform config DS update through transaction + Thread.sleep(1000); + + InstanceIdentifier tzonePath = ItmTepAutoConfigTestUtil.getTzIid( + ItmTestConstants.TZ_NAME); + Assert.assertNotNull(tzonePath); + + // check TEP is added into TZ + assertEqualBeans(ExpectedTransportZoneObjects.newTransportZone(), dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, tzonePath).checkedGet().get()); + + IpPrefix subnetMaskObj = ItmUtils.getDummySubnet(); + + InstanceIdentifier oldVTepPath = ItmTepAutoConfigTestUtil.getTepIid(subnetMaskObj, + ItmTestConstants.TZ_NAME, ItmTestConstants.INT_DEF_BR_DPID, ITMConstants.DUMMY_PORT); + Assert.assertNotNull(oldVTepPath); + + // add new bridge br2 + future = OvsdbTestUtil.addBridgeIntoNode(connInfo, ItmTestConstants.BR2_NAME, + ItmTestConstants.BR2_DPID, dataBroker); + future.get(); + // wait for OvsdbNodeListener to perform config DS update through transaction + Thread.sleep(1000); + + // update OVSDB node with br-name=br2 in ExternalIds column + String brName = ItmTestConstants.BR2_NAME; + future = OvsdbTestUtil.updateNode(connInfo, ItmTestConstants.NB_TZ_TEP_IP, + ItmTestConstants.TZ_NAME, brName, dataBroker); + future.get(); + // wait for OvsdbNodeListener to perform config DS update through transaction + Thread.sleep(1000); + + InstanceIdentifier newVTepPath = ItmTepAutoConfigTestUtil.getTepIid(subnetMaskObj, + ItmTestConstants.TZ_NAME, ItmTestConstants.INT_BR2_DPID, ITMConstants.DUMMY_PORT); + Assert.assertNotNull(newVTepPath); + + // check old TEP having default-bridge-DPID is deleted + Assert.assertEquals(Optional.absent(), dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, oldVTepPath).get()); + + // check TEP is updated with dpnId of br2 when br-name is updated to br2 from southbound + Assert.assertEquals(ItmTestConstants.INT_BR2_DPID, dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, newVTepPath).checkedGet().get().getDpnId()); + } + + @Test + public void tepAddIntoTepsNotHostedListTest() throws Exception { + // add into not hosted list + CheckedFuture future = + ItmTepAutoConfigTestUtil.addTep(ItmTestConstants.NOT_HOSTED_TZ_TEP_IP, + ItmTestConstants.NOT_HOSTED_TZ_TEPDPN_ID, ItmTestConstants.NOT_HOSTED_TZ_NAME, false, dataBroker); + future.get(); + InstanceIdentifier notHostedPath = + ItmTepAutoConfigTestUtil.getTepNotHostedInTZIid(ItmTestConstants.NOT_HOSTED_TZ_NAME); + Assert.assertNotNull(notHostedPath); + + assertEqualBeans(ExpectedTepNotHostedTransportZoneObjects.newTepNotHostedTransportZone(), + dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, notHostedPath) + .checkedGet().get()); + } + + @Test + public void tepDeleteFromTepsNotHostedListTest() throws Exception { + // add into not hosted list + CheckedFuture future = + ItmTepAutoConfigTestUtil.addTep(ItmTestConstants.NOT_HOSTED_TZ_TEP_IP, + ItmTestConstants.NOT_HOSTED_TZ_TEPDPN_ID, ItmTestConstants.NOT_HOSTED_TZ_NAME, false, dataBroker); + future.get(); + InstanceIdentifier notHostedPath = + ItmTepAutoConfigTestUtil.getTepNotHostedInTZIid(ItmTestConstants.NOT_HOSTED_TZ_NAME); + Assert.assertNotNull(notHostedPath); + + assertEqualBeans(ExpectedTepNotHostedTransportZoneObjects.newTepNotHostedTransportZone(), + dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, notHostedPath).checkedGet().get()); + + //delete from not hosted list + future = ItmTepAutoConfigTestUtil.deleteTep(ItmTestConstants.NOT_HOSTED_TZ_TEP_IP, + ItmTestConstants.NOT_HOSTED_TZ_TEPDPN_ID, ItmTestConstants.NOT_HOSTED_TZ_NAME, dataBroker); + future.get(); + + Assert.assertEquals(Optional.absent(), + dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, notHostedPath).get()); + } + + @Test + public void tepMoveFromTepsNotHostedListToTzTest() throws Exception { + // add into not hosted list + CheckedFuture future = + ItmTepAutoConfigTestUtil.addTep(ItmTestConstants.NOT_HOSTED_TZ_TEP_IP, + ItmTestConstants.NOT_HOSTED_TZ_TEPDPN_ID, ItmTestConstants.NOT_HOSTED_TZ_NAME, false, + dataBroker); + future.get(); + InstanceIdentifier notHostedPath = + ItmTepAutoConfigTestUtil.getTepNotHostedInTZIid(ItmTestConstants.NOT_HOSTED_TZ_NAME); + Assert.assertNotNull(notHostedPath); + + assertEqualBeans(ExpectedTepNotHostedTransportZoneObjects.newTepNotHostedTransportZone(), + dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, notHostedPath).checkedGet().get()); + + // create the same TZ + TransportZone transportZoneNorth = new TransportZoneBuilder().setZoneName(ItmTestConstants.NOT_HOSTED_TZ_NAME) + .setTunnelType(ItmTestConstants.TUNNEL_TYPE_VXLAN) + .setKey(new TransportZoneKey(ItmTestConstants.NOT_HOSTED_TZ_NAME)).build(); + Assert.assertNotNull(transportZoneNorth); + + ItmUtils.syncWrite(LogicalDatastoreType.CONFIGURATION, ItmTepAutoConfigTestUtil + .getTzIid(ItmTestConstants.NOT_HOSTED_TZ_NAME), transportZoneNorth, dataBroker); + + // wait for TransportZoneListener to perform config DS update + // for TEP movement through transaction + Thread.sleep(1000); + + InstanceIdentifier tzPath = ItmTepAutoConfigTestUtil.getTzIid( + ItmTestConstants.NOT_HOSTED_TZ_NAME); + Assert.assertNotNull(tzPath); + + // check TZ is Moved + assertEqualBeans(ExpectedTepNotHostedTransportZoneObjects.newTepNotHostedTransportZone().getUnknownVteps() + .get(0).getIpAddress().getIpv4Address().getValue(), dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, tzPath).checkedGet().get().getSubnets().get(0) + .getVteps().get(0).getIpAddress().getIpv4Address().getValue()); + + assertEqualBeans(ExpectedTepNotHostedTransportZoneObjects.newTepNotHostedTransportZone().getUnknownVteps() + .get(0).getDpnId(), dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, tzPath).checkedGet().get().getSubnets().get(0) + .getVteps().get(0).getDpnId()); + + assertEqualBeans(ExpectedTepNotHostedTransportZoneObjects.newTepNotHostedTransportZone().getZoneName(), + dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, tzPath) + .checkedGet().get().getZoneName()); + + // check TZ is removed + Assert.assertEquals(Optional.absent(), dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.CONFIGURATION, notHostedPath).get()); + } +} diff --git a/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTepAutoConfigTestUtil.java b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTepAutoConfigTestUtil.java new file mode 100644 index 000000000..817d7b22e --- /dev/null +++ b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTepAutoConfigTestUtil.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.genius.itm.tests; + +import com.google.common.util.concurrent.CheckedFuture; +import java.math.BigInteger; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.genius.itm.confighelpers.OvsdbTepAddConfigHelper; +import org.opendaylight.genius.itm.confighelpers.OvsdbTepRemoveConfigHelper; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZone; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZoneKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.VtepsKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class ItmTepAutoConfigTestUtil { + + /* transaction methods */ + public static CheckedFuture addTep(String tepIp, + String strDpnId, String tzName, boolean ofTunnel, DataBroker dataBroker) { + WriteTransaction wrTx = dataBroker.newWriteOnlyTransaction(); + + // add TEP received from southbound OVSDB into ITM config DS. + OvsdbTepAddConfigHelper.addTepReceivedFromOvsdb(tepIp, strDpnId, tzName, ofTunnel, + dataBroker, wrTx); + return wrTx.submit(); + } + + public static CheckedFuture deleteTep(String tepIp, + String strDpnId, String tzName, DataBroker dataBroker) { + WriteTransaction wrTx = dataBroker.newWriteOnlyTransaction(); + + // remove TEP received from southbound OVSDB from ITM config DS. + OvsdbTepRemoveConfigHelper.removeTepReceivedFromOvsdb(tepIp, strDpnId, tzName, dataBroker, wrTx); + return wrTx.submit(); + } + + public static CheckedFuture writeItmConfig( + InstanceIdentifier iid, ItmConfig itmConfig, DataBroker dataBroker) { + WriteTransaction tx = dataBroker.newWriteOnlyTransaction(); + tx.put(LogicalDatastoreType.CONFIGURATION, iid, itmConfig); + return tx.submit(); + } + + /* utility methods */ + public static InstanceIdentifier getTzIid(String tzName) { + InstanceIdentifier tzoneIid = + InstanceIdentifier.builder(TransportZones.class) + .child(TransportZone.class, new TransportZoneKey(tzName)) + .build(); + + return tzoneIid; + } + + public static InstanceIdentifier getTepIid(IpPrefix subnetMaskObj, String tzName, + BigInteger dpnId, String portName) { + SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj); + VtepsKey vtepkey = new VtepsKey(dpnId, portName); + + InstanceIdentifier vtepIid = InstanceIdentifier.builder(TransportZones.class) + .child(TransportZone.class, new TransportZoneKey(tzName)) + .child(Subnets.class, subnetsKey).child(Vteps.class, vtepkey).build(); + + return vtepIid; + } + + public static InstanceIdentifier getTepNotHostedInTZIid(String tzName) { + InstanceIdentifier tzonePath = + InstanceIdentifier.builder(TransportZones.class) + .child(TepsNotHostedInTransportZone.class, + new TepsNotHostedInTransportZoneKey(tzName)).build(); + + return tzonePath; + } +} diff --git a/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTestConstants.java b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTestConstants.java index d240fe956..2be45b001 100644 --- a/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTestConstants.java +++ b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTestConstants.java @@ -38,4 +38,29 @@ public interface ItmTestConstants { Class TUNNEL_TYPE_VXLAN = TunnelTypeVxlan.class; Class MONITOR_PROTOCOL = ITMConstants.DEFAULT_MONITOR_PROTOCOL; String DPID_STR_ONE = "1"; + String EXTERNAL_ID_TEP_IP_KEY = "tep-ip"; + String EXTERNAL_ID_TZNAME_KEY = "tzname"; + String EXTERNAL_ID_BR_NAME_KEY = "br-name"; + + String LOCALHOST_IP = "127.0.0.1"; + int OVSDB_CONN_PORT = 6640; + + String DEF_TZ_TEP_IP = "192.168.56.30"; + String NB_TZ_TEP_IP = "192.168.56.40"; + + String DEF_BR_NAME = "br-int"; + String DEF_BR_DPID = "00:00:00:00:00:00:00:01"; + BigInteger INT_DEF_BR_DPID = BigInteger.valueOf(1); + + String BR2_NAME = "br2"; + String BR2_DPID = "00:00:00:00:00:00:00:02"; + BigInteger INT_BR2_DPID = BigInteger.valueOf(2); + + //not hosted tz constants + String NOT_HOSTED_TZ_TEP_IP = "192.168.10.20"; + String NOT_HOSTED_TZ_TEPDPN_ID = "0"; + BigInteger NOT_HOSTED_INT_TZ_TEPDPN_ID = BigInteger.valueOf(0); + String NOT_HOSTED_TZ_NAME = "NotHostedTZ"; + Boolean OF_TUNNEL = false; + String NOT_HOSTED_DEF_BR_DPID = "00:00:00:00:00:00:00:00"; } diff --git a/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTestModule.java b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTestModule.java index b18bf9229..e5e3ad906 100644 --- a/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTestModule.java +++ b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTestModule.java @@ -15,9 +15,11 @@ import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipS import org.opendaylight.genius.idmanager.IdManager; import org.opendaylight.genius.interfacemanager.InterfacemgrProvider; import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager; +import org.opendaylight.genius.itm.globals.ITMConstants; import org.opendaylight.genius.itm.impl.ITMManager; import org.opendaylight.genius.itm.impl.ItmProvider; import org.opendaylight.genius.itm.listeners.InterfaceStateListener; +import org.opendaylight.genius.itm.listeners.OvsdbNodeListener; import org.opendaylight.genius.itm.listeners.TransportZoneListener; import org.opendaylight.genius.itm.listeners.TunnelMonitorChangeListener; import org.opendaylight.genius.itm.listeners.TunnelMonitorIntervalListener; @@ -34,6 +36,7 @@ import org.opendaylight.infrautils.inject.guice.testutils.AbstractGuiceJsr250Mod import org.opendaylight.lockmanager.LockManager; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfigBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.LockManagerService; @@ -41,7 +44,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev16041 * Dependency Injection Wiring for {@link ItmTest}. * * @author Michael Vorburger + * @author Tarun Thakur */ + public class ItmTestModule extends AbstractGuiceJsr250Module { @Override @@ -49,16 +54,17 @@ public class ItmTestModule extends AbstractGuiceJsr250Module { // Bindings for services from this project bind(ItmRpcService.class).to(ItmManagerRpcService.class); bind(ITMManager.class); - bind(ItmConfig.class).toInstance(mock(ItmConfig.class)); bind(ItmProvider.class); - + ItmConfig itmConfigObj = new ItmConfigBuilder() + .setDefTzEnabled(true).setDefTzTunnelType(ITMConstants.TUNNEL_TYPE_VXLAN).build(); + bind(ItmConfig.class).toInstance(itmConfigObj); bind(ItmMonitoringIntervalListener.class); bind(DpnTepsInfoListener.class); bind(StateTunnelListListener.class); bind(ItmMonitoringListener.class); - bind(TunnelMonitorIntervalListener.class); bind(TransportZoneListener.class); + bind(OvsdbNodeListener.class); bind(InterfaceStateListener.class); bind(VtepConfigSchemaListener.class); bind(TunnelMonitorChangeListener.class); diff --git a/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/OvsdbTestUtil.java b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/OvsdbTestUtil.java new file mode 100644 index 000000000..19a2b15bf --- /dev/null +++ b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/OvsdbTestUtil.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.genius.itm.tests; + +import com.google.common.util.concurrent.CheckedFuture; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchExternalIds; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchExternalIdsBuilder; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; + +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class OvsdbTestUtil { + /* methods */ + public static ConnectionInfo getConnectionInfo(int port, String strIpAddress) { + IpAddress ipAddress = new IpAddress(new Ipv4Address(strIpAddress)); + PortNumber portNumber = new PortNumber(port); + + ConnectionInfo connectionInfo = + new ConnectionInfoBuilder().setRemoteIp(ipAddress).setRemotePort(portNumber).build(); + + return connectionInfo; + } + + public static CheckedFuture createNode( + ConnectionInfo connectionInfo, String tepIp, String tzName, DataBroker dataBroker) + throws Exception { + final InstanceIdentifier iid = SouthboundUtils.createInstanceIdentifier(connectionInfo); + + // build Node using its builder class + NodeBuilder nodeBuilder = new NodeBuilder(); + NodeId ovsdbNodeId = SouthboundUtils.createNodeId(connectionInfo.getRemoteIp(), + connectionInfo.getRemotePort()); + nodeBuilder.setNodeId(ovsdbNodeId); + + // build OvsdbNodeAugmentation for Node + OvsdbNodeAugmentationBuilder ovsdbNodeAugBuilder = new OvsdbNodeAugmentationBuilder(); + ovsdbNodeAugBuilder.setConnectionInfo(connectionInfo); + + // create map of key-val pairs + Map externalIds = new HashMap<>(); + if (tepIp != null && !tepIp.isEmpty()) { + externalIds.put(ItmTestConstants.EXTERNAL_ID_TEP_IP_KEY, tepIp); + } + + if (tzName != null) { + externalIds.put(ItmTestConstants.EXTERNAL_ID_TZNAME_KEY, tzName); + } + + // get map-keys into set. + Set externalIdKeys = externalIds.keySet(); + + List externalIdsList = new ArrayList<>(); + String externalIdValue = null; + for (String externalIdKey : externalIdKeys) { + externalIdValue = externalIds.get(externalIdKey); + if (externalIdKey != null && externalIdValue != null) { + externalIdsList.add(new OpenvswitchExternalIdsBuilder().setExternalIdKey(externalIdKey) + .setExternalIdValue(externalIdValue).build()); + } + } + + // set ExternalIds list into Node + ovsdbNodeAugBuilder.setOpenvswitchExternalIds(externalIdsList); + // add OvsdbNodeAugmentation into Node + nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, ovsdbNodeAugBuilder.build()); + Node ovsdbNode = nodeBuilder.build(); + + WriteTransaction transaction = dataBroker.newWriteOnlyTransaction(); + transaction.put(LogicalDatastoreType.OPERATIONAL, iid, ovsdbNode, true); + return transaction.submit(); + } + + public static CheckedFuture updateNode( + ConnectionInfo connectionInfo, String tepIp, String tzName, String brName, + DataBroker dataBroker) throws Exception { + final InstanceIdentifier iid = SouthboundUtils.createInstanceIdentifier(connectionInfo); + + Node oldOvsdbNode = dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.OPERATIONAL, iid).checkedGet().get(); + + // build Node using its builder class + NodeBuilder nodeBuilder = new NodeBuilder(); + nodeBuilder.setNodeId(oldOvsdbNode.getNodeId()); + + // build OvsdbNodeAugmentation for Node + OvsdbNodeAugmentationBuilder ovsdbNodeAugBuilder = new OvsdbNodeAugmentationBuilder(); + ovsdbNodeAugBuilder.setConnectionInfo(connectionInfo); + + // create map of key-val pairs + Map externalIds = new HashMap<>(); + if (tepIp != null && !tepIp.isEmpty()) { + externalIds.put(ItmTestConstants.EXTERNAL_ID_TEP_IP_KEY, tepIp); + } + + if (tzName != null) { + externalIds.put(ItmTestConstants.EXTERNAL_ID_TZNAME_KEY, tzName); + } + + if (brName != null && !brName.isEmpty()) { + externalIds.put(ItmTestConstants.EXTERNAL_ID_BR_NAME_KEY, brName); + } + + // get map-keys into set. + Set externalIdKeys = externalIds.keySet(); + + List externalIdsList = new ArrayList<>(); + String externalIdValue = null; + for (String externalIdKey : externalIdKeys) { + externalIdValue = externalIds.get(externalIdKey); + if (externalIdKey != null && externalIdValue != null) { + externalIdsList.add(new OpenvswitchExternalIdsBuilder().setExternalIdKey(externalIdKey) + .setExternalIdValue(externalIdValue).build()); + } + } + + // set ExternalIds list into Node + ovsdbNodeAugBuilder.setOpenvswitchExternalIds(externalIdsList); + // add OvsdbNodeAugmentation into Node + nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, ovsdbNodeAugBuilder.build()); + Node ovsdbNode = nodeBuilder.build(); + + //ReadWriteTransaction transaction = dataBroker.newReadWriteTransaction(); + WriteTransaction transaction = dataBroker.newWriteOnlyTransaction(); + transaction.put(LogicalDatastoreType.OPERATIONAL, iid, ovsdbNode, true); + return transaction.submit(); + } + + public static CheckedFuture addBridgeIntoNode( + ConnectionInfo connectionInfo, String bridgeName, String dpid, DataBroker dataBroker) throws Exception { + NodeId ovsdbNodeId = SouthboundUtils.createNodeId(connectionInfo.getRemoteIp(), + connectionInfo.getRemotePort()); + NodeKey nodeKey = new NodeKey(ovsdbNodeId); + + NodeBuilder bridgeNodeBuilder = new NodeBuilder(); + + InstanceIdentifier bridgeIid = SouthboundUtils.createInstanceIdentifier(nodeKey, bridgeName); + + NodeId bridgeNodeId = SouthboundUtils.createManagedNodeId(bridgeIid); + bridgeNodeBuilder.setNodeId(bridgeNodeId); + OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder(); + ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName)) + .setDatapathId(new DatapathId(dpid)); + ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef( + SouthboundUtils.createInstanceIdentifier(nodeKey.getNodeId()))); + + bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build()); + + Node bridgeNode = bridgeNodeBuilder.build(); + + WriteTransaction tx = dataBroker.newWriteOnlyTransaction(); + tx.merge(LogicalDatastoreType.OPERATIONAL, bridgeIid, + bridgeNode, true); + return tx.submit(); + } +} diff --git a/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/xtend/ExpectedDefTransportZoneObjects.xtend b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/xtend/ExpectedDefTransportZoneObjects.xtend new file mode 100644 index 000000000..ac5be4e66 --- /dev/null +++ b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/xtend/ExpectedDefTransportZoneObjects.xtend @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.genius.itm.tests.xtend; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.VtepsBuilder; +import org.opendaylight.genius.itm.globals.ITMConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; +import org.opendaylight.genius.itm.tests.ItmTestConstants; + +import static extension org.opendaylight.mdsal.binding.testutils.XtendBuilderExtensions.operator_doubleGreaterThan + +class ExpectedDefTransportZoneObjects { + + static def newDefTzWithVxlanTunnelType() { + new TransportZoneBuilder >> [ + zoneName = ITMConstants.DEFAULT_TRANSPORT_ZONE + tunnelType = TunnelTypeVxlan + ] + } + + static def newDefTzWithGreTunnelType() { + new TransportZoneBuilder >> [ + zoneName = ITMConstants.DEFAULT_TRANSPORT_ZONE + tunnelType = TunnelTypeGre + ] + } + + static def newDefTzWithTep() { + new TransportZoneBuilder >> [ + zoneName = ITMConstants.DEFAULT_TRANSPORT_ZONE + tunnelType = TunnelTypeVxlan + + subnets = #[ + new SubnetsBuilder >> [ + gatewayIp = new IpAddress( new Ipv4Address(ITMConstants.DUMMY_GATEWAY_IP) ) + prefix = new IpPrefix( new Ipv4Prefix(ITMConstants.DUMMY_PREFIX) ) + vlanId = ITMConstants.DUMMY_VLANID + + vteps = #[ + new VtepsBuilder >> [ + dpnId = ItmTestConstants.INT_DEF_BR_DPID + ipAddress = new IpAddress( new Ipv4Address(ItmTestConstants.DEF_TZ_TEP_IP) ) + portname = ITMConstants.DUMMY_PORT + weight = 1 + ] + ] + ] + ] + ] + } +} diff --git a/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/xtend/ExpectedTepNotHostedTransportZoneObjects.xtend b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/xtend/ExpectedTepNotHostedTransportZoneObjects.xtend new file mode 100644 index 000000000..d8b8a2fdf --- /dev/null +++ b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/xtend/ExpectedTepNotHostedTransportZoneObjects.xtend @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.genius.itm.tests.xtend; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.tepsnothostedintransportzone.UnknownVtepsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZoneBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; + +import org.opendaylight.genius.itm.tests.ItmTestConstants; + +import static extension org.opendaylight.mdsal.binding.testutils.XtendBuilderExtensions.operator_doubleGreaterThan + +class ExpectedTepNotHostedTransportZoneObjects { + + static def newTepNotHostedTransportZone() { + new TepsNotHostedInTransportZoneBuilder >> [ + zoneName = ItmTestConstants.NOT_HOSTED_TZ_NAME + unknownVteps = #[ + new UnknownVtepsBuilder >> [ + dpnId = ItmTestConstants.NOT_HOSTED_INT_TZ_TEPDPN_ID + ipAddress = new IpAddress( new Ipv4Address(ItmTestConstants.NOT_HOSTED_TZ_TEP_IP) ) + ofTunnel = ItmTestConstants.OF_TUNNEL + ] + ] + ] + } +} diff --git a/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/xtend/ExpectedTransportZoneObjects.xtend b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/xtend/ExpectedTransportZoneObjects.xtend new file mode 100644 index 000000000..0a25c8ffb --- /dev/null +++ b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/xtend/ExpectedTransportZoneObjects.xtend @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.genius.itm.tests.xtend; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.VtepsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; +import org.opendaylight.genius.itm.tests.ItmTestConstants; +import org.opendaylight.genius.itm.globals.ITMConstants; + +import static extension org.opendaylight.mdsal.binding.testutils.XtendBuilderExtensions.operator_doubleGreaterThan + +class ExpectedTransportZoneObjects { + + static def newTransportZone() { + new TransportZoneBuilder >> [ + zoneName = "TZA" + tunnelType = TunnelTypeVxlan + subnets = #[ + new SubnetsBuilder >> [ + gatewayIp = new IpAddress( new Ipv4Address(ITMConstants.DUMMY_GATEWAY_IP) ) + prefix = new IpPrefix( new Ipv4Prefix(ITMConstants.DUMMY_PREFIX) ) + vlanId = ITMConstants.DUMMY_VLANID + + vteps = #[ + new VtepsBuilder >> [ + dpnId = ItmTestConstants.INT_DEF_BR_DPID + ipAddress = new IpAddress( new Ipv4Address(ItmTestConstants.NB_TZ_TEP_IP) ) + portname = ITMConstants.DUMMY_PORT + weight = 1 + ] + ] + ] + ] + ] + } + + static def updatedTransportZone() { + new TransportZoneBuilder >> [ + zoneName = "TZA" + tunnelType = TunnelTypeVxlan + subnets = #[ + new SubnetsBuilder >> [ + gatewayIp = new IpAddress( new Ipv4Address(ITMConstants.DUMMY_GATEWAY_IP) ) + prefix = new IpPrefix( new Ipv4Prefix(ITMConstants.DUMMY_PREFIX) ) + vlanId = ITMConstants.DUMMY_VLANID + + vteps = #[ + new VtepsBuilder >> [ + dpnId = ItmTestConstants.INT_DEF_BR_DPID + ipAddress = new IpAddress( new Ipv4Address(ItmTestConstants.DEF_TZ_TEP_IP) ) + portname = ITMConstants.DUMMY_PORT + weight = 1 + ] + ] + ] + ] + ] + } + +} -- 2.36.6