X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=southbound%2Fsouthbound-it%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fovsdb%2Fsouthbound%2Fit%2FSouthboundIT.java;h=8104a551fe4caafa079ed728103286e7cf9e1325;hb=b280e0059271cf85d51d6ab241e6c135c2a81832;hp=80846249dd5a29db3cbe434075440120a98724ef;hpb=2ebaf23050854274b6af934d434fb9d2fdb37ee6;p=ovsdb.git diff --git a/southbound/southbound-it/src/test/java/org/opendaylight/ovsdb/southbound/it/SouthboundIT.java b/southbound/southbound-it/src/test/java/org/opendaylight/ovsdb/southbound/it/SouthboundIT.java index 80846249d..6817bfa18 100644 --- a/southbound/southbound-it/src/test/java/org/opendaylight/ovsdb/southbound/it/SouthboundIT.java +++ b/southbound/southbound-it/src/test/java/org/opendaylight/ovsdb/southbound/it/SouthboundIT.java @@ -9,36 +9,54 @@ package org.opendaylight.ovsdb.southbound.it; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; +import static org.ops4j.pax.exam.CoreOptions.composite; import static org.ops4j.pax.exam.CoreOptions.maven; +import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperties; +import static org.ops4j.pax.exam.CoreOptions.vmOption; import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut; +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder; -import com.google.common.collect.ImmutableBiMap; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.ObjectArrays; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.HashMap; +import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Properties; import java.util.Set; +import javax.annotation.Nullable; import javax.inject.Inject; +import org.junit.After; import org.junit.Assert; +import org.junit.Assume; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; +import org.junit.internal.AssumptionViolatedException; import org.junit.runner.RunWith; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase; +import org.opendaylight.ovsdb.lib.OvsdbClient; +import org.opendaylight.ovsdb.lib.notation.Version; +import org.opendaylight.ovsdb.lib.schema.DatabaseSchema; import org.opendaylight.ovsdb.southbound.SouthboundConstants; import org.opendaylight.ovsdb.southbound.SouthboundMapper; import org.opendaylight.ovsdb.southbound.SouthboundProvider; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.ovsdb.southbound.SouthboundUtil; +import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils; +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.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid; import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase; @@ -52,19 +70,49 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.re import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.QosTypeBase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Autoattach; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachKey; 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.DatapathTypeEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntries; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Queues; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIds; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIdsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.Mappings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.MappingsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIds; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIdsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueListBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueListKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIds; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIdsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfigBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldpBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options; @@ -86,7 +134,10 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; import org.ops4j.pax.exam.Configuration; import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.junit.PaxExam; @@ -98,6 +149,11 @@ import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.ImmutableBiMap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + /** * Integration tests for southbound-impl * @@ -106,36 +162,158 @@ import org.slf4j.LoggerFactory; @RunWith(PaxExam.class) @ExamReactorStrategy(PerClass.class) public class SouthboundIT extends AbstractMdsalTestBase { - private static final String EXPECTED_VALUES_KEY = "ExpectedValuesKey"; - private static final String INPUT_VALUES_KEY = "InputValuesKey"; private static final String NETDEV_DP_TYPE = "netdev"; private static final Logger LOG = LoggerFactory.getLogger(SouthboundIT.class); private static final int OVSDB_UPDATE_TIMEOUT = 1000; - private static DataBroker dataBroker = null; + private static final int OVSDB_ROUNDTRIP_TIMEOUT = 10000; + private static final String FORMAT_STR = "%s_%s_%d"; + private static final Version AUTOATTACH_FROM_VERSION = Version.fromString("7.11.2"); + private static final Version IF_INDEX_FROM_VERSION = Version.fromString("7.2.1"); private static String addressStr; - private static String portStr; + private static int portNumber; private static String connectionType; - private static Boolean setup = false; + private static boolean setup = false; private static MdsalUtils mdsalUtils = null; - private static final String NETVIRT = "org.opendaylight.ovsdb.openstack.net-virt"; - private static final String NETVIRTPROVIDERS = "org.opendaylight.ovsdb.openstack.net-virt-providers"; + private static Node ovsdbNode; + private static int testMethodsRemaining; + private static DataBroker dataBroker; + private static Version schemaVersion; + private static OvsdbClient ovsdbClient; + private static DatabaseSchema dbSchema; @Inject private BundleContext bundleContext; - @Configuration - public Option[] config() { - return super.config(); + private static final NotifyingDataChangeListener CONFIGURATION_LISTENER = + new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION); + private static final NotifyingDataChangeListener OPERATIONAL_LISTENER = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL); + + private static class NotifyingDataChangeListener implements DataChangeListener { + private final LogicalDatastoreType type; + private final Set> createdIids = new HashSet<>(); + private final Set> removedIids = new HashSet<>(); + private final Set> updatedIids = new HashSet<>(); + private final InstanceIdentifier iid; + private final int RETRY_WAIT = 100; + + private NotifyingDataChangeListener(LogicalDatastoreType type) { + this.type = type; + this.iid = null; + } + + private NotifyingDataChangeListener(LogicalDatastoreType type, InstanceIdentifier iid) { + this.type = type; + this.iid = iid; + } + + @Override + public void onDataChanged( + AsyncDataChangeEvent, DataObject> asyncDataChangeEvent) { + LOG.info("{} DataChanged: created {}", type, asyncDataChangeEvent.getCreatedData().keySet()); + LOG.info("{} DataChanged: removed {}", type, asyncDataChangeEvent.getRemovedPaths()); + LOG.info("{} DataChanged: updated {}", type, asyncDataChangeEvent.getUpdatedData().keySet()); + createdIids.addAll(asyncDataChangeEvent.getCreatedData().keySet()); + removedIids.addAll(asyncDataChangeEvent.getRemovedPaths()); + updatedIids.addAll(asyncDataChangeEvent.getUpdatedData().keySet()); + // Handled managed iids + for (DataObject obj : asyncDataChangeEvent.getCreatedData().values()) { + if (obj instanceof ManagedNodeEntry) { + ManagedNodeEntry managedNodeEntry = (ManagedNodeEntry) obj; + LOG.info("{} DataChanged: created managed {}", managedNodeEntry.getBridgeRef().getValue()); + createdIids.add(managedNodeEntry.getBridgeRef().getValue()); + } + } + synchronized(this) { + notifyAll(); + } + } + + public boolean isCreated(InstanceIdentifier iid) { + return createdIids.remove(iid); + } + + public boolean isRemoved(InstanceIdentifier iid) { + return removedIids.remove(iid); + } + + public boolean isUpdated(InstanceIdentifier iid) { + return updatedIids.remove(iid); + } + + public void clear() { + createdIids.clear(); + removedIids.clear(); + updatedIids.clear(); + } + + public void registerDataChangeListener() { + dataBroker.registerDataChangeListener(type, iid, this, AsyncDataBroker.DataChangeScope.SUBTREE); + } + + public void waitForCreation(long timeout) throws InterruptedException { + synchronized (this) { + long _start = System.currentTimeMillis(); + LOG.info("Waiting for {} DataChanged creation on {}", type, iid); + while (!isCreated(iid) && (System.currentTimeMillis() - _start) < timeout) { + wait(RETRY_WAIT); + } + LOG.info("Woke up, waited {}ms for creation of {}", (System.currentTimeMillis() - _start), iid); + } + } + + public void waitForDeletion(long timeout) throws InterruptedException { + synchronized (this) { + long _start = System.currentTimeMillis(); + LOG.info("Waiting for {} DataChanged deletion on {}", type, iid); + while (!isRemoved(iid) && (System.currentTimeMillis() - _start) < timeout) { + wait(RETRY_WAIT); + } + LOG.info("Woke up, waited {}ms for deletion of {}", (System.currentTimeMillis() - _start), iid); + } + } + + public void waitForUpdate(long timeout) throws InterruptedException { + synchronized (this) { + long _start = System.currentTimeMillis(); + LOG.info("Waiting for {} DataChanged update on {}", type, iid); + while (!isUpdated(iid) && (System.currentTimeMillis() - _start) < timeout) { + wait(RETRY_WAIT); + } + LOG.info("Woke up, waited {}ms for update of {}", (System.currentTimeMillis() - _start), iid); + } + } + } - @Override - public String getModuleName() { - return "southbound-impl"; + @Configuration + public Option[] config() { + Option[] options = super.config(); + Option[] propertyOptions = getPropertiesOptions(); + Option[] otherOptions = getOtherOptions(); + Option[] combinedOptions = new Option[options.length + propertyOptions.length + otherOptions.length]; + System.arraycopy(options, 0, combinedOptions, 0, options.length); + System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length); + System.arraycopy(otherOptions, 0, combinedOptions, options.length + propertyOptions.length, + otherOptions.length); + return combinedOptions; + } + + private Option[] getOtherOptions() { + return new Option[] { + vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"), + keepRuntimeFolder() + }; } @Override - public String getInstanceName() { - return "southbound-default"; + public String getKarafDistro() { + return maven() + .groupId("org.opendaylight.ovsdb") + .artifactId("southbound-karaf") + .versionAsInProject() + .type("zip") + .getURL(); } @Override @@ -150,7 +328,7 @@ public class SouthboundIT extends AbstractMdsalTestBase { @Override public String getFeatureName() { - return "odl-ovsdb-southbound-impl-ui"; + return "odl-ovsdb-southbound-test"; } protected String usage() { @@ -160,24 +338,15 @@ public class SouthboundIT extends AbstractMdsalTestBase { } @Override - public Option[] getFeaturesOptions() { - return new Option[]{}; - } - - @Override - public Option[] getLoggingOptions() { - Option[] options = new Option[] { + public Option getLoggingOption() { + return composite( editConfigurationFilePut(SouthboundITConstants.ORG_OPS4J_PAX_LOGGING_CFG, - "log4j.logger.org.opendaylight.ovsdb.southbound-impl", - LogLevelOption.LogLevel.DEBUG.name()) - }; - - options = ObjectArrays.concat(options, super.getLoggingOptions(), Option.class); - return options; + "log4j.logger.org.opendaylight.ovsdb", + LogLevelOption.LogLevel.TRACE.name()), + super.getLoggingOption()); } - @Override - public Option[] getPropertiesOptions() { + private Option[] getPropertiesOptions() { Properties props = new Properties(System.getProperties()); String addressStr = props.getProperty(SouthboundITConstants.SERVER_IPADDRESS, SouthboundITConstants.DEFAULT_SERVER_IPADDRESS); @@ -189,7 +358,11 @@ public class SouthboundIT extends AbstractMdsalTestBase { LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}", connectionType, addressStr, portStr); - Option[] options = new Option[] { + return new Option[] { + propagateSystemProperties( + SouthboundITConstants.SERVER_IPADDRESS, + SouthboundITConstants.SERVER_PORT, + SouthboundITConstants.CONNECTION_TYPE), editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES, SouthboundITConstants.SERVER_IPADDRESS, addressStr), editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES, @@ -197,20 +370,20 @@ public class SouthboundIT extends AbstractMdsalTestBase { editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES, SouthboundITConstants.CONNECTION_TYPE, connectionType), }; - return options; } @Before - public void setUp() throws InterruptedException { - if (setup == true) { - LOG.info("Skipping setUp, already initialized"); + @Override + public void setup() throws InterruptedException { + if (setup) { + LOG.info("Skipping setup, already initialized"); return; } try { super.setup(); } catch (Exception e) { - e.printStackTrace(); + LOG.warn("Failed to setup test", e); } //dataBroker = getSession().getSALService(DataBroker.class); Thread.sleep(3000); @@ -218,11 +391,16 @@ public class SouthboundIT extends AbstractMdsalTestBase { Assert.assertNotNull("db should not be null", dataBroker); addressStr = bundleContext.getProperty(SouthboundITConstants.SERVER_IPADDRESS); - portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT); + String portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT); + try { + portNumber = Integer.parseInt(portStr); + } catch (NumberFormatException e) { + fail("Invalid port number " + portStr + System.lineSeparator() + usage()); + } connectionType = bundleContext.getProperty(SouthboundITConstants.CONNECTION_TYPE); LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}", - connectionType, addressStr, portStr); + connectionType, addressStr, portNumber); if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_ACTIVE)) { if (addressStr == null) { fail(usage()); @@ -230,12 +408,64 @@ public class SouthboundIT extends AbstractMdsalTestBase { } mdsalUtils = new MdsalUtils(dataBroker); + final ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + final InstanceIdentifier iid = SouthboundUtils.createInstanceIdentifier(connectionInfo); + dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, + iid, CONFIGURATION_LISTENER, AsyncDataBroker.DataChangeScope.SUBTREE); + dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, + iid, OPERATIONAL_LISTENER, AsyncDataBroker.DataChangeScope.SUBTREE); + + ovsdbNode = connectOvsdbNode(connectionInfo); + try { + ovsdbClient = SouthboundIntegrationTestUtils.getTestConnection(this); + assertNotNull("Invalid Client. Check connection params", ovsdbClient); + + dbSchema = ovsdbClient.getSchema(SouthboundIntegrationTestUtils.OPEN_VSWITCH_SCHEMA).get(); + assertNotNull("Invalid dbSchema.", dbSchema); + schemaVersion = dbSchema.getVersion(); + LOG.info("{} schema version = {}", SouthboundIntegrationTestUtils.OPEN_VSWITCH_SCHEMA, schemaVersion); + } catch (Exception e) { + fail("Error accessing schemaVersion in SouthboundIT setUp()." + usage()); + } + + // Let's count the test methods (we need to use this instead of @AfterClass on teardown() since the latter is + // useless with pax-exam) + for (Method method : getClass().getMethods()) { + boolean testMethod = false; + boolean ignoreMethod = false; + for (Annotation annotation : method.getAnnotations()) { + if (Test.class.equals(annotation.annotationType())) { + testMethod = true; + } + if (Ignore.class.equals(annotation.annotationType())) { + ignoreMethod = true; + } + } + if (testMethod && !ignoreMethod) { + testMethodsRemaining++; + } + } + LOG.info("{} test methods to run", testMethodsRemaining); + setup = true; } + @After + public void teardown() { + testMethodsRemaining--; + LOG.info("{} test methods remaining", testMethodsRemaining); + if (testMethodsRemaining == 0) { + try { + disconnectOvsdbNode(getConnectionInfo(addressStr, portNumber)); + } catch (InterruptedException e) { + LOG.warn("Interrupted while disconnecting", e); + } + } + } + /** * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port - * 6640. This test will wait for incoming connections for {@link SouthboundITConstants.CONNECTION_INIT_TIMEOUT} ms. + * 6640. This test will wait for incoming connections for {@link SouthboundITConstants#CONNECTION_INIT_TIMEOUT} ms. * * @throws InterruptedException */ @@ -247,29 +477,23 @@ public class SouthboundIT extends AbstractMdsalTestBase { } } - private ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) { + private static ConnectionInfo getConnectionInfo(final String addressStr, final int portNumber) { InetAddress inetAddress = null; try { inetAddress = InetAddress.getByName(addressStr); } catch (UnknownHostException e) { - fail("Could not allocate InetAddress: " + e); + fail("Could not resolve " + addressStr + ": " + e); } IpAddress address = SouthboundMapper.createIpAddress(inetAddress); - PortNumber port = new PortNumber(Integer.parseInt(portStr)); + PortNumber port = new PortNumber(portNumber); - LOG.info("connectionInfo: {}", new ConnectionInfoBuilder() + final ConnectionInfo connectionInfo = new ConnectionInfoBuilder() .setRemoteIp(address) .setRemotePort(port) - .build()); - return new ConnectionInfoBuilder() - .setRemoteIp(address) - .setRemotePort(port) - .build(); - } - - private String connectionInfoToString(final ConnectionInfo connectionInfo) { - return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue(); + .build(); + LOG.info("connectionInfo: {}", connectionInfo); + return connectionInfo; } @Test @@ -301,129 +525,152 @@ public class SouthboundIT extends AbstractMdsalTestBase { topology); } - private boolean addOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException { - boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, - SouthboundMapper.createInstanceIdentifier(connectionInfo), - SouthboundMapper.createNode(connectionInfo)); - Thread.sleep(OVSDB_UPDATE_TIMEOUT); - return result; + private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException { + final InstanceIdentifier iid = SouthboundUtils.createInstanceIdentifier(connectionInfo); + Assert.assertTrue( + mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, iid, SouthboundUtils.createNode(connectionInfo))); + waitForOperationalCreation(iid); + Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid); + Assert.assertNotNull(node); + LOG.info("Connected to {}", SouthboundUtils.connectionInfoToString(connectionInfo)); + return node; } - private Node getOvsdbNode(final ConnectionInfo connectionInfo) { - Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, - SouthboundMapper.createInstanceIdentifier(connectionInfo)); - return node; + private void waitForOperationalCreation(InstanceIdentifier iid) throws InterruptedException { + synchronized (OPERATIONAL_LISTENER) { + long _start = System.currentTimeMillis(); + LOG.info("Waiting for OPERATIONAL DataChanged creation on {}", iid); + while (!OPERATIONAL_LISTENER.isCreated( + iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) { + OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT); + } + LOG.info("Woke up, waited {} for creation of {}", (System.currentTimeMillis() - _start), iid); + } } - private boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException { - boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, - SouthboundMapper.createInstanceIdentifier(connectionInfo)); - Thread.sleep(OVSDB_UPDATE_TIMEOUT); - return result; + private static void waitForOperationalDeletion(InstanceIdentifier iid) throws InterruptedException { + synchronized (OPERATIONAL_LISTENER) { + long _start = System.currentTimeMillis(); + LOG.info("Waiting for OPERATIONAL DataChanged deletion on {}", iid); + while (!OPERATIONAL_LISTENER.isRemoved( + iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) { + OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT); + } + LOG.info("Woke up, waited {} for deletion of {}", (System.currentTimeMillis() - _start), iid); + } } - private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException { - Assert.assertTrue(addOvsdbNode(connectionInfo)); - Node node = getOvsdbNode(connectionInfo); - Assert.assertNotNull(node); - LOG.info("Connected to {}", connectionInfoToString(connectionInfo)); - return node; + private void waitForOperationalUpdate(InstanceIdentifier iid) throws InterruptedException { + synchronized (OPERATIONAL_LISTENER) { + long _start = System.currentTimeMillis(); + LOG.info("Waiting for OPERATIONAL DataChanged update on {}", iid); + while (!OPERATIONAL_LISTENER.isUpdated( + iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) { + OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT); + } + LOG.info("Woke up, waited {} for update of {}", (System.currentTimeMillis() - _start), iid); + } } - private boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException { - Assert.assertTrue(deleteOvsdbNode(connectionInfo)); - Node node = getOvsdbNode(connectionInfo); + private static void disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException { + final InstanceIdentifier iid = SouthboundUtils.createInstanceIdentifier(connectionInfo); + Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid)); + waitForOperationalDeletion(iid); + Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid); Assert.assertNull(node); - //Assume.assumeNotNull(node); // Using assumeNotNull because there is no assumeNull - LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo)); - return true; + LOG.info("Disconnected from {}", SouthboundUtils.connectionInfoToString(connectionInfo)); } @Test public void testAddDeleteOvsdbNode() throws InterruptedException { - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - Node ovsdbNode = connectOvsdbNode(connectionInfo); - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); - //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo)); + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + // At this point we're connected, disconnect and reconnect (the connection will be removed at the very end) + disconnectOvsdbNode(connectionInfo); + connectOvsdbNode(connectionInfo); } @Test public void testDpdkSwitch() throws InterruptedException { - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - Node ovsdbNode = connectOvsdbNode(connectionInfo); + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); List datapathTypeEntries = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class) .getDatapathTypeEntry(); if (datapathTypeEntries == null) { LOG.info("DPDK not supported on this node."); } else { - Class dpType = null; - String dpTypeStr = null; for (DatapathTypeEntry dpTypeEntry : datapathTypeEntries) { - dpType = dpTypeEntry.getDatapathType(); - dpTypeStr = SouthboundConstants.DATAPATH_TYPE_MAP.get(dpType); + Class dpType = dpTypeEntry.getDatapathType(); + String dpTypeStr = SouthboundConstants.DATAPATH_TYPE_MAP.get(dpType); LOG.info("dp type is {}", dpTypeStr); if (dpTypeStr.equals(NETDEV_DP_TYPE)) { LOG.info("Found a DPDK node; adding a corresponding netdev device"); - InstanceIdentifier bridgeIid = SouthboundMapper.createInstanceIdentifier(connectionInfo, + InstanceIdentifier bridgeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME)); - NodeId bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid); - addBridge(connectionInfo, bridgeIid, SouthboundITConstants.BRIDGE_NAME, bridgeNodeId, false, null, - true, dpType, null, null); - - // Verify that the device is netdev - OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); - Assert.assertNotNull(bridge); - Assert.assertEquals(dpTypeStr, bridge.getDatapathType()); - - // Add dpdk port - final String TEST_PORT_NAME = "testDPDKPort"; - OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = - createGenericDpdkOvsdbTerminationPointAugmentationBuilder(TEST_PORT_NAME); - Assert.assertTrue(addTerminationPoint(bridgeNodeId, TEST_PORT_NAME, ovsdbTerminationBuilder)); - - // Verify that DPDK port was created - InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); - Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, - terminationPointIid); - Assert.assertNotNull(terminationPointNode); - - // Verify that each termination point has DPDK ifType - Class dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP - .get("dpdk"); - Class opPort = null; - List terminationPoints = terminationPointNode.getTerminationPoint(); - for (TerminationPoint terminationPoint : terminationPoints) { - OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint - .getAugmentation(OvsdbTerminationPointAugmentation.class); - if (ovsdbTerminationPointAugmentation.getName().equals(TEST_PORT_NAME)) { - opPort = ovsdbTerminationPointAugmentation - .getInterfaceType(); - Assert.assertEquals(dpdkIfType, opPort); + NodeId bridgeNodeId = SouthboundUtils.createManagedNodeId(bridgeIid); + try (TestBridge testBridge = new TestBridge(connectionInfo, bridgeIid, + SouthboundITConstants.BRIDGE_NAME, bridgeNodeId, false, null, true, dpType, null, null, + null)) { + // Verify that the device is netdev + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); + Assert.assertNotNull(bridge); + Assert.assertEquals(dpType, bridge.getDatapathType()); + + // Add port for all dpdk interface types (dpdkvhost not supported in existing dpdk ovs) + List dpdkTypes = new ArrayList(); + dpdkTypes.add("dpdk"); + dpdkTypes.add("dpdkr"); + dpdkTypes.add("dpdkvhostuser"); + //dpdkTypes.add("dpdkvhost"); + + for (String dpdkType : dpdkTypes) { + String testPortname = "test"+dpdkType+"port"; + LOG.info("DPDK portname and type is {}, {}", testPortname, dpdkType); + Class dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP + .get(dpdkType); + OvsdbTerminationPointAugmentationBuilder ovsdbTerminationpointBuilder = + createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(testPortname, + dpdkIfType); + Assert.assertTrue( + addTerminationPoint(bridgeNodeId, testPortname, ovsdbTerminationpointBuilder)); + } + + // Verify that all DPDK ports are created + InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); + Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, + terminationPointIid); + Assert.assertNotNull(terminationPointNode); + + // Verify that each termination point has the specific DPDK ifType + for (String dpdkType : dpdkTypes) { + String testPortname = "test"+dpdkType+"port"; + Class dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP + .get(dpdkType); + List terminationPoints = terminationPointNode.getTerminationPoint(); + for (TerminationPoint terminationPoint : terminationPoints) { + OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint + .getAugmentation(OvsdbTerminationPointAugmentation.class); + if (ovsdbTerminationPointAugmentation.getName().equals(testPortname)) { + Class opPort = ovsdbTerminationPointAugmentation + .getInterfaceType(); + Assert.assertEquals(dpdkIfType, opPort); + } + } } } - Assert.assertTrue(deleteBridge(connectionInfo)); - break; } + break; } } - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); } @Test public void testOvsdbNodeOvsVersion() throws InterruptedException { - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - Node ovsdbNode = connectOvsdbNode(connectionInfo); OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class); Assert.assertNotNull(ovsdbNodeAugmentation); assertNotNull(ovsdbNodeAugmentation.getOvsVersion()); - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); - //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo)); } @Test public void testOpenVSwitchOtherConfig() throws InterruptedException { - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - Node ovsdbNode = connectOvsdbNode(connectionInfo); OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class); Assert.assertNotNull(ovsdbNodeAugmentation); List otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs(); @@ -439,22 +686,50 @@ public class SouthboundIT extends AbstractMdsalTestBase { } else { LOG.info("other_config is not present"); } - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); - //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo)); } - private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder, + @Test + public void testOvsdbBridgeControllerInfo() throws InterruptedException { + ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portNumber); + String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode); + assertNotNull("Failed to get controller target", controllerTarget); + List setControllerEntry = createControllerEntry(controllerTarget); + Uri setUri = new Uri(controllerTarget); + try (TestBridge testBridge = new TestBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true, + SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, + setControllerEntry, null)) { + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); + Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME, bridge); + Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(), + bridge.getControllerEntry()); + List getControllerEntries = bridge.getControllerEntry(); + for (ControllerEntry entry : getControllerEntries) { + if (entry.getTarget() != null) { + Assert.assertEquals(setUri.toString(), entry.getTarget().toString()); + } + } + } + } + + private List createControllerEntry(String controllerTarget) { + List controllerEntriesList = new ArrayList<>(); + controllerEntriesList.add(new ControllerEntryBuilder() + .setTarget(new Uri(controllerTarget)) + .build()); + return controllerEntriesList; + } + + private static void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder, final ConnectionInfo connectionInfo) { - InstanceIdentifier connectionNodePath = SouthboundMapper.createInstanceIdentifier(connectionInfo); + InstanceIdentifier connectionNodePath = SouthboundUtils.createInstanceIdentifier(connectionInfo); ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath)); } - private List createMdsalProtocols() { - List protocolList = new ArrayList(); + private static List createMdsalProtocols() { + List protocolList = new ArrayList<>(); ImmutableBiMap> mapper = SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse(); - protocolList.add(new ProtocolEntryBuilder(). - setProtocol((Class) mapper.get("OpenFlow13")).build()); + protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build()); return protocolList; } @@ -480,9 +755,19 @@ public class SouthboundIT extends AbstractMdsalTestBase { return ovsdbTerminationBuilder; } + private OvsdbTerminationPointAugmentationBuilder createSpecificDpdkOvsdbTerminationPointAugmentationBuilder( + String testPortname,Class dpdkIfType) { + OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = + createGenericOvsdbTerminationPointAugmentationBuilder(); + ovsdbTerminationBuilder.setName(testPortname); + ovsdbTerminationBuilder.setInterfaceType(dpdkIfType); + return ovsdbTerminationBuilder; + } + private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName, - final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder) - throws InterruptedException { + final OvsdbTerminationPointAugmentationBuilder + ovsdbTerminationPointAugmentationBuilder) + throws InterruptedException { InstanceIdentifier portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId); NodeBuilder portNodeBuilder = new NodeBuilder(); @@ -500,71 +785,389 @@ public class SouthboundIT extends AbstractMdsalTestBase { return result; } - /* - * base method for adding test bridges. Other helper methods used to create bridges should utilize this method. - * - * @param connectionInfo - * @param bridgeIid if passed null, one is created - * @param bridgeName cannot be null - * @param bridgeNodeId if passed null, one is created based on bridgeIid - * @param setProtocolEntries toggles whether default protocol entries are set for the bridge - * @param failMode toggles whether default fail mode is set for the bridge - * @param setManagedBy toggles whether to setManagedBy for the bridge - * @param dpType if passed null, this parameter is ignored - * @param externalIds if passed null, this parameter is ignored - * @param otherConfig if passed null, this parameter is ignored - * @return success of bridge addition - * @throws InterruptedException - */ - private boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier bridgeIid, - final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries, - final Class failMode, final boolean setManagedBy, - final Class dpType, - final List externalIds, - final List otherConfigs) throws InterruptedException { - - NodeBuilder bridgeNodeBuilder = new NodeBuilder(); - if (bridgeIid == null) { - bridgeIid = SouthboundMapper.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)); - } - if (bridgeNodeId == null) { - bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid); - } - bridgeNodeBuilder.setNodeId(bridgeNodeId); - OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder(); - ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName)); - if (setProtocolEntries) { - ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols()); - } - if (failMode != null) { + private static class TestBridge implements AutoCloseable { + private final ConnectionInfo connectionInfo; + private final String bridgeName; + + /** + * Creates a test bridge which can be automatically removed when no longer necessary. + * + * @param connectionInfo The connection information. + * @param bridgeIid The bridge identifier; if {@code null}, one is created based on {@code bridgeName}. + * @param bridgeName The bridge name; must be provided. + * @param bridgeNodeId The bridge node identifier; if {@code null}, one is created based on {@code bridgeIid}. + * @param setProtocolEntries {@code true} to set default protocol entries for the bridge. + * @param failMode The fail mode to set for the bridge. + * @param setManagedBy {@code true} to specify {@code setManagedBy} for the bridge. + * @param dpType The datapath type. + * @param externalIds The external identifiers if any. + * @param otherConfigs The other configuration items if any. + */ + public TestBridge(final ConnectionInfo connectionInfo, @Nullable InstanceIdentifier bridgeIid, + final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries, + final Class failMode, final boolean setManagedBy, + @Nullable final Class dpType, + @Nullable final List externalIds, + @Nullable final List controllerEntries, + @Nullable final List otherConfigs) { + this.connectionInfo = connectionInfo; + this.bridgeName = bridgeName; + NodeBuilder bridgeNodeBuilder = new NodeBuilder(); + if (bridgeIid == null) { + bridgeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)); + } + if (bridgeNodeId == null) { + bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid); + } + bridgeNodeBuilder.setNodeId(bridgeNodeId); + OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder(); + ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName)); + if (setProtocolEntries) { + ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols()); + } ovsdbBridgeAugmentationBuilder.setFailMode(failMode); + if (setManagedBy) { + setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo); + } + ovsdbBridgeAugmentationBuilder.setDatapathType(dpType); + ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds); + ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries); + ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs); + bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build()); + LOG.debug("Built with the intent to store bridge data {}", ovsdbBridgeAugmentationBuilder.toString()); + Assert.assertTrue( + mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, bridgeNodeBuilder.build())); + try { + Thread.sleep(OVSDB_UPDATE_TIMEOUT); + } catch (InterruptedException e) { + LOG.warn("Sleep interrupted while waiting for bridge creation (bridge {})", bridgeName, e); + } } - if (setManagedBy) { - setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo); + + public TestBridge(final ConnectionInfo connectionInfo, final String bridgeName) { + this(connectionInfo, null, bridgeName, null, true, + SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null); } - if (dpType != null) { - ovsdbBridgeAugmentationBuilder.setDatapathType(dpType); + + @Override + public void close() { + final InstanceIdentifier iid = + SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)); + Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid)); + try { + Thread.sleep(OVSDB_UPDATE_TIMEOUT); + } catch (InterruptedException e) { + LOG.warn("Sleep interrupted while waiting for bridge deletion (bridge {})", bridgeName, e); + } } - if (externalIds != null) { - ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds); + } + + private static class TestAutoAttach implements AutoCloseable { + private final ConnectionInfo connectionInfo; + private final Uri autoattachId; + private final Uri bridgeId; + + public TestAutoAttach (final ConnectionInfo connectionInfo, + final Uri autoattachId, + final Uri bridgeId, + @Nullable final String systemName, + @Nullable final String systemDescription, + @Nullable final List mappings, + @Nullable final List externalIds) { + this.connectionInfo = connectionInfo; + this.autoattachId = autoattachId; + this.bridgeId = bridgeId; + + Autoattach aaEntry = new AutoattachBuilder() + .setAutoattachId(autoattachId) + .setBridgeId(bridgeId) + .setSystemName(systemName) + .setSystemDescription(systemDescription) + .setMappings(mappings) + .setAutoattachExternalIds(externalIds) + .build(); + InstanceIdentifier iid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(Autoattach.class, aaEntry.getKey()); + final NotifyingDataChangeListener aaOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid); + aaOperationalListener.registerDataChangeListener(); + + Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, aaEntry)); + try { + aaOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT); + } catch (InterruptedException e) { + LOG.warn("Sleep interrupted while waiting for queue {}", iid, e); + } } - if (otherConfigs != null) { - ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs); + @Override + public void close() { + final InstanceIdentifier iid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(Autoattach.class, new AutoattachKey(this.autoattachId)); + final NotifyingDataChangeListener aaOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid); + aaOperationalListener.registerDataChangeListener(); + + Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid)); + try { + aaOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT); + } catch (InterruptedException e) { + LOG.warn("Sleep interrupted while waiting for qos deletion (qos {})", iid, e); + } + } + } + + @Test + public void testCRUDAutoAttach() throws InterruptedException { + final boolean isOldSchema = schemaVersion.compareTo(AUTOATTACH_FROM_VERSION) < 0; + + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + String testAutoattachId = new String("testAutoattachEntry"); + String testSystemName = new String("testSystemName"); + String testSystemDescription = new String("testSystemDescription"); + String testAutoattachExternalKey = new String("testAutoattachExternalKey"); + String testAutoattachExternalValue = new String("testAutoattachExternalValue"); + + try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); + Assert.assertNotNull(bridge); + + // CREATE: Create Autoattach table + NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier( + connectionInfo, bridge.getBridgeName())); + String bridgeId = nodeId.getValue(); + try(TestAutoAttach testAutoattach = new TestAutoAttach(connectionInfo, new Uri(testAutoattachId), + new Uri(bridgeId), testSystemName, testSystemDescription, null, null)) { + // READ: Read md-sal operational datastore to see if the AutoAttach table was created + // and if Bridge table was updated with AutoAttach Uuid + OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + Autoattach operAa = getAutoAttach(ovsdbNodeAugmentation, new Uri(testAutoattachId)); + + // skip tests after verifying that Autoattach doesn't break with unsupported schema + Assume.assumeFalse(isOldSchema); + + // FIXME: Remove once CRUD is supported + Assume.assumeFalse(operAa == null); + + Assert.assertNotNull(operAa); + Assert.assertEquals(testSystemName, operAa.getSystemName()); + bridge = getBridge(connectionInfo); + Uuid aaUuid = new Uuid(operAa.getAutoattachUuid().getValue()); + Assert.assertEquals(aaUuid, bridge.getAutoAttach()); + + // UPDATE: Update mappings column of AutoAttach table that was created + List mappings = ImmutableList.of(new MappingsBuilder().setMappingsKey(100L).setMappingsValue(200).build()); + Autoattach updatedAa = new AutoattachBuilder() + .setAutoattachId(new Uri(testAutoattachId)) + .setMappings(mappings) + .build(); + InstanceIdentifier iid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(Autoattach.class, updatedAa.getKey()); + final NotifyingDataChangeListener aaOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid); + aaOperationalListener.registerDataChangeListener(); + Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, updatedAa)); + aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // UPDATE: Update external_ids column of AutoAttach table that was created + List externalIds = new ArrayList<>(); + externalIds.add(new AutoattachExternalIdsBuilder() + .setAutoattachExternalIdKey(testAutoattachExternalKey) + .setAutoattachExternalIdValue(testAutoattachExternalValue) + .build()); + updatedAa = new AutoattachBuilder() + .setAutoattachId(new Uri(testAutoattachId)) + .setAutoattachExternalIds(externalIds) + .build(); + Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, updatedAa)); + aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // READ: Read the updated AutoAttach table for latest mappings and external_ids column value + ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + operAa = getAutoAttach(ovsdbNodeAugmentation, new Uri(testAutoattachId)); + Assert.assertNotNull(operAa); + List operMappingsList = operAa.getMappings(); + for (Mappings operMappings: operMappingsList) { + Assert.assertEquals(mappings.get(operMappingsList.indexOf(operMappings)).getMappingsKey(), operMappings.getMappingsKey()); + Assert.assertEquals(mappings.get(operMappingsList.indexOf(operMappings)).getMappingsValue(), operMappings.getMappingsValue()); + } + List operExternalIds = operAa.getAutoattachExternalIds(); + externalIds.add(new AutoattachExternalIdsBuilder() + .setAutoattachExternalIdKey(SouthboundConstants.AUTOATTACH_ID_EXTERNAL_ID_KEY) + .setAutoattachExternalIdValue(operAa.getAutoattachId().getValue()) + .build()); + for (AutoattachExternalIds operExternalId : operExternalIds) { + Assert.assertEquals(externalIds.get(operExternalIds.indexOf(operExternalId)).getAutoattachExternalIdKey(), + operExternalId.getAutoattachExternalIdKey()); + Assert.assertEquals(externalIds.get(operExternalIds.indexOf(operExternalId)).getAutoattachExternalIdValue(), + operExternalId.getAutoattachExternalIdValue()); + } + + // DELETE: Delete AutoAttach table + Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid)); + aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + operAa = getAutoAttach(ovsdbNodeAugmentation, new Uri(testAutoattachId)); + Assert.assertNull(operAa); + } catch (AssumptionViolatedException e) { + LOG.warn("Skipped test for Autoattach due to unsupported schema", e); + } catch (Exception e) { + fail("Unexpected exception in CRUD test for Autoattach table for schema:" + schemaVersion.toString() +". " + e); + } + } + } + + private Autoattach getAutoAttach(OvsdbNodeAugmentation ovsdbNodeAugmentation, Uri uri) { + if (ovsdbNodeAugmentation.getAutoattach() != null + && !ovsdbNodeAugmentation.getAutoattach().isEmpty()) { + for (Autoattach aa : ovsdbNodeAugmentation.getAutoattach()) { + if (aa.getKey().getAutoattachId().equals(uri)) { + return aa; + } + } + } + return null; + } + + private static class TestQos implements AutoCloseable { + private final ConnectionInfo connectionInfo; + private final Uri qosId; + + /** + * Creates a test qos entry which can be automatically removed when no longer necessary. + * + * @param connectionInfo The connection information. + * @param qosId The Qos identifier. + * @param qosType The qos type. + * @param externalIds The external identifiers if any. + * @param otherConfigs The other configuration items if any. + */ + public TestQos(final ConnectionInfo connectionInfo, + final Uri qosId, + final Class qosType, + @Nullable final List externalIds, + @Nullable final List otherConfigs) { + this.connectionInfo = connectionInfo; + this.qosId = qosId; + + QosEntries qosEntry = new QosEntriesBuilder() + .setQosId(qosId) + .setQosType(qosType) + .setQosExternalIds(externalIds) + .setQosOtherConfig(otherConfigs) + .build(); + InstanceIdentifier qeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(QosEntries.class, qosEntry.getKey()); + final NotifyingDataChangeListener qosOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qeIid); + qosOperationalListener.registerDataChangeListener(); + + Assert.assertTrue( + mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + qeIid, qosEntry)); + + try { + qosOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT); + } catch (InterruptedException e) { + LOG.warn("Sleep interrupted while waiting for queue {}", qeIid, e); + } + + } + + @Override + public void close() { + final InstanceIdentifier qeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(QosEntries.class, new QosEntriesKey(this.qosId)); + final NotifyingDataChangeListener qosOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qeIid); + qosOperationalListener.registerDataChangeListener(); + + Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qeIid)); + try { + qosOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT); + } catch (InterruptedException e) { + LOG.warn("Sleep interrupted while waiting for qos deletion (qos {})", qeIid, e); + } } - bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build()); - LOG.debug("Built with the intent to store bridge data {}", - ovsdbBridgeAugmentationBuilder.toString()); - boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, - bridgeIid, bridgeNodeBuilder.build()); - Thread.sleep(OVSDB_UPDATE_TIMEOUT); - return result; } - private boolean addBridge(final ConnectionInfo connectionInfo, final String bridgeName) - throws InterruptedException { + private static class TestQueue implements AutoCloseable { + private final ConnectionInfo connectionInfo; + private final Uri queueId; + + /** + * Creates a test queue entry which can be automatically removed when no longer necessary. + * + * @param connectionInfo The connection information. + * @param queueId The Queue identifier. + * @param queueDscp The queue dscp value. + * @param externalIds The external identifiers if any. + * @param otherConfigs The other configuration items if any. + */ + public TestQueue(final ConnectionInfo connectionInfo, + final Uri queueId, + final Short queueDscp, + @Nullable final List externalIds, + @Nullable final List otherConfigs) { + this.connectionInfo = connectionInfo; + this.queueId = queueId; + + Queues queue = new QueuesBuilder() + .setQueueId(queueId) + .setDscp(queueDscp) + .setQueuesExternalIds(externalIds) + .setQueuesOtherConfig(otherConfigs) + .build(); + InstanceIdentifier qIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(Queues.class, queue.getKey()); + final NotifyingDataChangeListener queueOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qIid); + queueOperationalListener.registerDataChangeListener(); + + Assert.assertTrue( + mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + qIid, queue)); + + try { + queueOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT); + } catch (InterruptedException e) { + LOG.warn("Sleep interrupted while waiting for queue {}", queueId, e); + } + } + + @Override + public void close() { + InstanceIdentifier qIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(Queues.class, new QueuesKey(this.queueId)); + final NotifyingDataChangeListener queueOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qIid); + queueOperationalListener.registerDataChangeListener(); + + Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qIid)); + try { + queueOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT); + } catch (InterruptedException e) { + LOG.warn("Sleep interrupted while waiting for queue deletion (queue {})", queueId, e); + } + } + } - return addBridge(connectionInfo, null, bridgeName, null, true, - SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null); + private OvsdbNodeAugmentation getOvsdbNode(ConnectionInfo connectionInfo, LogicalDatastoreType store) { + InstanceIdentifier nodeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo); + Node node = mdsalUtils.read(store, nodeIid); + Assert.assertNotNull(node); + OvsdbNodeAugmentation ovsdbNodeAugmentation = node.getAugmentation(OvsdbNodeAugmentation.class); + Assert.assertNotNull(ovsdbNodeAugmentation); + return ovsdbNodeAugmentation; } private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) { @@ -575,13 +1178,13 @@ public class SouthboundIT extends AbstractMdsalTestBase { * Extract the store type data store contents for the particular bridge identified by * bridgeName. * - * @param connectionInfo - * @param bridgeName + * @param connectionInfo the connection information + * @param bridgeName the bridge name * @param store defined by the LogicalDatastoreType enumeration * @return store type data store contents */ private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName, - LogicalDatastoreType store) { + LogicalDatastoreType store) { Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store); Assert.assertNotNull(bridgeNode); OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class); @@ -593,8 +1196,8 @@ public class SouthboundIT extends AbstractMdsalTestBase { * extract the LogicalDataStoreType.OPERATIONAL type data store contents for the particular bridge * identified by bridgeName * - * @param connectionInfo - * @param bridgeName + * @param connectionInfo the connection information + * @param bridgeName the bridge name * @see SouthboundIT.getBridge(ConnectionInfo, String, LogicalDatastoreType) * @return LogicalDatastoreType.OPERATIONAL type data store contents */ @@ -606,15 +1209,14 @@ public class SouthboundIT extends AbstractMdsalTestBase { * Extract the node contents from store type data store for the * bridge identified by bridgeName * - * @param connectionInfo - * @param bridgeName + * @param connectionInfo the connection information + * @param bridgeName the bridge name * @param store defined by the LogicalDatastoreType enumeration * @return store type data store contents */ private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) { InstanceIdentifier bridgeIid = - SouthboundMapper.createInstanceIdentifier(connectionInfo, - new OvsdbBridgeName(bridgeName)); + SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)); return mdsalUtils.read(store, bridgeIid); } @@ -622,953 +1224,329 @@ public class SouthboundIT extends AbstractMdsalTestBase { * Extract the node contents from LogicalDataStoreType.OPERATIONAL data store for the * bridge identified by bridgeName * - * @param connectionInfo - * @param bridgeName + * @param connectionInfo the connection information + * @param bridgeName the bridge name * @return LogicalDatastoreType.OPERATIONAL type data store contents */ private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) { return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL); } - private boolean deleteBridge(ConnectionInfo connectionInfo) throws InterruptedException { - return deleteBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME); - } - - private boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName) - throws InterruptedException { - - boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, - SouthboundMapper.createInstanceIdentifier(connectionInfo, - new OvsdbBridgeName(bridgeName))); - Thread.sleep(OVSDB_UPDATE_TIMEOUT); - return result; - } - @Test public void testAddDeleteBridge() throws InterruptedException { - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - Node ovsdbNode = connectOvsdbNode(connectionInfo); - - Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)); - OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); - Assert.assertNotNull(bridge); - LOG.info("bridge: {}", bridge); - - Assert.assertTrue(deleteBridge(connectionInfo)); + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); - //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo)); + try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); + Assert.assertNotNull(bridge); + LOG.info("bridge: {}", bridge); + } } private InstanceIdentifier getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) { - return SouthboundMapper.createInstanceIdentifier(connectionInfo, - bridge.getBridgeName()); + return SouthboundUtils.createInstanceIdentifier(connectionInfo, bridge.getBridgeName()); } /** * Extracts the TerminationPointAugmentation for the index TerminationPoint * on bridgeName * - * @param connectionInfo - * @param bridgeName - * @param store - * @param index - * @return + * @param connectionInfo the connection information + * @param bridgeName the bridge name + * @param store defined by the LogicalDatastoreType enumeration + * @param index the index we're interested in + * @return the augmentation (or {@code null} if none) */ - private OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation(ConnectionInfo connectionInfo, - String bridgeName, LogicalDatastoreType store, int index ) { + private OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation( + ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index) { - return ((OvsdbTerminationPointAugmentation) - getBridgeNode(connectionInfo, bridgeName, store) - .getTerminationPoint().get(index) - .getAugmentation(OvsdbTerminationPointAugmentation.class)); + List tpList = getBridgeNode(connectionInfo, bridgeName, store).getTerminationPoint(); + if (tpList == null) { + return null; + } + return tpList.get(index).getAugmentation(OvsdbTerminationPointAugmentation.class); } @Test - public void testTerminationPointOfPort() throws InterruptedException { - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - connectOvsdbNode(connectionInfo); + public void testCRUDTerminationPointIfIndex() throws InterruptedException { + final boolean isOldSchema = schemaVersion.compareTo(IF_INDEX_FROM_VERSION) < 0; + Assume.assumeFalse(isOldSchema); + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + + // Test create ifIndex + try (TestBridge testBridge = new TestBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME, null, true, + SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), + true, SouthboundMapper.createDatapathType("netdev"), null, null, null)) { + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); + Assert.assertNotNull(bridge); + LOG.info("bridge: {}", bridge); + NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundUtils.createInstanceIdentifier( + connectionInfo, bridge.getBridgeName())); + OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = + createGenericOvsdbTerminationPointAugmentationBuilder(); + String portName = "testIfIndex"; + ovsdbTerminationBuilder.setName(portName); - Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)); - OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); - Assert.assertNotNull(bridge); - LOG.info("bridge: {}", bridge); - NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier( - connectionInfo, bridge.getBridgeName())); - OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = - createGenericOvsdbTerminationPointAugmentationBuilder(); - String portName = "testOfPort"; - ovsdbTerminationBuilder.setName(portName); - Long ofPortExpected = new Long(45002); - ovsdbTerminationBuilder.setOfport(ofPortExpected); - Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); - InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); - Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); - Assert.assertNotNull(terminationPointNode); - - List terminationPoints = terminationPointNode.getTerminationPoint(); - for (TerminationPoint terminationPoint : terminationPoints) { - OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = - terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); - if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { - Long ofPort = ovsdbTerminationPointAugmentation.getOfport(); - // if ephemeral port 45002 is in use, ofPort is set to 1 - Assert.assertTrue(ofPort.equals(ofPortExpected) || ofPort.equals(new Long(1))); - LOG.info("ofPort: {}", ofPort); + Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); + Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); + Assert.assertNotNull(terminationPointNode); + + // Test read ifIndex + List terminationPoints = terminationPointNode.getTerminationPoint(); + for (TerminationPoint terminationPoint : terminationPoints) { + OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = + terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { + Long ifIndex = ovsdbTerminationPointAugmentation.getIfindex(); + Assert.assertNotNull(ifIndex); + LOG.info("ifIndex: {} for the port:{}", ifIndex, portName); + } } } - Assert.assertTrue(deleteBridge(connectionInfo)); - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); } @Test - public void testTerminationPointOfPortRequest() throws InterruptedException { - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - connectOvsdbNode(connectionInfo); - Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)); - OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); - Assert.assertNotNull(bridge); - NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier( - connectionInfo, bridge.getBridgeName())); - OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = - createGenericOvsdbTerminationPointAugmentationBuilder(); - String portName = "testOfPortRequest"; - ovsdbTerminationBuilder.setName(portName); - Long ofPortExpected = new Long(45008); - Integer ofPortRequestExpected = ofPortExpected.intValue(); - Long ofPortInput = new Long(45008); - ovsdbTerminationBuilder.setOfport(ofPortInput); - ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected); - Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); - InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); - Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); - Assert.assertNotNull(terminationPointNode); - - List terminationPoints = terminationPointNode.getTerminationPoint(); - for (TerminationPoint terminationPoint : terminationPoints) { - OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = - terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); - if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { - Long ofPort = ovsdbTerminationPointAugmentation.getOfport(); - // if ephemeral port 45002 is in use, ofPort is set to 1 - Assert.assertTrue(ofPort.equals(ofPortExpected) || ofPort.equals(new Long(1))); - LOG.info("ofPort: {}", ofPort); - - Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest(); - Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected)); - LOG.info("ofPortRequest: {}", ofPortRequest); - } - } - Assert.assertTrue(deleteBridge(connectionInfo)); - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); - } + public void testCRDTerminationPointOfPort() throws InterruptedException { + final Long OFPORT_EXPECTED = 45002L; - /* - * Generates the test cases involved in testing PortExternalIds. See inline comments for descriptions of - * the particular cases considered. - * - * The return value is a Map in the form (K,V)=(testCaseName,testCase). - * - testCaseName is a String - * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of - * either corresponding INPUT port external_ids, or EXPECTED port external_ids - * INPUT is the List we use when calling - * TerminationPointAugmentationBuilder.setPortExternalIds() - * EXPECTED is the List we expect to receive after calling - * TerminationPointAugmentationBuilder.getPortExternalIds() - */ - private Map>> generatePortExternalIdsTestCases() { - Map>> testMap = - new HashMap>>(); + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); - final String PORT_EXTERNAL_ID_KEY = "PortExternalIdKey"; - final String PORT_EXTERNAL_ID_VALUE = "PortExternalIdValue"; - final String FORMAT_STR = "%s_%s_%d"; - final String GOOD_KEY = "GoodKey"; - final String GOOD_VALUE = "GoodValue"; - final String NO_VALUE_FOR_KEY = "NoValueForKey"; - final String NO_KEY_FOR_VALUE = "NoKeyForValue"; + // CREATE + try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); + Assert.assertNotNull(bridge); + LOG.info("bridge: {}", bridge); + NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundUtils.createInstanceIdentifier( + connectionInfo, bridge.getBridgeName())); + OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = + createGenericOvsdbTerminationPointAugmentationBuilder(); + String portName = "testOfPort"; + ovsdbTerminationBuilder.setName(portName); - // Test Case 1: TestOneExternalId - // Test Type: Positive - // Description: Create a termination point with one PortExternalIds - // Expected: A port is created with the single external_ids specified below - final String testOneExternalIdName = "TestOneExternalId"; - int externalIdCounter = 0; - List oneExternalId = (List) Lists.newArrayList( - (new PortExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testOneExternalIdName, - PORT_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format(FORMAT_STR, testOneExternalIdName, - PORT_EXTERNAL_ID_VALUE, externalIdCounter)) - .build())); - Map> testCase = Maps.newHashMap(); - testCase.put(EXPECTED_VALUES_KEY, oneExternalId); - testCase.put(INPUT_VALUES_KEY, oneExternalId); - testMap.put(testOneExternalIdName, testCase); - - // Test Case 2: TestFiveExternalId - // Test Type: Positive - // Description: Create a termination point with multiple (five) PortExternalIds - // Expected: A port is created with the five external_ids specified below - final String testFiveExternalIdName = "TestFiveExternalId"; - externalIdCounter = 0; - List fiveExternalId = (List) Lists.newArrayList( - (new PortExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName, - PORT_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName, - PORT_EXTERNAL_ID_VALUE, externalIdCounter)) - .build()), - (new PortExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName, - PORT_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName, - PORT_EXTERNAL_ID_VALUE, externalIdCounter)) - .build()), - (new PortExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName, - PORT_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName, - PORT_EXTERNAL_ID_VALUE, externalIdCounter)) - .build()), - (new PortExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName, - PORT_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName, - PORT_EXTERNAL_ID_VALUE, externalIdCounter)) - .build()), - (new PortExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName, - PORT_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName, - PORT_EXTERNAL_ID_VALUE, externalIdCounter)) - .build())); - testCase = Maps.newHashMap(); - testCase.put(EXPECTED_VALUES_KEY, fiveExternalId); - testCase.put(INPUT_VALUES_KEY, fiveExternalId); - testMap.put(testOneExternalIdName, testCase); - - // Test Case 3: TestOneGoodExternalIdOneMalformedExternalIdValue - // Test Type: Negative - // Description: - // One perfectly fine PortExternalId - // (TestOneGoodExternalIdOneMalformedExternalIdValue_PortExternalIdKey_1, - // TestOneGoodExternalIdOneMalformedExternalId_PortExternalIdValue_1) - // and one malformed PortExternalId which only has key specified - // (TestOneGoodExternalIdOneMalformedExternalIdValue_NoValueForKey_2, - // UNSPECIFIED) - // Expected: A port is created without any external_ids - final String testOneGoodExternalIdOneMalformedExternalIdValueName = - "TestOneGoodExternalIdOneMalformedExternalIdValue"; - externalIdCounter = 0; - PortExternalIds oneGood = new PortExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdValueName, - GOOD_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format("FORMAT_STR", - testOneGoodExternalIdOneMalformedExternalIdValueName, - GOOD_VALUE, externalIdCounter)) - .build(); - PortExternalIds oneBad = new PortExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, - testOneGoodExternalIdOneMalformedExternalIdValueName, NO_VALUE_FOR_KEY, ++externalIdCounter)) - .build(); - List oneGoodOneBadInput = (List) Lists.newArrayList( - oneGood, oneBad); - List oneGoodOneBadExpected = null; - testCase = Maps.newHashMap(); - testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput); - testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected); - - // Test Case 4: TestOneGoodExternalIdOneMalformedExternalIdKey - // Test Type: Negative - // Description: - // One perfectly fine PortExternalId - // (TestOneGoodExternalIdOneMalformedExternalIdValue_PortExternalIdKey_1, - // TestOneGoodExternalIdOneMalformedExternalId_PortExternalIdValue_1) - // and one malformed PortExternalId which only has key specified - // (UNSPECIFIED, - // TestOneGoodExternalIdOneMalformedExternalIdKey_NoKeyForValue_2) - // Expected: A port is created without any external_ids - final String testOneGoodExternalIdOneMalformedExternalIdKeyName = - "TestOneGoodExternalIdOneMalformedExternalIdKey"; - externalIdCounter = 0; - oneGood = new PortExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdKeyName, - GOOD_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format("FORMAT_STR", - testOneGoodExternalIdOneMalformedExternalIdKeyName, - GOOD_VALUE, externalIdCounter)) - .build(); - oneBad = new PortExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, - testOneGoodExternalIdOneMalformedExternalIdKeyName, NO_KEY_FOR_VALUE, ++externalIdCounter)) - .build(); - oneGoodOneBadInput = (List) Lists.newArrayList( - oneGood, oneBad); - oneGoodOneBadExpected = null; - testCase = Maps.newHashMap(); - testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput); - testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected); + ovsdbTerminationBuilder.setOfport(OFPORT_EXPECTED); + Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); + Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); + Assert.assertNotNull(terminationPointNode); - return testMap; - } + // READ + List terminationPoints = terminationPointNode.getTerminationPoint(); + for (TerminationPoint terminationPoint : terminationPoints) { + OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = + terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { + Long ofPort = ovsdbTerminationPointAugmentation.getOfport(); + // if ephemeral port 45002 is in use, ofPort is set to 1 + Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(1L)); + LOG.info("ofPort: {}", ofPort); + } + } - /* - * @see SouthboundIT.testCRUDPortExternalIds() - * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set" - */ - private void assertExpectedPortExternalIdsExist( List expected, - List test ) { + // UPDATE- Not Applicable. From the OpenVSwitch Documentation: + // "A client should ideally set this column’s value in the same database transaction that it uses to create + // the interface." - if (expected != null) { - for (PortExternalIds expectedExternalId : expected) { - Assert.assertTrue(test.contains(expectedExternalId)); - } - } else { - Assert.assertNull(test); + // DELETE handled by TestBridge } } - /* - * @see SouthboundIT.testCRUDPortExternalIds() - * This is a helper test method. The method only checks if - * updateFromInputExternalIds != updateToInputExternalIds, (i.e., the updateTo "set" isn't the same - * as the updateFrom "set". Then, the method ensures each element of erase is not an element of test, as the input - * test cases are divergent. - */ - private void assertPortExternalIdsErased( List updateFromInputExternalIds, - List updateToInputExternalIds, - List updateFromExpectedExternalIds, - List updateToTestExternalIds ) { - - if (!updateFromInputExternalIds.containsAll(updateToInputExternalIds)) { - for (PortExternalIds erasedExternalId : updateFromExpectedExternalIds) { - Assert.assertTrue(!updateToTestExternalIds.contains(erasedExternalId)); - } - } - } - - /* - * Tests the CRUD operations for Port external_ids. - * - * @see SouthboundIT.generatePortExternalIdsTestCases() for specific test case information - */ @Test - public void testCRUDTerminationPointPortExternalIds() throws InterruptedException { - final String TEST_PREFIX = "CRUDTPPortExternalIds"; - final int TERMINATION_POINT_TEST_INDEX = 0; - - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - connectOvsdbNode(connectionInfo); - - // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after - // the update has been performed. - Map>> updateFromTestCases = generatePortExternalIdsTestCases(); - Map>> updateToTestCases = generatePortExternalIdsTestCases(); - Map> updateFromTestCase = null; - List updateFromInputExternalIds = null; - List updateFromExpectedExternalIds = null; - List updateFromConfigurationExternalIds = null; - List updateFromOperationalExternalIds = null; - Map> updateToTestCase = null; - List updateToInputExternalIds = null; - List updateToExpectedExternalIds = null; - List updateToConfigurationExternalIds = null; - List updateToOperationalExternalIds = null; - String testBridgeName = null; - String testPortName = null; - OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation = null; - OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmenation = null; - OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation = null; - OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation = null; - OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder = null; - OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder = null; - TerminationPointBuilder tpUpdateBuilder = null; - NodeBuilder portUpdateNodeBuilder = null; - NodeId testBridgeNodeId = null; - NodeId portUpdateNodeId = null; - InstanceIdentifier portIid = null; - boolean result = false; - - for (String updateFromTestCaseKey : updateFromTestCases.keySet()) { - updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey); - updateFromInputExternalIds = updateFromTestCase.get(INPUT_VALUES_KEY); - updateFromExpectedExternalIds = updateFromTestCase.get(EXPECTED_VALUES_KEY); - for (String testCaseKey : updateToTestCases.keySet()) { - testPortName = testBridgeName = String.format("%s_%s", TEST_PREFIX, testCaseKey); - updateToTestCase = updateToTestCases.get(testCaseKey); - updateToInputExternalIds = updateToTestCase.get(INPUT_VALUES_KEY); - updateToExpectedExternalIds = updateToTestCase.get(EXPECTED_VALUES_KEY); + public void testCRDTerminationPointOfPortRequest() throws InterruptedException { + final Long OFPORT_EXPECTED = 45008L; + final Long OFPORT_INPUT = 45008L; - // CREATE: Create the test bridge - Assert.assertTrue(addBridge(connectionInfo, null, - testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), - true, null, null, null)); - testBridgeNodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier( - connectionInfo, new OvsdbBridgeName(testBridgeName))); - tpCreateAugmentationBuilder = createGenericOvsdbTerminationPointAugmentationBuilder(); - tpCreateAugmentationBuilder.setName(testPortName); - tpCreateAugmentationBuilder.setPortExternalIds(updateFromInputExternalIds); - Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder)); - - // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store, - // then repeat for OPERATIONAL data store - updateFromConfigurationTerminationPointAugmentation = - getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName, - LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX); - updateFromConfigurationExternalIds = updateFromConfigurationTerminationPointAugmentation - .getPortExternalIds(); - assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateFromConfigurationExternalIds); - updateFromOperationalTerminationPointAugmenation = - getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName, - LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX); - updateFromOperationalExternalIds = updateFromOperationalTerminationPointAugmenation - .getPortExternalIds(); - assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateFromOperationalExternalIds); - - // UPDATE: update the external_ids - testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId(); - tpUpdateAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder(); - tpUpdateAugmentationBuilder.setPortExternalIds(updateToInputExternalIds); - portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId); - portUpdateNodeBuilder = new NodeBuilder(); - portUpdateNodeId = SouthboundMapper.createManagedNodeId(portIid); - portUpdateNodeBuilder.setNodeId(portUpdateNodeId); - tpUpdateBuilder = new TerminationPointBuilder(); - tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName))); - tpUpdateBuilder.addAugmentation( - OvsdbTerminationPointAugmentation.class, - tpUpdateAugmentationBuilder.build()); - portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build())); - result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, - portIid, portUpdateNodeBuilder.build()); - Thread.sleep(OVSDB_UPDATE_TIMEOUT); - Assert.assertTrue(result); + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); - // READ: the test port and ensure changes are propagated to the CONFIGURATION data store, - // then repeat for OPERATIONAL data store - updateToConfigurationTerminationPointAugmentation = - getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName, - LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX); - updateToConfigurationExternalIds = updateToConfigurationTerminationPointAugmentation - .getPortExternalIds(); - assertExpectedPortExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds); - updateToOperationalTerminationPointAugmentation = - getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName, - LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX); - updateToOperationalExternalIds = updateToOperationalTerminationPointAugmentation.getPortExternalIds(); - assertExpectedPortExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds); - - // Make sure the old port external ids aren't present in the CONFIGURATION data store - assertPortExternalIdsErased(updateFromInputExternalIds, updateToInputExternalIds, - updateFromExpectedExternalIds, updateToConfigurationExternalIds); - assertPortExternalIdsErased(updateFromInputExternalIds, updateToInputExternalIds, - updateFromExpectedExternalIds, updateToConfigurationExternalIds); + // CREATE + try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); + Assert.assertNotNull(bridge); + NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier( + connectionInfo, bridge.getBridgeName())); + OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = + createGenericOvsdbTerminationPointAugmentationBuilder(); + String portName = "testOfPortRequest"; + ovsdbTerminationBuilder.setName(portName); + Integer ofPortRequestExpected = OFPORT_EXPECTED.intValue(); + ovsdbTerminationBuilder.setOfport(OFPORT_INPUT); + ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected); + Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); + Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); + Assert.assertNotNull(terminationPointNode); - // DELETE - Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName)); + // READ + List terminationPoints = terminationPointNode.getTerminationPoint(); + for (TerminationPoint terminationPoint : terminationPoints) { + OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = + terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { + Long ofPort = ovsdbTerminationPointAugmentation.getOfport(); + // if ephemeral port 45008 is in use, ofPort is set to 1 + Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(1L)); + LOG.info("ofPort: {}", ofPort); + + Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest(); + Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected)); + LOG.info("ofPortRequest: {}", ofPortRequest); + } } - } - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); - } - - /* - * Generates the test cases involved in testing InterfaceExternalIds. See inline comments for descriptions of - * the particular cases considered. - * - * The return value is a Map in the form (K,V)=(testCaseName,testCase). - * - testCaseName is a String - * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of - * either corresponding INPUT interface external_ids, or EXPECTED interface external_ids - * INPUT is the List we use when calling - * TerminationPointAugmentationBuilder.setInterfaceExternalIds() - * EXPECTED is the List we expect to receive after calling - * TerminationPointAugmentationBuilder.getInterfaceExternalIds() - */ - private Map>> generateInterfaceExternalIdsTestCases() { - Map>> testMap = - new HashMap>>(); - - final String INTERFACE_EXTERNAL_ID_KEY = "IntExternalIdKey"; - final String INTERFACE_EXTERNAL_ID_VALUE = "IntExternalIdValue"; - final String FORMAT_STR = "%s_%s_%d"; - final String GOOD_KEY = "GoodKey"; - final String GOOD_VALUE = "GoodValue"; - final String NO_VALUE_FOR_KEY = "NoValueForKey"; - final String NO_KEY_FOR_VALUE = "NoKeyForValue"; - // Test Case 1: TestOneExternalId - // Test Type: Positive - // Description: Create a termination point with one InterfaceExternalIds - // Expected: A termination point is created with the single external_ids specified below - final String testOneExternalIdName = "TestOneExternalId"; - int externalIdCounter = 0; - List oneExternalId = (List) Lists.newArrayList( - (new InterfaceExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testOneExternalIdName, - INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format(FORMAT_STR, testOneExternalIdName, - INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter)) - .build())); - Map> testCase = Maps.newHashMap(); - testCase.put(EXPECTED_VALUES_KEY, oneExternalId); - testCase.put(INPUT_VALUES_KEY, oneExternalId); - testMap.put(testOneExternalIdName, testCase); - - // Test Case 2: TestFiveExternalId - // Test Type: Positive - // Description: Create a termination point with multiple (five) InterfaceExternalIds - // Expected: A termination point is created with the five external_ids specified below - final String testFiveExternalIdName = "TestFiveExternalId"; - externalIdCounter = 0; - List fiveExternalId = (List) Lists.newArrayList( - (new InterfaceExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName, - INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName, - INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter)) - .build()), - (new InterfaceExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName, - INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName, - INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter)) - .build()), - (new InterfaceExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName, - INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName, - INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter)) - .build()), - (new InterfaceExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName, - INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName, - INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter)) - .build()), - (new InterfaceExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName, - INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName, - INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter)) - .build())); - testCase = Maps.newHashMap(); - testCase.put(EXPECTED_VALUES_KEY, fiveExternalId); - testCase.put(INPUT_VALUES_KEY, fiveExternalId); - testMap.put(testOneExternalIdName, testCase); - - // Test Case 3: TestOneGoodExternalIdOneMalformedExternalIdValue - // Test Type: Negative - // Description: - // One perfectly fine InterfaceExternalId - // (TestOneGoodExternalIdOneMalformedExternalIdValue_IntExternalIdKey_1, - // TestOneGoodExternalIdOneMalformedExternalId_IntExternalIdValue_1) - // and one malformed PortExternalId which only has key specified - // (TestOneGoodExternalIdOneMalformedExternalIdValue_NoValueForKey_2, - // UNSPECIFIED) - // Expected: A termination point is created without any external_ids - final String testOneGoodExternalIdOneMalformedExternalIdValueName = - "TestOneGoodExternalIdOneMalformedExternalIdValue"; - externalIdCounter = 0; - InterfaceExternalIds oneGood = new InterfaceExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdValueName, - GOOD_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format("FORMAT_STR", - testOneGoodExternalIdOneMalformedExternalIdValueName, - GOOD_VALUE, externalIdCounter)) - .build(); - InterfaceExternalIds oneBad = new InterfaceExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, - testOneGoodExternalIdOneMalformedExternalIdValueName, NO_VALUE_FOR_KEY, ++externalIdCounter)) - .build(); - List oneGoodOneBadInput = (List) Lists.newArrayList( - oneGood, oneBad); - List oneGoodOneBadExpected = null; - testCase = Maps.newHashMap(); - testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput); - testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected); - - // Test Case 4: TestOneGoodExternalIdOneMalformedExternalIdKey - // Test Type: Negative - // Description: - // One perfectly fine InterfaceExternalId - // (TestOneGoodExternalIdOneMalformedExternalIdValue_IntExternalIdKey_1, - // TestOneGoodExternalIdOneMalformedExternalId_IntExternalIdValue_1) - // and one malformed BridgeExternalId which only has key specified - // (UNSPECIFIED, - // TestOneGoodExternalIdOneMalformedExternalIdKey_NoKeyForValue_2) - // Expected: A termination point is created without any external_ids - final String testOneGoodExternalIdOneMalformedExternalIdKeyName = - "TestOneGoodExternalIdOneMalformedExternalIdKey"; - externalIdCounter = 0; - oneGood = new InterfaceExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdKeyName, - GOOD_KEY, ++externalIdCounter)) - .setExternalIdValue(String.format("FORMAT_STR", - testOneGoodExternalIdOneMalformedExternalIdKeyName, - GOOD_VALUE, externalIdCounter)) - .build(); - oneBad = new InterfaceExternalIdsBuilder() - .setExternalIdKey(String.format(FORMAT_STR, - testOneGoodExternalIdOneMalformedExternalIdKeyName, NO_KEY_FOR_VALUE, ++externalIdCounter)) - .build(); - oneGoodOneBadInput = (List) Lists.newArrayList( - oneGood, oneBad); - oneGoodOneBadExpected = null; - testCase = Maps.newHashMap(); - testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput); - testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected); + // UPDATE- Not Applicable. From the OpenVSwitch documentation: + // "A client should ideally set this column’s value in the same database transaction that it uses to + // create the interface. " - return testMap; + // DELETE handled by TestBridge + } } - /* - * @see SouthboundIT.testCRUDInterfaceExternalIds() - * This is helper test method to compare a test "set" of InterfaceExternalIds against an expected "set" - */ - private void assertExpectedInterfaceExternalIdsExist( List expected, - List test ) { - - if (expected != null) { - for (InterfaceExternalIds expectedExternalId : expected) { - Assert.assertTrue(test.contains(expectedExternalId)); + private void assertExpectedExist(List expected, List test) { + if (expected != null && test != null) { + for (T exp : expected) { + Assert.assertTrue("The retrieved values don't contain " + exp, test.contains(exp)); } - } else { - Assert.assertNull(test); } } - /* - * @see SouthboundIT.testCRUDInterfaceExternalIds() - * This is a helper test method. The method only checks if - * updateFromInputExternalIds != updateToInputExternalIds, (i.e., the updateTo "set" isn't the same - * as the updateFrom "set". Then, the method ensures each element of erase is not an element of test, as the input - * test cases are divergent. - */ - private void assertInterfaceExternalIdsErased( List updateFromInputExternalIds, - List updateToInputExternalIds, - List updateFromExpectedExternalIds, - List updateToTestExternalIds ) { - - if (!updateFromInputExternalIds.containsAll(updateToInputExternalIds)) { - for (InterfaceExternalIds erasedExternalId : updateFromExpectedExternalIds) { - Assert.assertTrue(!updateToTestExternalIds.contains(erasedExternalId)); - } - } + private interface SouthboundTerminationPointHelper { + void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List values); + List readValues(OvsdbTerminationPointAugmentation augmentation); } /* - * Tests the CRUD operations for Interface external_ids. + * Tests the CRUD operations for Port external_ids. * - * @see SouthboundIT.generateInterfaceExternalIdsTestCases() for specific test case information + * @see SouthboundIT.generatePortExternalIdsTestCases() for specific test case information */ - @Test - public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException { - final String TEST_PREFIX = "CRUDTPInterfaceExternalIds"; + private void testCRUDTerminationPoint( + KeyValueBuilder builder, String prefix, SouthboundTerminationPointHelper helper) + throws InterruptedException { final int TERMINATION_POINT_TEST_INDEX = 0; - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - connectOvsdbNode(connectionInfo); + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after // the update has been performed. - Map>> updateFromTestCases = - generateInterfaceExternalIdsTestCases(); - Map>> updateToTestCases = - generateInterfaceExternalIdsTestCases(); - Map> updateFromTestCase = null; - List updateFromInputExternalIds = null; - List updateFromExpectedExternalIds = null; - List updateFromConfigurationExternalIds = null; - List updateFromOperationalExternalIds = null; - Map> updateToTestCase = null; - List updateToInputExternalIds = null; - List updateToExpectedExternalIds = null; - List updateToConfigurationExternalIds = null; - List updateToOperationalExternalIds = null; - String testBridgeName = null; - String testPortName = null; - OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation = null; - OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmenation = null; - OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation = null; - OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation = null; - OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder = null; - OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder = null; - TerminationPointBuilder tpUpdateBuilder = null; - NodeBuilder portUpdateNodeBuilder = null; - NodeId testBridgeNodeId = null; - NodeId portUpdateNodeId = null; - InstanceIdentifier portIid = null; - boolean result = false; - - for (String updateFromTestCaseKey : updateFromTestCases.keySet()) { - updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey); - updateFromInputExternalIds = updateFromTestCase.get(INPUT_VALUES_KEY); - updateFromExpectedExternalIds = updateFromTestCase.get(EXPECTED_VALUES_KEY); - for (String testCaseKey : updateToTestCases.keySet()) { - testPortName = testBridgeName = String.format("%s_%s", TEST_PREFIX, testCaseKey); - updateToTestCase = updateToTestCases.get(testCaseKey); - updateToInputExternalIds = updateToTestCase.get(INPUT_VALUES_KEY); - updateToExpectedExternalIds = updateToTestCase.get(EXPECTED_VALUES_KEY); - - // CREATE: Create the test interface - Assert.assertTrue(addBridge(connectionInfo, null, - testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), - true, null, null, null)); - testBridgeNodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier( - connectionInfo, new OvsdbBridgeName(testBridgeName))); - tpCreateAugmentationBuilder = createGenericOvsdbTerminationPointAugmentationBuilder(); - tpCreateAugmentationBuilder.setName(testPortName); - tpCreateAugmentationBuilder.setInterfaceExternalIds(updateFromInputExternalIds); - Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder)); - - // READ: Read the test interface and ensure changes are propagated to the CONFIGURATION data store, - // then repeat for OPERATIONAL data store - updateFromConfigurationTerminationPointAugmentation = - getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName, - LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX); - updateFromConfigurationExternalIds = updateFromConfigurationTerminationPointAugmentation - .getInterfaceExternalIds(); - assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds, - updateFromConfigurationExternalIds); - updateFromOperationalTerminationPointAugmenation = - getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName, - LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX); - updateFromOperationalExternalIds = updateFromOperationalTerminationPointAugmenation - .getInterfaceExternalIds(); - assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds, - updateFromOperationalExternalIds); - - // UPDATE: update the external_ids - testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId(); - tpUpdateAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder(); - tpUpdateAugmentationBuilder.setInterfaceExternalIds(updateToInputExternalIds); - portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId); - portUpdateNodeBuilder = new NodeBuilder(); - portUpdateNodeId = SouthboundMapper.createManagedNodeId(portIid); - portUpdateNodeBuilder.setNodeId(portUpdateNodeId); - tpUpdateBuilder = new TerminationPointBuilder(); - tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName))); - tpUpdateBuilder.addAugmentation( - OvsdbTerminationPointAugmentation.class, - tpUpdateAugmentationBuilder.build()); - portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build())); - result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, - portIid, portUpdateNodeBuilder.build()); - Thread.sleep(OVSDB_UPDATE_TIMEOUT); - Assert.assertTrue(result); + List> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From"); + List> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To"); - // READ: the test interface and ensure changes are propagated to the CONFIGURATION data store, - // then repeat for OPERATIONAL data store - updateToConfigurationTerminationPointAugmentation = - getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName, - LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX); - updateToConfigurationExternalIds = updateToConfigurationTerminationPointAugmentation - .getInterfaceExternalIds(); - assertExpectedInterfaceExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds); - updateToOperationalTerminationPointAugmentation = - getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName, - LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX); - updateToOperationalExternalIds = updateToOperationalTerminationPointAugmentation - .getInterfaceExternalIds(); - assertExpectedInterfaceExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds); - - // Make sure the old interface external ids aren't present in the CONFIGURATION data store - assertInterfaceExternalIdsErased(updateFromInputExternalIds, updateToInputExternalIds, - updateFromExpectedExternalIds, updateToConfigurationExternalIds); - assertInterfaceExternalIdsErased(updateFromInputExternalIds, updateToInputExternalIds, - updateFromExpectedExternalIds, updateToConfigurationExternalIds); + for (SouthboundTestCase updateFromTestCase : updateFromTestCases) { + for (SouthboundTestCase updateToTestCase : updateToTestCases) { + String testBridgeAndPortName = String.format("%s_%s", prefix, updateToTestCase.name); - // DELETE - Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName)); + // CREATE: Create the test bridge + try (TestBridge testBridge = new TestBridge(connectionInfo, null, testBridgeAndPortName, null, true, + SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, + null)) { + NodeId testBridgeNodeId = SouthboundUtils.createManagedNodeId( + SouthboundUtils.createInstanceIdentifier(connectionInfo, + new OvsdbBridgeName(testBridgeAndPortName))); + OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder = + createGenericOvsdbTerminationPointAugmentationBuilder(); + tpCreateAugmentationBuilder.setName(testBridgeAndPortName); + helper.writeValues(tpCreateAugmentationBuilder, updateFromTestCase.inputValues); + Assert.assertTrue( + addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder)); + + // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store, + // then repeat for OPERATIONAL data store + OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation = + getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName, + LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX); + if (updateFromConfigurationTerminationPointAugmentation != null) { + List updateFromConfigurationValues = + helper.readValues(updateFromConfigurationTerminationPointAugmentation); + assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues); + } + OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation = + getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName, + LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX); + if (updateFromOperationalTerminationPointAugmentation != null) { + List updateFromOperationalValues = + helper.readValues(updateFromOperationalTerminationPointAugmentation); + assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues); + } + + // UPDATE: update the values + testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId(); + OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder = + new OvsdbTerminationPointAugmentationBuilder(); + helper.writeValues(tpUpdateAugmentationBuilder, updateToTestCase.inputValues); + InstanceIdentifier portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId); + NodeBuilder portUpdateNodeBuilder = new NodeBuilder(); + NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid); + portUpdateNodeBuilder.setNodeId(portUpdateNodeId); + TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder(); + tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName))); + tpUpdateBuilder.addAugmentation( + OvsdbTerminationPointAugmentation.class, + tpUpdateAugmentationBuilder.build()); + portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build())); + Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + portIid, portUpdateNodeBuilder.build())); + Thread.sleep(OVSDB_UPDATE_TIMEOUT); + + // READ: the test port and ensure changes are propagated to the CONFIGURATION data store, + // then repeat for OPERATIONAL data store + OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation = + getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName, + LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX); + if (updateToConfigurationTerminationPointAugmentation != null) { + List updateToConfigurationValues = + helper.readValues(updateToConfigurationTerminationPointAugmentation); + assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues); + assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationValues); + } + OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation = + getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName, + LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX); + if (updateToOperationalTerminationPointAugmentation != null) { + List updateToOperationalValues = + helper.readValues(updateToOperationalTerminationPointAugmentation); + if (updateFromTestCase.expectedValues != null) { + assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues); + assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalValues); + } + } + + // DELETE handled by TestBridge + } } } - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); } /* - * Generates the test cases involved in testing TP Options. See inline comments for descriptions of - * the particular cases considered. + * Tests the CRUD operations for Port external_ids. * - * The return value is a Map in the form (K,V)=(testCaseName,testCase). - * - testCaseName is a String - * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of - * either corresponding INPUT TP Options, or EXPECTED TP Options - * INPUT is the List we use when calling - * TerminationPointAugmentationBuilder.setOptions() - * EXPECTED is the List we expect to receive after calling - * TerminationPointAugmentationBuilder.getOptions() + * @see SouthboundIT.generatePortExternalIdsTestCases() for specific test case information */ - private Map>> generateTerminationPointOptionsTestCases() { - Map>> testMap = - new HashMap>>(); - - final String TP_OPTIONS_KEY = "TPOptionsKey"; - final String TP_OPTIONS_VALUE = "TPOptionsValue"; - final String FORMAT_STR = "%s_%s_%d"; - final String GOOD_KEY = "GoodKey"; - final String GOOD_VALUE = "GoodValue"; - final String NO_VALUE_FOR_KEY = "NoValueForKey"; - final String NO_KEY_FOR_VALUE = "NoKeyForValue"; - - // Test Case 1: TestOneOptions - // Test Type: Positive - // Description: Create a termination point with one Options - // Expected: A termination point is created with the single Options specified below - final String testOneOptionsName = "TestOneOptions"; - int optionsCounter = 0; - List oneOptions = (List) Lists.newArrayList( - (new OptionsBuilder() - .setOption(String.format(FORMAT_STR, testOneOptionsName, - TP_OPTIONS_KEY, ++optionsCounter)) - .setValue(String.format(FORMAT_STR, testOneOptionsName, - TP_OPTIONS_VALUE, optionsCounter)) - .build())); - Map> testCase = Maps.newHashMap(); - testCase.put(EXPECTED_VALUES_KEY, oneOptions); - testCase.put(INPUT_VALUES_KEY, oneOptions); - testMap.put(testOneOptionsName, testCase); - - // Test Case 2: TestFiveOptions - // Test Type: Positive - // Description: Create a termination point with multiple (five) Options - // Expected: A termination point is created with the five options specified below - final String testFiveOptions = "TestFiveOptions"; - optionsCounter = 0; - List fiveOptions = (List) Lists.newArrayList( - (new OptionsBuilder() - .setOption(String.format(FORMAT_STR, testFiveOptions, - TP_OPTIONS_KEY, ++optionsCounter)) - .setValue(String.format(FORMAT_STR, testFiveOptions, - TP_OPTIONS_VALUE, optionsCounter)) - .build()), - (new OptionsBuilder() - .setOption(String.format(FORMAT_STR, testFiveOptions, - TP_OPTIONS_KEY, ++optionsCounter)) - .setValue(String.format(FORMAT_STR, testFiveOptions, - TP_OPTIONS_VALUE, optionsCounter)) - .build()), - (new OptionsBuilder() - .setOption(String.format(FORMAT_STR, testFiveOptions, - TP_OPTIONS_KEY, ++optionsCounter)) - .setValue(String.format(FORMAT_STR, testFiveOptions, - TP_OPTIONS_VALUE, optionsCounter)) - .build()), - (new OptionsBuilder() - .setOption(String.format(FORMAT_STR, testFiveOptions, - TP_OPTIONS_KEY, ++optionsCounter)) - .setValue(String.format(FORMAT_STR, testFiveOptions, - TP_OPTIONS_VALUE, optionsCounter)) - .build()), - (new OptionsBuilder() - .setOption(String.format(FORMAT_STR, testFiveOptions, - TP_OPTIONS_KEY, ++optionsCounter)) - .setValue(String.format(FORMAT_STR, testFiveOptions, - TP_OPTIONS_VALUE, optionsCounter)) - .build())); - testCase = Maps.newHashMap(); - testCase.put(EXPECTED_VALUES_KEY, fiveOptions); - testCase.put(INPUT_VALUES_KEY, fiveOptions); - testMap.put(testOneOptionsName, testCase); - - // Test Case 3: TestOneGoodOptionsOneMalformedOptionsValue - // Test Type: Negative - // Description: - // One perfectly fine Options - // (TestOneGoodOptionsOneMalformedOptionsValue_OptionsKey_1, - // TestOneGoodOptionsOneMalformedOptions_OptionsValue_1) - // and one malformed Options which only has key specified - // (TestOneGoodOptionsOneMalformedOptionsValue_NoValueForKey_2, - // UNSPECIFIED) - // Expected: A termination point is created without any options - final String testOneGoodOptionsOneMalformedOptionsValueName = - "TestOneGoodOptionsOneMalformedOptionsValue"; - optionsCounter = 0; - Options oneGood = new OptionsBuilder() - .setOption(String.format(FORMAT_STR, testOneGoodOptionsOneMalformedOptionsValueName, - GOOD_KEY, ++optionsCounter)) - .setValue(String.format("FORMAT_STR", - testOneGoodOptionsOneMalformedOptionsValueName, - GOOD_VALUE, optionsCounter)) - .build(); - Options oneBad = new OptionsBuilder() - .setOption(String.format(FORMAT_STR, - testOneGoodOptionsOneMalformedOptionsValueName, NO_VALUE_FOR_KEY, ++optionsCounter)) - .build(); - List oneGoodOneBadInput = (List) Lists.newArrayList( - oneGood, oneBad); - List oneGoodOneBadExpected = null; - testCase = Maps.newHashMap(); - testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput); - testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected); - - // Test Case 4: TestOneGoodOptionsOneMalformedOptionsKey - // Test Type: Negative - // Description: - // One perfectly fine Options - // (TestOneGoodOptionsOneMalformedOptionsValue_OptionsKey_1, - // TestOneGoodOptionsOneMalformedOptions_OptionsValue_1) - // and one malformed Options which only has key specified - // (UNSPECIFIED, - // TestOneGoodOptionsOneMalformedOptionsKey_NoKeyForValue_2) - // Expected: A termination point is created without any options - final String testOneGoodOptionsOneMalformedOptionsKeyName = - "TestOneGoodOptionsOneMalformedOptionsKey"; - optionsCounter = 0; - oneGood = new OptionsBuilder() - .setOption(String.format(FORMAT_STR, testOneGoodOptionsOneMalformedOptionsKeyName, - GOOD_KEY, ++optionsCounter)) - .setValue(String.format("FORMAT_STR", - testOneGoodOptionsOneMalformedOptionsKeyName, - GOOD_VALUE, optionsCounter)) - .build(); - oneBad = new OptionsBuilder() - .setOption(String.format(FORMAT_STR, - testOneGoodOptionsOneMalformedOptionsKeyName, NO_KEY_FOR_VALUE, ++optionsCounter)) - .build(); - oneGoodOneBadInput = (List) Lists.newArrayList( - oneGood, oneBad); - oneGoodOneBadExpected = null; - testCase = Maps.newHashMap(); - testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput); - testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected); - - return testMap; + @Test + public void testCRUDTerminationPointPortExternalIds() throws InterruptedException { + testCRUDTerminationPoint(new SouthboundPortExternalIdsBuilder(), "TPPortExternalIds", + new PortExternalIdsSouthboundHelper()); } /* - * @see SouthboundIT.testCRUDTerminationPointOptions() - * This is helper test method to compare a test "set" of Options against an expected "set" + * Tests the CRUD operations for Interface external_ids. + * + * @see SouthboundIT.generateInterfaceExternalIdsTestCases() for specific test case information */ - private void assertExpectedOptionsExist( List expected, - List test ) { - - if (expected != null) { - for (Options expectedOption : expected) { - Assert.assertTrue(test.contains(expectedOption)); - } - } else { - Assert.assertNull(test); - } + @Test + public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException { + testCRUDTerminationPoint(new SouthboundInterfaceExternalIdsBuilder(), "TPInterfaceExternalIds", + new InterfaceExternalIdsSouthboundHelper()); } /* - * @see SouthboundIT.testCRUDTPOptions() - * This is a helper test method. The method only checks if - * updateFromInputOptions != updateToInputOptions, (i.e., the updateTo "set" isn't the same - * as the updateFrom "set". Then, the method ensures each element of erase is not an element of test, as the input - * test cases are divergent. + * Tests the CRUD operations for Interface lldp. + * + * @see SouthboundIT.generateInterfaceLldpTestCases() for specific test case information */ - private void assertOptionsErased( List updateFromInputOptions, - List updateToInputOptions, - List updateFromExpectedOptions, - List updateToTestOptions ) { - - if (!updateFromInputOptions.containsAll(updateToInputOptions)) { - for (Options erasedOption : updateFromExpectedOptions) { - Assert.assertTrue(!updateToTestOptions.contains(erasedOption)); - } - } + @Test + public void testCRUDTerminationPointInterfaceLldp() throws InterruptedException { + testCRUDTerminationPoint(new SouthboundInterfaceLldpBuilder(), "TPInterfaceLldp", + new InterfaceLldpSouthboundHelper()); } /* @@ -1578,323 +1556,265 @@ public class SouthboundIT extends AbstractMdsalTestBase { */ @Test public void testCRUDTerminationPointOptions() throws InterruptedException { - final String TEST_PREFIX = "CRUDTPOptions"; - final int TERMINATION_POINT_TEST_INDEX = 0; - - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - connectOvsdbNode(connectionInfo); - - // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after - // the update has been performed. - Map>> updateFromTestCases = - generateTerminationPointOptionsTestCases(); - Map>> updateToTestCases = - generateTerminationPointOptionsTestCases(); - Map> updateFromTestCase = null; - List updateFromInputOptions = null; - List updateFromExpectedOptions = null; - List updateFromConfigurationOptions = null; - List updateFromOperationalOptions = null; - Map> updateToTestCase = null; - List updateToInputOptions = null; - List updateToExpectedOptions = null; - List updateToConfigurationOptions = null; - List updateToOperationalOptions = null; - String testBridgeName = null; - String testPortName = null; - OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation = null; - OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmenation = null; - OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation = null; - OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation = null; - OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder = null; - OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder = null; - TerminationPointBuilder tpUpdateBuilder = null; - NodeBuilder portUpdateNodeBuilder = null; - NodeId testBridgeNodeId = null; - NodeId portUpdateNodeId = null; - InstanceIdentifier portIid = null; - boolean result = false; - - for (String updateFromTestCaseKey : updateFromTestCases.keySet()) { - updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey); - updateFromInputOptions = updateFromTestCase.get(INPUT_VALUES_KEY); - updateFromExpectedOptions = updateFromTestCase.get(EXPECTED_VALUES_KEY); - for (String testCaseKey : updateToTestCases.keySet()) { - testPortName = testBridgeName = String.format("%s_%s", TEST_PREFIX, testCaseKey); - updateToTestCase = updateToTestCases.get(testCaseKey); - updateToInputOptions = updateToTestCase.get(INPUT_VALUES_KEY); - updateToExpectedOptions = updateToTestCase.get(EXPECTED_VALUES_KEY); - - // CREATE: Create the test interface - Assert.assertTrue(addBridge(connectionInfo, null, - testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), - true, null, null, null)); - testBridgeNodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier( - connectionInfo, new OvsdbBridgeName(testBridgeName))); - tpCreateAugmentationBuilder = createGenericOvsdbTerminationPointAugmentationBuilder(); - tpCreateAugmentationBuilder.setName(testPortName); - tpCreateAugmentationBuilder.setOptions(updateFromInputOptions); - Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder)); - - // READ: Read the test interface and ensure changes are propagated to the CONFIGURATION data store, - // then repeat for OPERATIONAL data store - updateFromConfigurationTerminationPointAugmentation = - getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName, - LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX); - updateFromConfigurationOptions = updateFromConfigurationTerminationPointAugmentation - .getOptions(); - assertExpectedOptionsExist(updateFromExpectedOptions, - updateFromConfigurationOptions); - updateFromOperationalTerminationPointAugmenation = - getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName, - LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX); - updateFromOperationalOptions = updateFromOperationalTerminationPointAugmenation - .getOptions(); - assertExpectedOptionsExist(updateFromExpectedOptions, - updateFromOperationalOptions); - - // UPDATE: update the external_ids - testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId(); - tpUpdateAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder(); - tpUpdateAugmentationBuilder.setOptions(updateToInputOptions); - portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId); - portUpdateNodeBuilder = new NodeBuilder(); - portUpdateNodeId = SouthboundMapper.createManagedNodeId(portIid); - portUpdateNodeBuilder.setNodeId(portUpdateNodeId); - tpUpdateBuilder = new TerminationPointBuilder(); - tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName))); - tpUpdateBuilder.addAugmentation( - OvsdbTerminationPointAugmentation.class, - tpUpdateAugmentationBuilder.build()); - portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build())); - result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, - portIid, portUpdateNodeBuilder.build()); - Thread.sleep(OVSDB_UPDATE_TIMEOUT); - Assert.assertTrue(result); - - // READ: the test interface and ensure changes are propagated to the CONFIGURATION data store, - // then repeat for OPERATIONAL data store - updateToConfigurationTerminationPointAugmentation = - getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName, - LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX); - updateToConfigurationOptions = updateToConfigurationTerminationPointAugmentation - .getOptions(); - assertExpectedOptionsExist(updateToExpectedOptions, updateToConfigurationOptions); - updateToOperationalTerminationPointAugmentation = - getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName, - LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX); - updateToOperationalOptions = updateToOperationalTerminationPointAugmentation - .getOptions(); - assertExpectedOptionsExist(updateToExpectedOptions, updateToOperationalOptions); - - // Make sure the old interface external ids aren't present in the CONFIGURATION data store - assertOptionsErased(updateFromInputOptions, updateToInputOptions, - updateFromExpectedOptions, updateToConfigurationOptions); - assertOptionsErased(updateFromInputOptions, updateToInputOptions, - updateFromExpectedOptions, updateToConfigurationOptions); - - // DELETE - Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName)); - } - } - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); + testCRUDTerminationPoint(new SouthboundOptionsBuilder(), "TPOptions", new OptionsSouthboundHelper()); } + /* + * Tests the CRUD operations for Interface other_configs. + * + * @see SouthboundIT.generateInterfaceExternalIdsTestCases() for specific test case information + */ @Test - public void testTerminationPointInterfaceOtherConfigs() throws InterruptedException { - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - connectOvsdbNode(connectionInfo); - Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)); - OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); - Assert.assertNotNull(bridge); - NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier( - connectionInfo, bridge.getBridgeName())); - OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = - createGenericOvsdbTerminationPointAugmentationBuilder(); - String portName = "testInterfaceOtherConfigs"; - ovsdbTerminationBuilder.setName(portName); - //setup - InterfaceOtherConfigsBuilder interfaceBuilder1 = new InterfaceOtherConfigsBuilder(); - interfaceBuilder1.setOtherConfigKey("interfaceOtherConfigsKey1"); - interfaceBuilder1.setOtherConfigValue("interfaceOtherConfigsValue1"); - InterfaceOtherConfigsBuilder interfaceBuilder2 = new InterfaceOtherConfigsBuilder(); - interfaceBuilder2.setOtherConfigKey("interfaceOtherConfigsKey2"); - interfaceBuilder2.setOtherConfigValue("interfaceOtherConfigsValue2"); - List interfaceOtherConfigs = Lists.newArrayList(interfaceBuilder1.build(), - interfaceBuilder2.build()); - ovsdbTerminationBuilder.setInterfaceOtherConfigs(interfaceOtherConfigs); - - Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); - Thread.sleep(1000); - InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); - Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); - Assert.assertNotNull(terminationPointNode); - - List terminationPoints = terminationPointNode.getTerminationPoint(); - for (TerminationPoint terminationPoint : terminationPoints) { - OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = - terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); - if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { - List actualInterfaceOtherConfigs = ovsdbTerminationPointAugmentation. - getInterfaceOtherConfigs(); - Assert.assertNotNull(actualInterfaceOtherConfigs); - Assert.assertNotNull(interfaceOtherConfigs); - Assert.assertTrue(interfaceOtherConfigs.size() == actualInterfaceOtherConfigs.size()); - for (InterfaceOtherConfigs interfaceOtherConfig : interfaceOtherConfigs) { - Assert.assertTrue(actualInterfaceOtherConfigs.contains(interfaceOtherConfig)); - } - } - } - Assert.assertTrue(deleteBridge(connectionInfo)); - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); + public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException { + testCRUDTerminationPoint(new SouthboundInterfaceOtherConfigsBuilder(), "TPInterfaceOtherConfigs", + new InterfaceOtherConfigsSouthboundHelper()); } + /* + * Tests the CRUD operations for Port other_configs. + * + * @see SouthboundIT.generatePortExternalIdsTestCases() for specific test case information + */ @Test - public void testTerminationPointPortOtherConfigs() throws InterruptedException { - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - connectOvsdbNode(connectionInfo); - Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)); - OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); - Assert.assertNotNull(bridge); - NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier( - connectionInfo, bridge.getBridgeName())); - OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = - createGenericOvsdbTerminationPointAugmentationBuilder(); - String portName = "testPortOtherConfigs"; - ovsdbTerminationBuilder.setName(portName); - //setup - PortOtherConfigsBuilder portBuilder1 = new PortOtherConfigsBuilder(); - portBuilder1.setOtherConfigKey("portOtherConfigsKey1"); - portBuilder1.setOtherConfigValue("portOtherConfigsValue1"); - PortOtherConfigsBuilder portBuilder2 = new PortOtherConfigsBuilder(); - portBuilder2.setOtherConfigKey("portOtherConfigsKey2"); - portBuilder2.setOtherConfigValue("portOtherConfigsValue2"); - List portOtherConfigs = Lists.newArrayList(portBuilder1.build(), - portBuilder2.build()); - ovsdbTerminationBuilder.setPortOtherConfigs(portOtherConfigs); - - Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); - InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); - Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); - Assert.assertNotNull(terminationPointNode); - - List terminationPoints = terminationPointNode.getTerminationPoint(); - for (TerminationPoint terminationPoint : terminationPoints) { - OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = - terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); - if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { - List actualPortOtherConfigs = ovsdbTerminationPointAugmentation. - getPortOtherConfigs(); - Assert.assertTrue((portOtherConfigs.size() == actualPortOtherConfigs.size())); - for (PortOtherConfigs portOtherConfig : portOtherConfigs) { - Assert.assertTrue(actualPortOtherConfigs.contains(portOtherConfig)); - } - } - } - Assert.assertTrue(deleteBridge(connectionInfo)); - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); + public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException { + testCRUDTerminationPoint(new SouthboundPortOtherConfigsBuilder(), "TPPortOtherConfigs", + new PortOtherConfigsSouthboundHelper()); } @Test - public void testTerminationPointVlan() throws InterruptedException { - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - connectOvsdbNode(connectionInfo); - Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)); - OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); - Assert.assertNotNull(bridge); - NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier( - connectionInfo, bridge.getBridgeName())); - OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = - createGenericOvsdbTerminationPointAugmentationBuilder(); - String portName = "testTerminationPointVlanId"; - ovsdbTerminationBuilder.setName(portName); - //setup - Integer vlanId = new Integer(4000); - ovsdbTerminationBuilder.setVlanTag(new VlanId(vlanId)); + public void testCRUDTerminationPoints() throws InterruptedException { + String port1 = "vx1"; + String port2 = "vxlanport"; + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); - Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); - InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); - Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); - Assert.assertNotNull(terminationPointNode); + try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME); + Assert.assertNotNull(bridge); + NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier( + connectionInfo, bridge.getBridgeName())); + OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = + createGenericOvsdbTerminationPointAugmentationBuilder(); - List terminationPoints = terminationPointNode.getTerminationPoint(); - for (TerminationPoint terminationPoint : terminationPoints) { - OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = - terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); - if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { - //test - VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag(); - Assert.assertNotNull(actualVlanId); - Integer actualVlanIdInt = actualVlanId.getValue(); - Assert.assertTrue(actualVlanIdInt.equals(vlanId)); - } + // add and delete a single port + String portName = port1; + ovsdbTerminationBuilder.setName(portName); + Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); + Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); + Assert.assertNotNull(terminationPointNode); + + SouthboundUtils.createInstanceIdentifier(connectionInfo, + new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME)); + portName = port1; + InstanceIdentifier nodePath = + SouthboundUtils.createInstanceIdentifier(connectionInfo, + new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME)) + .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName))); + + Assert.assertTrue("failed to delete port " + portName, + mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath)); + LOG.info("shague: waiting for delete {}", portName); + Thread.sleep(1000); + TerminationPoint terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath); + Assert.assertNull(terminationPoint); + + // add two ports, then delete them + portName = port1; + ovsdbTerminationBuilder.setName(portName); + Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + terminationPointIid = getTpIid(connectionInfo, bridge); + terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); + Assert.assertNotNull(terminationPointNode); + + portName = port2; + ovsdbTerminationBuilder.setName(portName); + Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + terminationPointIid = getTpIid(connectionInfo, bridge); + terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); + Assert.assertNotNull(terminationPointNode); + + SouthboundUtils.createInstanceIdentifier(connectionInfo, + new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME)); + portName = port1; + nodePath = + SouthboundUtils.createInstanceIdentifier(connectionInfo, + new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME)) + .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName))); + + Assert.assertTrue("failed to delete port " + portName, + mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath)); + LOG.info("shague: waiting for delete {}", portName); + Thread.sleep(1000); + terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath); + Assert.assertNull(terminationPoint); + + portName = port2; + nodePath = SouthboundUtils.createInstanceIdentifier(connectionInfo, + new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME)) + .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName))); + + Assert.assertTrue("failed to delete port " + portName, + mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath)); + LOG.info("shague: waiting for delete {}", portName); + Thread.sleep(1000); + terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath); + Assert.assertNull(terminationPoint); + + // DELETE handled by TestBridge } - Assert.assertTrue(deleteBridge(connectionInfo)); - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); } @Test - public void testTerminationPointVlanModes() throws InterruptedException { - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - connectOvsdbNode(connectionInfo); - VlanMode []vlanModes = VlanMode.values(); - for (VlanMode vlanMode : vlanModes) { + public void testCRUDTerminationPointVlan() throws InterruptedException { + final Integer CREATED_VLAN_ID = 4000; + final Integer UPDATED_VLAN_ID = 4001; - Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)); - OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + + // CREATE + try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME); Assert.assertNotNull(bridge); - NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier( + NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier( connectionInfo, bridge.getBridgeName())); OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = createGenericOvsdbTerminationPointAugmentationBuilder(); - String portName = "testTerminationPointVlanMode" + vlanMode.toString(); + String portName = "testTerminationPointVlanId"; ovsdbTerminationBuilder.setName(portName); - //setup - ovsdbTerminationBuilder.setVlanMode(vlanMode); + ovsdbTerminationBuilder.setVlanTag(new VlanId(CREATED_VLAN_ID)); Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); Assert.assertNotNull(terminationPointNode); + // READ List terminationPoints = terminationPointNode.getTerminationPoint(); + OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation; for (TerminationPoint terminationPoint : terminationPoints) { - OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = - terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation( + OvsdbTerminationPointAugmentation.class); + if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { + VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag(); + Assert.assertNotNull(actualVlanId); + Integer actualVlanIdInt = actualVlanId.getValue(); + Assert.assertEquals(CREATED_VLAN_ID, actualVlanIdInt); + } + } + + // UPDATE + NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId(); + OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder = + new OvsdbTerminationPointAugmentationBuilder(); + tpUpdateAugmentationBuilder.setVlanTag(new VlanId(UPDATED_VLAN_ID)); + InstanceIdentifier portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId); + NodeBuilder portUpdateNodeBuilder = new NodeBuilder(); + NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid); + portUpdateNodeBuilder.setNodeId(portUpdateNodeId); + TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder(); + tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName))); + tpUpdateBuilder.addAugmentation( + OvsdbTerminationPointAugmentation.class, + tpUpdateAugmentationBuilder.build()); + tpUpdateBuilder.setTpId(new TpId(portName)); + portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build())); + Assert.assertTrue( + mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build())); + Thread.sleep(OVSDB_UPDATE_TIMEOUT); + + terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); + terminationPoints = terminationPointNode.getTerminationPoint(); + for (TerminationPoint terminationPoint : terminationPoints) { + ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation( + OvsdbTerminationPointAugmentation.class); if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { - //test - Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode)); + VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag(); + Assert.assertNotNull(actualVlanId); + Integer actualVlanIdInt = actualVlanId.getValue(); + Assert.assertEquals(UPDATED_VLAN_ID, actualVlanIdInt); } } - Assert.assertTrue(deleteBridge(connectionInfo)); + + // DELETE handled by TestBridge } - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); } - private ArrayList> generateVlanSets() { - ArrayList> vlanSets = new ArrayList>(); + @Test + public void testCRUDTerminationPointVlanModes() throws InterruptedException { + final VlanMode UPDATED_VLAN_MODE = VlanMode.Access; + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + VlanMode []vlanModes = VlanMode.values(); + for (VlanMode vlanMode : vlanModes) { + // CREATE + try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); + Assert.assertNotNull(bridge); + NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier( + connectionInfo, bridge.getBridgeName())); + OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = + createGenericOvsdbTerminationPointAugmentationBuilder(); + String portName = "testTerminationPointVlanMode" + vlanMode.toString(); + ovsdbTerminationBuilder.setName(portName); + ovsdbTerminationBuilder.setVlanMode(vlanMode); + Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); + Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); + Assert.assertNotNull(terminationPointNode); + + // READ + List terminationPoints = terminationPointNode.getTerminationPoint(); + for (TerminationPoint terminationPoint : terminationPoints) { + OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = + terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { + //test + Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode)); + } + } - Set emptySet = new HashSet(); - vlanSets.add(emptySet); + // UPDATE + NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId(); + OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder = + new OvsdbTerminationPointAugmentationBuilder(); + tpUpdateAugmentationBuilder.setVlanMode(UPDATED_VLAN_MODE); + InstanceIdentifier portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId); + NodeBuilder portUpdateNodeBuilder = new NodeBuilder(); + NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid); + portUpdateNodeBuilder.setNodeId(portUpdateNodeId); + TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder(); + tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName))); + tpUpdateBuilder.addAugmentation( + OvsdbTerminationPointAugmentation.class, + tpUpdateAugmentationBuilder.build()); + tpUpdateBuilder.setTpId(new TpId(portName)); + portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build())); + Assert.assertTrue( + mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build())); + Thread.sleep(OVSDB_UPDATE_TIMEOUT); - Set singleSet = new HashSet(); - Integer single = new Integer(2222); - singleSet.add(single); - vlanSets.add(singleSet); + terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); + terminationPoints = terminationPointNode.getTerminationPoint(); + for (TerminationPoint terminationPoint : terminationPoints) { + OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = + terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { + //test + Assert.assertEquals(UPDATED_VLAN_MODE, ovsdbTerminationPointAugmentation.getVlanMode()); + } + } - Set minMaxMiddleSet = new HashSet(); - Integer min = new Integer(0); - minMaxMiddleSet.add(min); - Integer max = new Integer(4095); - minMaxMiddleSet.add(max); - Integer minPlusOne = new Integer(min + 1); - minMaxMiddleSet.add(minPlusOne); - Integer maxMinusOne = new Integer(max - 1); - minMaxMiddleSet.add(maxMinusOne); - Integer middle = new Integer((max - min) / 2); - minMaxMiddleSet.add(middle); - vlanSets.add(minMaxMiddleSet); + // DELETE handled by TestBridge + } + } + } - return vlanSets; + @SuppressWarnings("unchecked") + private List> generateVlanSets() { + int min = 0; + int max = 4095; + return Lists.newArrayList( + Collections.emptySet(), + Sets.newHashSet(2222), + Sets.newHashSet(min, max, min + 1, max - 1, (max - min) / 2)); } private List buildTrunkList(Set trunkSet) { @@ -1908,516 +1828,1291 @@ public class SouthboundIT extends AbstractMdsalTestBase { } @Test - public void testTerminationPointVlanTrunks() throws InterruptedException { - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - connectOvsdbNode(connectionInfo); - ArrayList> vlanSets = generateVlanSets(); + public void testCRUDTerminationPointVlanTrunks() throws InterruptedException { + final List UPDATED_TRUNKS = buildTrunkList(Sets.newHashSet(2011)); + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + Iterable> vlanSets = generateVlanSets(); int testCase = 0; for (Set vlanSet : vlanSets) { ++testCase; - Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)); - OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); - Assert.assertNotNull(bridge); - NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier( - connectionInfo, bridge.getBridgeName())); - OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = - createGenericOvsdbTerminationPointAugmentationBuilder(); - String portName = "testTerminationPointVlanTrunks" + testCase; - ovsdbTerminationBuilder.setName(portName); - //setup - List trunks = buildTrunkList(vlanSet); - ovsdbTerminationBuilder.setTrunks(trunks); - Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); - InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); - Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); - Assert.assertNotNull(terminationPointNode); + // CREATE + try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) { + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); + Assert.assertNotNull(bridge); + NodeId nodeId = SouthboundUtils.createManagedNodeId(connectionInfo, bridge.getBridgeName()); + OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = + createGenericOvsdbTerminationPointAugmentationBuilder(); + String portName = "testTerminationPointVlanTrunks" + testCase; + ovsdbTerminationBuilder.setName(portName); + List trunks = buildTrunkList(vlanSet); + ovsdbTerminationBuilder.setTrunks(trunks); + Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + InstanceIdentifier terminationPointIid = getTpIid(connectionInfo, bridge); + Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); + Assert.assertNotNull(terminationPointNode); + + // READ + List terminationPoints = terminationPointNode.getTerminationPoint(); + for (TerminationPoint terminationPoint : terminationPoints) { + OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = + terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { + List actualTrunks = ovsdbTerminationPointAugmentation.getTrunks(); + for (Trunks trunk : trunks) { + Assert.assertTrue(actualTrunks.contains(trunk)); + } + } + } - List terminationPoints = terminationPointNode.getTerminationPoint(); - for (TerminationPoint terminationPoint : terminationPoints) { - OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = - terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); - if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { - List actualTrunks = ovsdbTerminationPointAugmentation.getTrunks(); - for (Trunks trunk : trunks) { - Assert.assertTrue(actualTrunks.contains(trunk)); + + // UPDATE + NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId(); + OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder = + new OvsdbTerminationPointAugmentationBuilder(); + tpUpdateAugmentationBuilder.setTrunks(UPDATED_TRUNKS); + InstanceIdentifier portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId); + NodeBuilder portUpdateNodeBuilder = new NodeBuilder(); + NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid); + portUpdateNodeBuilder.setNodeId(portUpdateNodeId); + TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder(); + tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName))); + tpUpdateBuilder.addAugmentation( + OvsdbTerminationPointAugmentation.class, + tpUpdateAugmentationBuilder.build()); + tpUpdateBuilder.setTpId(new TpId(portName)); + portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build())); + Assert.assertTrue( + mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build())); + Thread.sleep(OVSDB_UPDATE_TIMEOUT); + + terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid); + terminationPoints = terminationPointNode.getTerminationPoint(); + for (TerminationPoint terminationPoint : terminationPoints) { + OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = + terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + if (ovsdbTerminationPointAugmentation.getName().equals(portName)) { + //test + Assert.assertEquals(UPDATED_TRUNKS, ovsdbTerminationPointAugmentation.getTrunks()); } } + + // DELETE handled by TestBridge } - Assert.assertTrue(deleteBridge(connectionInfo)); } - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); } + /* + * Tests setting and deleting qos field in a port. + */ @Test - public void testGetOvsdbNodes() throws InterruptedException { - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - connectOvsdbNode(connectionInfo); - InstanceIdentifier topologyPath = InstanceIdentifier - .create(NetworkTopology.class) - .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID)); + public void testCRUDTerminationPointQos() throws InterruptedException { + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + String testQosId = new String("testQosEntry"); + + // CREATE + try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME); + TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId), + SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HFSC), null, null)) { + OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + QosEntries operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation); + Assert.assertNotNull(operQos); + Uuid qosUuid = new Uuid(operQos.getQosUuid().getValue()); - Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath); - Assert.assertEquals("There should only be one node in the topology", 1, topology.getNode().size()); - InstanceIdentifier expectedNodeIid = SouthboundMapper.createInstanceIdentifier(connectionInfo); - Node node = topology.getNode().iterator().next(); + OvsdbBridgeAugmentation bridge = getBridge(connectionInfo); + Assert.assertNotNull(bridge); + NodeId nodeId = SouthboundUtils.createManagedNodeId(connectionInfo, bridge.getBridgeName()); + OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder = + createGenericOvsdbTerminationPointAugmentationBuilder(); + String portName = "testTerminationPointQos"; + ovsdbTerminationBuilder.setName(portName); + ovsdbTerminationBuilder.setQos(qosUuid); + Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder)); + + // READ and check that qos uuid has been added to the port + InstanceIdentifier tpEntryIid = getTpIid(connectionInfo, bridge) + .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName))); + TerminationPoint terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpEntryIid); + Assert.assertNotNull(terminationPoint); + OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = + terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + Assert.assertEquals(ovsdbTerminationPointAugmentation.getQos(), qosUuid); + + // UPDATE - remove the qos entry from the port + OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder = + new OvsdbTerminationPointAugmentationBuilder(); + tpUpdateAugmentationBuilder.setName(portName); + TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder(); + tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName))); + tpUpdateBuilder.addAugmentation( + OvsdbTerminationPointAugmentation.class, + tpUpdateAugmentationBuilder.build()); + tpUpdateBuilder.setTpId(new TpId(portName)); + + Assert.assertTrue( + mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpEntryIid, tpUpdateBuilder.build())); + Thread.sleep(OVSDB_UPDATE_TIMEOUT); + + // READ and verify that qos uuid has been removed from port + TerminationPoint terminationPointUpdate = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpEntryIid); + Assert.assertNotNull(terminationPointUpdate); + OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentationUpdate = + terminationPointUpdate.getAugmentation(OvsdbTerminationPointAugmentation.class); + Assert.assertNull(ovsdbTerminationPointAugmentationUpdate.getQos()); + + // DELETE handled by TestBridge + } + } + + @Test + public void testGetOvsdbNodes() throws InterruptedException { + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + InstanceIdentifier topologyPath = InstanceIdentifier + .create(NetworkTopology.class) + .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID)); + + Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath); + InstanceIdentifier expectedNodeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo); NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class, NodeKey.class).getNodeId(); - Assert.assertEquals(expectedNodeId, node.getNodeId()); - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); + Node foundNode = null; + Assert.assertNotNull("Expected to find topology: " + topologyPath, topology); + Assert.assertNotNull("Expected to find some nodes" + topology.getNode()); + LOG.info("expectedNodeId: {}, getNode: {}", expectedNodeId, topology.getNode()); + for (Node node : topology.getNode()) { + if (node.getNodeId().getValue().equals(expectedNodeId.getValue())) { + foundNode = node; + break; + } + } + Assert.assertNotNull("Expected to find Node: " + expectedNodeId, foundNode); } /* - * Generates the test cases involved in testing BridgeExternalIds. See inline comments for descriptions of - * the particular cases considered. - * - * The return value is a Map in the form (K,V)=(testCaseName,testCase). - * - testCaseName is a String - * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of - * either corresponding INPUT bridge external ids, or EXPECTED bridge external ids - * INPUT is the List we use when calling BridgeAugmentationBuilder.setBridgeExternalIds() - * EXPECTED is the List we expect to receive after calling BridgeAugmentationBuilder.getBridgeExternalIds() + * @see SouthboundIT.generateBridgeOtherConfigsTestCases() for specific test case information. */ - private Map>> generateBridgeExternalIdsTestCases() { - Map>> testMap = - new HashMap>>(); + @Test + public void testCRUDBridgeOtherConfigs() throws InterruptedException { + testCRUDBridge("BridgeOtherConfigs", new SouthboundBridgeOtherConfigsBuilder(), + new BridgeOtherConfigsSouthboundHelper()); + } - final String BRIDGE_EXTERNAL_ID_KEY = "BridgeExternalIdKey"; - final String BRIDGE_EXTERNAL_ID_VALUE = "BridgeExternalIdValue"; - final String FORMAT_STR = "%s_%s_%d"; - final String GOOD_KEY = "GoodKey"; - final String GOOD_VALUE = "GoodValue"; - final String NO_VALUE_FOR_KEY = "NoValueForKey"; - final String NO_KEY_FOR_VALUE = "NoKeyForValue"; + private interface SouthboundBridgeHelper { + void writeValues(OvsdbBridgeAugmentationBuilder builder, List values); + List readValues(OvsdbBridgeAugmentation augmentation); + } - // Test Case 1: TestOneExternalId - // Test Type: Positive - // Description: Create a bridge with one BridgeExternalIds - // Expected: A bridge is created with the single external_ids specified below - final String testOneExternalIdName = "TestOneExternalId"; - int externalIdCounter = 0; - List oneExternalId = (List) Lists.newArrayList( - (new BridgeExternalIdsBuilder() - .setBridgeExternalIdKey(String.format(FORMAT_STR, testOneExternalIdName, - BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setBridgeExternalIdValue(String.format(FORMAT_STR, testOneExternalIdName, - BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter)) - .build())); - Map> testCase = Maps.newHashMap(); - testCase.put(EXPECTED_VALUES_KEY, oneExternalId); - testCase.put(INPUT_VALUES_KEY, oneExternalId); - testMap.put(testOneExternalIdName, testCase); - - // Test Case 2: TestFiveExternalId - // Test Type: Positive - // Description: Create a bridge with multiple (five) BridgeExternalIds - // Expected: A bridge is created with the five external_ids specified below - final String testFiveExternalIdName = "TestFiveExternalId"; - externalIdCounter = 0; - List fiveExternalId = (List) Lists.newArrayList( - (new BridgeExternalIdsBuilder() - .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName, - BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName, - BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter)) - .build()), - (new BridgeExternalIdsBuilder() - .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName, - BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName, - BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter)) - .build()), - (new BridgeExternalIdsBuilder() - .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName, - BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName, - BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter)) - .build()), - (new BridgeExternalIdsBuilder() - .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName, - BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName, - BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter)) - .build()), - (new BridgeExternalIdsBuilder() - .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName, - BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter)) - .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName, - BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter)) - .build())); - testCase = Maps.newHashMap(); - testCase.put(EXPECTED_VALUES_KEY, fiveExternalId); - testCase.put(INPUT_VALUES_KEY, fiveExternalId); - testMap.put(testOneExternalIdName, testCase); - - // Test Case 3: TestOneGoodExternalIdOneMalformedExternalIdValue - // Test Type: Negative - // Description: - // One perfectly fine BridgeExternalId - // (TestOneGoodExternalIdOneMalformedExternalIdValue_BridgeExternalIdKey_1, - // TestOneGoodExternalIdOneMalformedExternalId_BridgeExternalIdValue_1) - // and one malformed BridgeExternalId which only has key specified - // (TestOneGoodExternalIdOneMalformedExternalIdValue_NoValueForKey_2, - // UNSPECIFIED) - // Expected: A bridge is created without any external_ids - final String testOneGoodExternalIdOneMalformedExternalIdValueName = - "TestOneGoodExternalIdOneMalformedExternalIdValue"; - externalIdCounter = 0; - BridgeExternalIds oneGood = new BridgeExternalIdsBuilder() - .setBridgeExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdValueName, - GOOD_KEY, ++externalIdCounter)) - .setBridgeExternalIdValue(String.format("FORMAT_STR", - testOneGoodExternalIdOneMalformedExternalIdValueName, - GOOD_VALUE, externalIdCounter)) - .build(); - BridgeExternalIds oneBad = new BridgeExternalIdsBuilder() - .setBridgeExternalIdKey(String.format(FORMAT_STR, - testOneGoodExternalIdOneMalformedExternalIdValueName, NO_VALUE_FOR_KEY, ++externalIdCounter)) - .build(); - List oneGoodOneBadInput = (List) Lists.newArrayList( - oneGood, oneBad); - List oneGoodOneBadExpected = null; - testCase = Maps.newHashMap(); - testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput); - testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected); - - // Test Case 4: TestOneGoodExternalIdOneMalformedExternalIdKey - // Test Type: Negative - // Description: - // One perfectly fine BridgeExternalId - // (TestOneGoodExternalIdOneMalformedExternalIdValue_BridgeExternalIdKey_1, - // TestOneGoodExternalIdOneMalformedExternalId_BridgeExternalIdValue_1) - // and one malformed BridgeExternalId which only has key specified - // (UNSPECIFIED, - // TestOneGoodExternalIdOneMalformedExternalIdKey_NoKeyForValue_2) - // Expected: A bridge is created without any external_ids - final String testOneGoodExternalIdOneMalformedExternalIdKeyName = - "TestOneGoodExternalIdOneMalformedExternalIdKey"; - externalIdCounter = 0; - oneGood = new BridgeExternalIdsBuilder() - .setBridgeExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdKeyName, - GOOD_KEY, ++externalIdCounter)) - .setBridgeExternalIdValue(String.format("FORMAT_STR", - testOneGoodExternalIdOneMalformedExternalIdKeyName, - GOOD_VALUE, externalIdCounter)) - .build(); - oneBad = new BridgeExternalIdsBuilder() - .setBridgeExternalIdKey(String.format(FORMAT_STR, - testOneGoodExternalIdOneMalformedExternalIdKeyName, NO_KEY_FOR_VALUE, ++externalIdCounter)) - .build(); - oneGoodOneBadInput = (List) Lists.newArrayList( - oneGood, oneBad); - oneGoodOneBadExpected = null; - testCase = Maps.newHashMap(); - testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput); - testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected); + private void testCRUDBridge(String prefix, KeyValueBuilder builder, SouthboundBridgeHelper helper) + throws InterruptedException { + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after + // the update has been performed. + List> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From"); + List> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To"); + for (SouthboundTestCase updateFromTestCase : updateFromTestCases) { + for (SouthboundTestCase updateToTestCase : updateToTestCases) { + String testBridgeName = String.format("%s_%s", prefix, updateToTestCase.name); + + // CREATE: Create the test bridge + final OvsdbBridgeName ovsdbBridgeName = new OvsdbBridgeName(testBridgeName); + final InstanceIdentifier bridgeIid = + SouthboundUtils.createInstanceIdentifier(connectionInfo, ovsdbBridgeName); + final NodeId bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid); + final NodeBuilder bridgeCreateNodeBuilder = new NodeBuilder(); + bridgeCreateNodeBuilder.setNodeId(bridgeNodeId); + OvsdbBridgeAugmentationBuilder bridgeCreateAugmentationBuilder = new OvsdbBridgeAugmentationBuilder(); + bridgeCreateAugmentationBuilder.setBridgeName(ovsdbBridgeName); + bridgeCreateAugmentationBuilder.setProtocolEntry(createMdsalProtocols()); + bridgeCreateAugmentationBuilder.setFailMode( + SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure")); + setManagedBy(bridgeCreateAugmentationBuilder, connectionInfo); + helper.writeValues(bridgeCreateAugmentationBuilder, updateFromTestCase.inputValues); + bridgeCreateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, + bridgeCreateAugmentationBuilder.build()); + LOG.debug("Built with the intent to store bridge data {}", bridgeCreateAugmentationBuilder.toString()); + Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, + bridgeCreateNodeBuilder.build())); + Thread.sleep(OVSDB_UPDATE_TIMEOUT); + + // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store, + // then repeat for OPERATIONAL data store + List updateFromConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName, + LogicalDatastoreType.CONFIGURATION)); + assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationExternalIds); + List updateFromOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName)); + assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalExternalIds); + + // UPDATE: update the values + final OvsdbBridgeAugmentationBuilder bridgeUpdateAugmentationBuilder = + new OvsdbBridgeAugmentationBuilder(); + helper.writeValues(bridgeUpdateAugmentationBuilder, updateToTestCase.inputValues); + final NodeBuilder bridgeUpdateNodeBuilder = new NodeBuilder(); + final Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName); + bridgeUpdateNodeBuilder.setNodeId(bridgeNode.getNodeId()); + bridgeUpdateNodeBuilder.setKey(bridgeNode.getKey()); + bridgeUpdateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, + bridgeUpdateAugmentationBuilder.build()); + Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, + bridgeUpdateNodeBuilder.build())); + Thread.sleep(OVSDB_UPDATE_TIMEOUT); + + // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store, + // then repeat for OPERATIONAL data store + List updateToConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName, + LogicalDatastoreType.CONFIGURATION)); + assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationExternalIds); + assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationExternalIds); + List updateToOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName)); + if (updateFromTestCase.expectedValues != null) { + assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalExternalIds); + assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalExternalIds); + } - return testMap; + // DELETE + Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, bridgeIid)); + Thread.sleep(OVSDB_UPDATE_TIMEOUT); + } + } } /* - * Generates the test cases involved in testing BridgeOtherConfigs. See inline comments for descriptions of - * the particular cases considered. - * - * The return value is a Map in the form (K,V)=(testCaseName,testCase). - * - testCaseName is a String - * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of - * either corresponding INPUT bridge other_configs, or EXPECTED bridge other_configs - * INPUT is the List we use when calling BridgeAugmentationBuilder.setBridgeOtherConfigs() - * EXPECTED is the List we expect to receive after calling BridgeAugmentationBuilder.getBridgeOtherConfigs() + * @see SouthboundIT.generateBridgeExternalIdsTestCases() for specific test case information */ - private Map>> generateBridgeOtherConfigsTestCases() { - Map>> testMap = - new HashMap>>(); + @Test + public void testCRUDBridgeExternalIds() throws InterruptedException { + testCRUDBridge("BridgeExternalIds", new SouthboundBridgeExternalIdsBuilder(), + new BridgeExternalIdsSouthboundHelper()); + } - final String BRIDGE_OTHER_CONFIGS_KEY = "BridgeOtherConfigKey"; - final String BRIDGE_OTHER_CONFIGS_VALUE = "BridgeOtherConfigValue"; - final String FORMAT_STR = "%s_%s_%d"; - final String GOOD_KEY = "GoodKey"; - final String GOOD_VALUE = "GoodValue"; - final String NO_VALUE_FOR_KEY = "NoValueForKey"; - final String NO_KEY_FOR_VALUE = "NoKeyForValue"; + @Test + public void testAddDeleteQos() throws InterruptedException { + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + OvsdbNodeAugmentation ovsdbNodeAugmentation; + Uri qosUri = new Uri("QOS-ROW"); + List typeList = new ArrayList(); + typeList.add(SouthboundConstants.QOS_LINUX_HTB); + typeList.add(SouthboundConstants.QOS_LINUX_HFSC); + + for (String qosType : typeList) { + try (TestQos testQos = new TestQos(connectionInfo, qosUri, SouthboundMapper.createQosType(qosType), null, null)) { + ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + QosEntries operQosHtb = getQos(qosUri, ovsdbNodeAugmentation); + Assert.assertNotNull(operQosHtb); + } + ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + QosEntries operQosHtb = getQos(qosUri, ovsdbNodeAugmentation); + Assert.assertNull(operQosHtb); + } + } - // Test Case 1: TestOneOtherConfig - // Test Type: Positive - // Description: Create a bridge with one other_config - // Expected: A bridge is created with the single other_config specified below - final String testOneOtherConfigName = "TestOneOtherConfig"; - int otherConfigCounter = 0; - List oneOtherConfig = (List) Lists.newArrayList( - (new BridgeOtherConfigsBuilder() - .setBridgeOtherConfigKey(String.format(FORMAT_STR, testOneOtherConfigName, - BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter)) - .setBridgeOtherConfigValue(String.format(FORMAT_STR, testOneOtherConfigName, - BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter)) - .build())); - Map> testCase = Maps.newHashMap(); - testCase.put(EXPECTED_VALUES_KEY, oneOtherConfig); - testCase.put(INPUT_VALUES_KEY, oneOtherConfig); - testMap.put(testOneOtherConfigName, testCase); - - // Test Case 2: TestFiveOtherConfig - // Test Type: Positive - // Description: Create a bridge with multiple (five) other_configs - // Expected: A bridge is created with the five other_configs specified below - final String testFiveOtherConfigName = "TestFiveOtherConfig"; - otherConfigCounter = 0; - List fiveOtherConfig = (List) Lists.newArrayList( - (new BridgeOtherConfigsBuilder() - .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName, - BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter)) - .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName, - BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter)) - .build()), - (new BridgeOtherConfigsBuilder() - .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName, - BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter)) - .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName, - BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter)) - .build()), - (new BridgeOtherConfigsBuilder() - .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName, - BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter)) - .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName, - BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter)) - .build()), - (new BridgeOtherConfigsBuilder() - .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName, - BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter)) - .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName, - BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter)) - .build()), - (new BridgeOtherConfigsBuilder() - .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName, - BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter)) - .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName, - BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter)) - .build())); - testCase = Maps.newHashMap(); - testCase.put(EXPECTED_VALUES_KEY, fiveOtherConfig); - testCase.put(INPUT_VALUES_KEY, fiveOtherConfig); - testMap.put(testOneOtherConfigName, testCase); - - // Test Case 3: TestOneGoodOtherConfigOneMalformedOtherConfigValue - // Test Type: Negative - // Description: - // One perfectly fine BridgeOtherConfig - // (TestOneGoodOtherConfigOneMalformedOtherConfigValue_BridgeOtherConfigKey_1, - // TestOneGoodOtherConfigOneMalformedOtherConfig_BridgeOtherConfigValue_1) - // and one malformed BridgeOtherConfig which only has key specified - // (TestOneGoodOtherConfigOneMalformedOtherConfigValue_NoValueForKey_2, - // UNSPECIFIED) - // Expected: A bridge is created without any other_config - final String testOneGoodOtherConfigOneMalformedOtherConfigValueName = - "TestOneGoodOtherConfigOneMalformedOtherConfigValue"; - otherConfigCounter = 0; - BridgeOtherConfigs oneGood = new BridgeOtherConfigsBuilder() - .setBridgeOtherConfigKey(String.format(FORMAT_STR, testOneGoodOtherConfigOneMalformedOtherConfigValueName, - GOOD_KEY, ++otherConfigCounter)) - .setBridgeOtherConfigValue(String.format("FORMAT_STR", - testOneGoodOtherConfigOneMalformedOtherConfigValueName, - GOOD_VALUE, otherConfigCounter)) - .build(); - BridgeOtherConfigs oneBad = new BridgeOtherConfigsBuilder() - .setBridgeOtherConfigKey(String.format(FORMAT_STR, - testOneGoodOtherConfigOneMalformedOtherConfigValueName, NO_VALUE_FOR_KEY, ++otherConfigCounter)) - .build(); - List oneGoodOneBadInput = (List) Lists.newArrayList( - oneGood, oneBad); - List oneGoodOneBadExpected = null; - testCase = Maps.newHashMap(); - testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput); - testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected); - - // Test Case 4: TestOneGoodOtherConfigOneMalformedOtherConfigKey - // Test Type: Negative - // Description: - // One perfectly fine BridgeOtherConfig - // (TestOneGoodOtherConfigOneMalformedOtherConfigValue_BridgeOtherConfigKey_1, - // TestOneGoodOtherConfigOneMalformedOtherConfig_BridgeOtherConfigValue_1) - // and one malformed BridgeOtherConfig which only has key specified - // (UNSPECIFIED, - // TestOneGoodOtherConfigOneMalformedOtherConfigKey_NoKeyForValue_2) - // Expected: A bridge is created without any other_config - final String testOneGoodOtherConfigOneMalformedOtherConfigKeyName = - "TestOneGoodOtherConfigOneMalformedOtherConfigIdKey"; - otherConfigCounter = 0; - oneGood = new BridgeOtherConfigsBuilder() - .setBridgeOtherConfigKey(String.format(FORMAT_STR, testOneGoodOtherConfigOneMalformedOtherConfigKeyName, - GOOD_KEY, ++otherConfigCounter)) - .setBridgeOtherConfigValue(String.format("FORMAT_STR", - testOneGoodOtherConfigOneMalformedOtherConfigKeyName, - GOOD_VALUE, otherConfigCounter)) - .build(); - oneBad = new BridgeOtherConfigsBuilder() - .setBridgeOtherConfigKey(String.format(FORMAT_STR, - testOneGoodOtherConfigOneMalformedOtherConfigKeyName, NO_KEY_FOR_VALUE, ++otherConfigCounter)) - .build(); - oneGoodOneBadInput = (List) Lists.newArrayList( - oneGood, oneBad); - oneGoodOneBadExpected = null; - testCase = Maps.newHashMap(); - testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput); - testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected); + @Test + public void testAddDeleteQueue() throws InterruptedException { + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + Uri queueUri = new Uri("QUEUE-A1"); + + try (TestQueue testQueue = new TestQueue(connectionInfo, queueUri, new Short("25"), null, null)) { + OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + Queues operQueue = getQueue(queueUri, ovsdbNodeAugmentation); + Assert.assertNotNull(operQueue); + } + OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + Queues operQueue = getQueue(queueUri, ovsdbNodeAugmentation); + Assert.assertNull(operQueue); + } - return testMap; + private static class SouthboundQueuesExternalIdsHelper implements SouthboundQueueHelper { + @Override + public void writeValues(QueuesBuilder builder, List values) { + builder.setQueuesExternalIds(values); + } + + @Override + public List readValues(Queues queue) { + return queue.getQueuesExternalIds(); + } + } + + private static class SouthboundQueuesOtherConfigHelper implements SouthboundQueueHelper { + @Override + public void writeValues(QueuesBuilder builder, List values) { + builder.setQueuesOtherConfig(values); + } + + @Override + public List readValues(Queues queue) { + return queue.getQueuesOtherConfig(); + } + } + + private interface SouthboundQueueHelper { + void writeValues(QueuesBuilder builder, List values); + List readValues(Queues queue); + } + + private Queues getQueue(Uri queueId, OvsdbNodeAugmentation node) { + for (Queues queue : node.getQueues()) { + if (queue.getKey().getQueueId().getValue().equals(queueId.getValue())) + return queue; + } + return null; + } + + private static class SouthboundQosExternalIdsHelper implements SouthboundQosHelper { + @Override + public void writeValues(QosEntriesBuilder builder, List values) { + builder.setQosExternalIds(values); + } + + @Override + public List readValues(QosEntries qos) { + return qos.getQosExternalIds(); + } + } + + private static class SouthboundQosOtherConfigHelper implements SouthboundQosHelper { + @Override + public void writeValues(QosEntriesBuilder builder, List values) { + builder.setQosOtherConfig(values); + } + + @Override + public List readValues(QosEntries qos) { + return qos.getQosOtherConfig(); + } + } + + private interface SouthboundQosHelper { + void writeValues(QosEntriesBuilder builder, List values); + List readValues(QosEntries qos); + } + + private QosEntries getQos(Uri qosId, OvsdbNodeAugmentation node) { + for (QosEntries qos : node.getQosEntries()) { + if (qos.getKey().getQosId().equals(qosId)) + return qos; + } + return null; + } + + private void testCRUDQueue( + KeyValueBuilder builder, String prefix, SouthboundQueueHelper helper) + throws InterruptedException { + + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + + // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after + // the update has been performed. + List> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From"); + List> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To"); + + for (SouthboundTestCase updateFromTestCase : updateFromTestCases) { + for (SouthboundTestCase updateToTestCase : updateToTestCases) { + String testQueueId = String.format("%s_%s", prefix, updateToTestCase.name); + + // CREATE: and update the test queue with starting values. + try (TestQueue testQueue = new TestQueue(connectionInfo, new Uri(testQueueId), new Short("45"), null, null)) { + QueuesBuilder queuesBuilder = new QueuesBuilder(); + queuesBuilder.setQueueId(new Uri(testQueueId)); + InstanceIdentifier queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(Queues.class, queuesBuilder.build().getKey()); + final NotifyingDataChangeListener queueConfigurationListener = + new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION, queueIid); + queueConfigurationListener.registerDataChangeListener(); + final NotifyingDataChangeListener queueOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid); + queueOperationalListener.registerDataChangeListener(); + + helper.writeValues(queuesBuilder, updateFromTestCase.inputValues); + Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + queueIid, queuesBuilder.build())); + queueConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // READ: Read the test queue and ensure changes are propagated to the CONFIGURATION data store, + // then repeat for OPERATIONAL data store + OvsdbNodeAugmentation updateFromConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.CONFIGURATION); + Queues queueFromConfig = getQueue(new Uri(testQueueId), updateFromConfigurationOvsdbNodeAugmentation); + if (queueFromConfig != null) { + List updateFromConfigurationValues = + helper.readValues(queueFromConfig); + assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues); + } + + queueOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + OvsdbNodeAugmentation updateFromOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + Queues queueFromOper = getQueue(new Uri(testQueueId), updateFromOperationalOvsdbNodeAugmentation); + if (queueFromOper != null) { + List updateFromOperationalValues = + helper.readValues(queueFromOper); + assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues); + } + + // UPDATE: update the values + QueuesBuilder queuesUpdateBuilder = new QueuesBuilder(); + queuesUpdateBuilder.setQueueId(new Uri(testQueueId)); + helper.writeValues(queuesUpdateBuilder, updateToTestCase.inputValues); + Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + queueIid, queuesUpdateBuilder.build())); + queueConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // READ: the test queue and ensure changes are propagated to the CONFIGURATION data store, + // then repeat for OPERATIONAL data store + OvsdbNodeAugmentation updateToConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.CONFIGURATION); + Queues queueToConfig = getQueue(new Uri(testQueueId), updateToConfigurationOvsdbNodeAugmentation); + if (queueToConfig != null) { + List updateToConfigurationValues = + helper.readValues(queueToConfig); + assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues); + } + + queueOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + OvsdbNodeAugmentation updateToOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + Queues queueToOper = getQueue(new Uri(testQueueId), updateToOperationalOvsdbNodeAugmentation); + if (queueToOper != null) { + List updateToOperationalValues = + helper.readValues(queueToOper); + assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues); + } + + // DELETE handled by TestQueue + } + } + } } - /* - * @see SouthboundIT.generateBridgeOtherConfigsTestCases() for specific test case information. - */ @Test - public void testBridgeOtherConfigs() throws InterruptedException { - final String TEST_BRIDGE_PREFIX = "BridgeOtherConfig"; - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - connectOvsdbNode(connectionInfo); + public void testCRUDQueueExternalIds() throws InterruptedException { + testCRUDQueue(new SouthboundQueuesExternalIdsBuilder(), "QueueExternalIds", + new SouthboundQueuesExternalIdsHelper()); + } - Map>> testCases = - generateBridgeOtherConfigsTestCases(); - List inputBridgeOtherConfigs = null; - List expectedBridgeOtherConfigs = null; - List actualBridgeOtherConfigs = null; - String testBridgeName = null; - boolean bridgeAdded = false; - for (String testCaseKey : testCases.keySet()) { - testBridgeName = String.format("%s_%s", TEST_BRIDGE_PREFIX, testCaseKey); - inputBridgeOtherConfigs = testCases.get(testCaseKey).get(INPUT_VALUES_KEY); - expectedBridgeOtherConfigs = testCases.get(testCaseKey).get(EXPECTED_VALUES_KEY); - bridgeAdded = addBridge(connectionInfo, null, testBridgeName, null, true, - SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, - null, inputBridgeOtherConfigs); - Assert.assertTrue(bridgeAdded); - - actualBridgeOtherConfigs = getBridge(connectionInfo, testBridgeName).getBridgeOtherConfigs(); - - // Verify the expected other_config are present, or no (null) other_config are present - if (expectedBridgeOtherConfigs != null) { - for (BridgeOtherConfigs expectedOtherConfig : expectedBridgeOtherConfigs) { - Assert.assertTrue(actualBridgeOtherConfigs.contains(expectedOtherConfig)); + @Test + public void testCRUDQueueOtherConfig() throws InterruptedException { + testCRUDQueue(new SouthboundQueuesOtherConfigBuilder(), "QueueOtherConfig", + new SouthboundQueuesOtherConfigHelper()); + } + + @Test + public void testCRUDQueueDscp() throws InterruptedException { + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + String testQueueId = "testQueueDscp"; + + // CREATE: and update the test queue with starting values. + try (TestQueue testQueue = new TestQueue(connectionInfo, new Uri(testQueueId), new Short("0"), null, null)) { + for (Short dscp = 1; dscp < 64; dscp++) { + QueuesBuilder queuesBuilder = new QueuesBuilder(); + queuesBuilder.setQueueId(new Uri(testQueueId)); + InstanceIdentifier queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(Queues.class, queuesBuilder.build().getKey()); + final NotifyingDataChangeListener queueOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid); + queueOperationalListener.registerDataChangeListener(); + + queuesBuilder.setDscp(dscp); + Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + queueIid, queuesBuilder.build())); + queueOperationalListener.waitForUpdate(OVSDB_ROUNDTRIP_TIMEOUT); + + // READ: Read the test queue and ensure changes are propagated to the OPERATIONAL data store + // assumption is that CONFIGURATION was updated if OPERATIONAL is correct + OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + Queues operQueue = getQueue(new Uri(testQueueId), ovsdbNodeAugmentation); + Assert.assertNotNull(operQueue); + Short operDscp = operQueue.getDscp(); + Assert.assertNotNull(operDscp); + Assert.assertEquals(dscp, operDscp); + } + + // DELETE handled by TestQueue + } + + } + + private void testCRUDQos( + KeyValueBuilder builder, String prefix, SouthboundQosHelper helper) + throws InterruptedException { + + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + + // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after + // the update has been performed. + List> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From"); + List> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To"); + + for (SouthboundTestCase updateFromTestCase : updateFromTestCases) { + for (SouthboundTestCase updateToTestCase : updateToTestCases) { + String testQosId = String.format("%s_%s", prefix, updateToTestCase.name); + + // CREATE: and update the test qos with starting values. + try (TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId), SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HTB), null, null)) { + QosEntriesBuilder qosBuilder = new QosEntriesBuilder(); + qosBuilder.setQosId(new Uri(testQosId)); + InstanceIdentifier qosIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(QosEntries.class, qosBuilder.build().getKey()); + final NotifyingDataChangeListener qosConfigurationListener = + new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION, qosIid); + qosConfigurationListener.registerDataChangeListener(); + final NotifyingDataChangeListener qosOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qosIid); + qosOperationalListener.registerDataChangeListener(); + + helper.writeValues(qosBuilder, updateFromTestCase.inputValues); + Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + qosIid, qosBuilder.build())); + qosConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // READ: Read the test queue and ensure changes are propagated to the CONFIGURATION data store, + // then repeat for OPERATIONAL data store + OvsdbNodeAugmentation updateFromConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.CONFIGURATION); + QosEntries qosFromConfig = getQos(new Uri(testQosId), updateFromConfigurationOvsdbNodeAugmentation); + if (qosFromConfig != null) { + List updateFromConfigurationValues = + helper.readValues(qosFromConfig); + assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues); + } + + qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + OvsdbNodeAugmentation updateFromOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + QosEntries qosFromOper = getQos(new Uri(testQosId), updateFromOperationalOvsdbNodeAugmentation); + if (qosFromOper != null) { + List updateFromOperationalValues = + helper.readValues(qosFromOper); + assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues); + } + + // UPDATE: update the values + QosEntriesBuilder qosUpdateBuilder = new QosEntriesBuilder(); + qosUpdateBuilder.setQosId(new Uri(testQosId)); + helper.writeValues(qosUpdateBuilder, updateToTestCase.inputValues); + Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + qosIid, qosUpdateBuilder.build())); + qosConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // READ: the test queue and ensure changes are propagated to the CONFIGURATION data store, + // then repeat for OPERATIONAL data store + OvsdbNodeAugmentation updateToConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.CONFIGURATION); + QosEntries qosToConfig = getQos(new Uri(testQosId), updateToConfigurationOvsdbNodeAugmentation); + if (qosToConfig != null) { + List updateToConfigurationValues = + helper.readValues(qosToConfig); + assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues); + } + + qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + OvsdbNodeAugmentation updateToOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + QosEntries qosToOper = getQos(new Uri(testQosId), updateToOperationalOvsdbNodeAugmentation); + if (qosToOper != null) { + List updateToOperationalValues = + helper.readValues(qosToOper); + assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues); + } + + // DELETE handled by TestQueue } - } else { - Assert.assertNull(actualBridgeOtherConfigs); } - Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName)); } - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); } - /* - * @see SouthboundIT.testCRUDBridgeExternalIds() - * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set" - */ - private void assertExpectedBridgeExternalIdsExist( List expected, - List test ) { + @Test + public void testCRUDQosExternalIds() throws InterruptedException { + testCRUDQos(new SouthboundQosExternalIdsBuilder(), "QosExternalIds", + new SouthboundQosExternalIdsHelper()); + } - if (expected != null) { - for (BridgeExternalIds expectedExternalId : expected) { - Assert.assertTrue(test.contains(expectedExternalId)); + @Test + public void testCRUDQosOtherConfig() throws InterruptedException { + testCRUDQos(new SouthboundQosOtherConfigBuilder(), "QosOtherConfig", + new SouthboundQosOtherConfigHelper()); + } + @Test + public void testCRUDQosQueues() throws InterruptedException { + ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber); + String testQosId = "testQosQueues"; + + // CREATE: and update the test queue with starting values. + try (TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId), + SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HTB), null, null); + TestQueue testQueue1 = new TestQueue(connectionInfo, new Uri("queue1"), new Short("12"), null, null); + TestQueue testQueue2 = new TestQueue(connectionInfo, new Uri("queue2"), new Short("35"), null, null)) { + QosEntriesBuilder qosBuilder = new QosEntriesBuilder(); + qosBuilder.setQosId(new Uri(testQosId)); + InstanceIdentifier qosIid = SouthboundUtils.createInstanceIdentifier(connectionInfo) + .augmentation(OvsdbNodeAugmentation.class) + .child(QosEntries.class, qosBuilder.build().getKey()); + final NotifyingDataChangeListener qosOperationalListener = + new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qosIid); + qosOperationalListener.registerDataChangeListener(); + + // READ, UPDATE: Read the UUIDs of the Queue rows and add them to the + // configuration of the Qos row. + OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + Queues operQueue1 = getQueue(new Uri("queue1"), ovsdbNodeAugmentation); + Assert.assertNotNull(operQueue1); + Uuid queue1Uuid = new Uuid(operQueue1.getQueueUuid().getValue()); + Queues operQueue2 = getQueue(new Uri("queue2"), ovsdbNodeAugmentation); + Assert.assertNotNull(operQueue2); + Uuid queue2Uuid = new Uuid(operQueue2.getQueueUuid().getValue()); + + List queueList = new ArrayList<>(); + queueList.add(new QueueListBuilder().setQueueNumber(new Long("0")) + .setQueueUuid(queue1Uuid).build()); + queueList.add(new QueueListBuilder().setQueueNumber(new Long("1")) + .setQueueUuid(queue2Uuid).build()); + qosBuilder.setQueueList(queueList); + + Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, + qosIid, qosBuilder.build())); + qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // READ: Read the test qos and ensure changes are propagated to the OPERATIONAL data store + // assumption is that CONFIGURATION was updated if OPERATIONAL is correct + ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + QosEntries operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation); + Assert.assertNotNull(operQos); + List operQueueList = operQos.getQueueList(); + Assert.assertNotNull(operQueueList); + for (QueueList queueEntry : queueList) { + Assert.assertTrue(isQueueInList(operQueueList, queueEntry)); } - } else { - Assert.assertNull(test); + + // DELETE one queue from queue list and check that one remains + KeyedInstanceIdentifier qosQueueIid = qosIid + .child(QueueList.class, new QueueListKey(new Long("0"))); + Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qosQueueIid)); + qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + // READ: Read the test qos and ensure changes are propagated to the OPERATIONAL data store + // assumption is that CONFIGURATION was updated if OPERATIONAL is correct + ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation); + Assert.assertNotNull(operQos); + operQueueList = operQos.getQueueList(); + Assert.assertNotNull(operQueueList); + for (QueueList queueEntry : queueList) { + if (queueEntry.getQueueUuid().equals(queue2Uuid)) { + Assert.assertTrue(isQueueInList(operQueueList, queueEntry)); + } else if (queueEntry.getQueueUuid().equals(queue1Uuid)) { + Assert.assertFalse(isQueueInList(operQueueList, queueEntry)); + } else { + Assert.assertTrue("Unknown queue entry in qos queue list", false); + } + } + + // DELETE queue list and check that list is empty + qosQueueIid = qosIid + .child(QueueList.class, new QueueListKey(new Long("1"))); + Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qosQueueIid)); + qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT); + + ovsdbNodeAugmentation = getOvsdbNode(connectionInfo, + LogicalDatastoreType.OPERATIONAL); + operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation); + Assert.assertNotNull(operQos); + operQueueList = operQos.getQueueList(); + Assert.assertNotNull(operQueueList); + Assert.assertTrue(operQueueList.isEmpty()); } } - /* - * @see SouthboundIT.testCRUDBridgeExternalIds() - * This is a helper test method. The method only checks if - * updateFromInputExternalIds != updateToInputExternalIds, (i.e., the updateTo "set" isn't the same - * as the updateFrom "set". Then, the method ensures each element of erase is not an element of test, as the input - * test cases are divergent. + private Boolean isQueueInList(List queueList, QueueList queue) { + for (QueueList queueEntry : queueList) { + if (queueEntry.getQueueNumber().equals(queue.getQueueNumber()) + && queueEntry.getQueueUuid().equals(queue.getQueueUuid())) { + return true; + } + } + return false; + } + + /** + *

+ * Representation of a southbound test case. Each test case has a name, a list of input values and a list of + * expected values. The input values are provided to the augmentation builder, and the expected values are checked + * against the output of the resulting augmentation. + *

+ *

+ * Instances of this class are immutable. + *

+ * + * @param The type of data used for the test case. + */ + private static final class SouthboundTestCase { + private final String name; + private final List inputValues; + private final List expectedValues; + + /** + * Creates an instance of a southbound test case. + * + * @param name The test case's name. + * @param inputValues The input values (provided as input to the underlying augmentation builder). + * @param expectedValues The expected values (checked against the output of the underlying augmentation). + */ + public SouthboundTestCase( + final String name, final List inputValues, final List expectedValues) { + this.name = name; + this.inputValues = inputValues; + this.expectedValues = expectedValues; + } + } + + /** + * Southbound test case builder. + * + * @param The type of data used for the test case. */ - private void assertBridgeExternalIdsErased( List updateFromInputExternalIds, - List updateToInputExternalIds, - List updateFromExpectedExternalIds, - List updateToTestExternalIds ) { - - if (!updateFromInputExternalIds.containsAll(updateToInputExternalIds)) { - for (BridgeExternalIds erasedExternalId : updateFromExpectedExternalIds) { - Assert.assertTrue(!updateToTestExternalIds.contains(erasedExternalId)); + private static final class SouthboundTestCaseBuilder { + private String name; + private List inputValues; + private List expectedValues; + + /** + * Creates a builder. Builders may be reused, the generated immutable instances are independent of the + * builders. There are no default values. + */ + public SouthboundTestCaseBuilder() { + // Nothing to do + } + + /** + * Sets the test case's name. + * + * @param name The test case's name. + * @return The builder. + */ + public SouthboundTestCaseBuilder name(final String name) { + this.name = name; + return this; + } + + /** + * Sets the input values. + * + * @param inputValues The input values. + * @return The builder. + */ + @SafeVarargs + public final SouthboundTestCaseBuilder input(final T... inputValues) { + this.inputValues = Lists.newArrayList(inputValues); + return this; + } + + /** + * Indicates that the provided input values should be expected as output values. + * + * @return The builder. + */ + public SouthboundTestCaseBuilder expectInputAsOutput() { + this.expectedValues = this.inputValues; + return this; + } + + /** + * Indicates that no output should be expected. + * + * @return The builder. + */ + public SouthboundTestCaseBuilder expectNoOutput() { + this.expectedValues = null; + return this; + } + + /** + * Builds an immutable instance representing the test case. + * + * @return The test case. + */ + @SuppressWarnings("unchecked") + public SouthboundTestCase build() { + return new SouthboundTestCase<>(name, inputValues, expectedValues); + } + } + + private abstract static class KeyValueBuilder { + private static final int COUNTER_START = 0; + private int counter = COUNTER_START; + + protected abstract Builder builder(); + + protected abstract void setKey(Builder builder, String key); + + protected abstract void setValue(Builder builder, String value); + + protected abstract boolean isValueMandatory(); + + public final T build(final String testName, final String key, final String value) { + final Builder builder = builder(); + this.counter++; + if (key != null) { + setKey(builder, String.format(FORMAT_STR, testName, key, this.counter)); + } + if (value != null) { + setValue(builder, String.format(FORMAT_STR, testName, value, this.counter)); } + return builder.build(); + } + + public final void reset() { + this.counter = COUNTER_START; + } + } + + private static final class SouthboundQueuesExternalIdsBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new QueuesExternalIdsBuilder(); + } + + @Override + protected void setKey(Builder builder, String key) { + ((QueuesExternalIdsBuilder) builder).setQueuesExternalIdKey(key); + } + + @Override + protected void setValue(Builder builder, String value) { + ((QueuesExternalIdsBuilder) builder).setQueuesExternalIdValue(value); + } + + @Override + protected boolean isValueMandatory() { + return true; + } + } + + private static final class SouthboundQueuesOtherConfigBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new QueuesOtherConfigBuilder(); + } + + @Override + protected void setKey(Builder builder, String key) { + ((QueuesOtherConfigBuilder) builder).setQueueOtherConfigKey(key); + } + + @Override + protected void setValue(Builder builder, String value) { + ((QueuesOtherConfigBuilder) builder).setQueueOtherConfigValue(value); + } + + @Override + protected boolean isValueMandatory() { + return false; + } + } + + private static final class SouthboundQosExternalIdsBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new QosExternalIdsBuilder(); + } + + @Override + protected void setKey(Builder builder, String key) { + ((QosExternalIdsBuilder) builder).setQosExternalIdKey(key); + } + + @Override + protected void setValue(Builder builder, String value) { + ((QosExternalIdsBuilder) builder).setQosExternalIdValue(value); + } + + @Override + protected boolean isValueMandatory() { + return true; + } + } + + private static final class SouthboundQosOtherConfigBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new QosOtherConfigBuilder(); + } + + @Override + protected void setKey(Builder builder, String key) { + ((QosOtherConfigBuilder) builder).setOtherConfigKey(key); + } + + @Override + protected void setValue(Builder builder, String value) { + ((QosOtherConfigBuilder) builder).setOtherConfigValue(value); + } + + @Override + protected boolean isValueMandatory() { + return false; + } + } + + private static final class SouthboundPortExternalIdsBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new PortExternalIdsBuilder(); + } + + @Override + protected void setKey(Builder builder, String key) { + ((PortExternalIdsBuilder) builder).setExternalIdKey(key); + } + + @Override + protected void setValue(Builder builder, String value) { + ((PortExternalIdsBuilder) builder).setExternalIdValue(value); + } + + @Override + protected boolean isValueMandatory() { + return true; + } + } + + private static final class SouthboundInterfaceExternalIdsBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new InterfaceExternalIdsBuilder(); + } + + @Override + protected void setKey(Builder builder, String key) { + ((InterfaceExternalIdsBuilder) builder).setExternalIdKey(key); + } + + @Override + protected void setValue(Builder builder, String value) { + ((InterfaceExternalIdsBuilder) builder).setExternalIdValue(value); + } + + @Override + protected boolean isValueMandatory() { + return true; + } + } + + private static final class SouthboundInterfaceLldpBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new InterfaceLldpBuilder(); + } + + @Override + protected void setKey(Builder builder, String key) { + ((InterfaceLldpBuilder) builder).setLldpKey((key)); + } + + @Override + protected void setValue(Builder builder, String value) { + ((InterfaceLldpBuilder) builder).setLldpValue(value); + } + + @Override + protected boolean isValueMandatory() { + return true; + } + } + + private static final class SouthboundOptionsBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new OptionsBuilder(); + } + + @Override + protected void setKey(Builder builder, String key) { + ((OptionsBuilder) builder).setOption(key); + } + + @Override + protected void setValue(Builder builder, String value) { + ((OptionsBuilder) builder).setValue(value); + } + + @Override + protected boolean isValueMandatory() { + return false; + } + } + + private static final class SouthboundInterfaceOtherConfigsBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new InterfaceOtherConfigsBuilder(); + } + + @Override + protected void setKey(Builder builder, String key) { + ((InterfaceOtherConfigsBuilder) builder).setOtherConfigKey(key); + } + + @Override + protected void setValue(Builder builder, String value) { + ((InterfaceOtherConfigsBuilder) builder).setOtherConfigValue(value); + } + + @Override + protected boolean isValueMandatory() { + return false; + } + } + + private static final class SouthboundPortOtherConfigsBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new PortOtherConfigsBuilder(); + } + + @Override + protected void setKey(Builder builder, String key) { + ((PortOtherConfigsBuilder) builder).setOtherConfigKey(key); + } + + @Override + protected void setValue(Builder builder, String value) { + ((PortOtherConfigsBuilder) builder).setOtherConfigValue(value); + } + + @Override + protected boolean isValueMandatory() { + return false; + } + } + + private static final class SouthboundBridgeOtherConfigsBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new BridgeOtherConfigsBuilder(); + } + + @Override + protected void setKey(Builder builder, String key) { + ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigKey(key); + } + + @Override + protected void setValue(Builder builder, String value) { + ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigValue(value); + } + + @Override + protected boolean isValueMandatory() { + return false; + } + } + + private static final class SouthboundBridgeExternalIdsBuilder extends KeyValueBuilder { + @Override + protected Builder builder() { + return new BridgeExternalIdsBuilder(); + } + + @Override + protected void setKey(Builder builder, String key) { + ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdKey(key); + } + + @Override + protected void setValue(Builder builder, String value) { + ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdValue(value); + } + + @Override + protected boolean isValueMandatory() { + return true; } } /* - * @see SouthboundIT.generateBridgeExternalIdsTestCases() for specific test case information + * Generates the test cases involved in testing key-value-based data. See inline comments for descriptions of + * the particular cases considered. */ - @Test - public void testCRUDBridgeExternalIds() throws InterruptedException { - final String TEST_BRIDGE_PREFIX = "CRUDBridgeExternalIds"; - ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr); - connectOvsdbNode(connectionInfo); - // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after - // the update has been performed. - Map>> updateFromTestCases = generateBridgeExternalIdsTestCases(); - Map>> updateToTestCases = generateBridgeExternalIdsTestCases(); - Map> updateFromTestCase = null; - List updateFromInputExternalIds = null; - List updateFromExpectedExternalIds = null; - List updateFromConfigurationExternalIds = null; - List updateFromOperationalExternalIds = null; - Map> updateToTestCase = null; - List updateToInputExternalIds = null; - List updateToExpectedExternalIds = null; - List updateToConfigurationExternalIds = null; - List updateToOperationalExternalIds = null; - String testBridgeName = null; - for (String updateFromTestCaseKey : updateFromTestCases.keySet()) { - updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey); - updateFromInputExternalIds = updateFromTestCase.get(INPUT_VALUES_KEY); - updateFromExpectedExternalIds = updateFromTestCase.get(EXPECTED_VALUES_KEY); - for (String testCaseKey : updateToTestCases.keySet()) { - testBridgeName = String.format("%s_%s", TEST_BRIDGE_PREFIX, testCaseKey); - updateToTestCase = updateToTestCases.get(testCaseKey); - updateToInputExternalIds = updateToTestCase.get(INPUT_VALUES_KEY); - updateToExpectedExternalIds = updateToTestCase.get(EXPECTED_VALUES_KEY); + private static List> generateKeyValueTestCases( + KeyValueBuilder builder, String testName) { + List> testCases = new ArrayList<>(); - // CREATE: Create the test bridge - boolean bridgeAdded = addBridge(connectionInfo, null, - testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), - true, null, updateFromInputExternalIds, null); - Assert.assertTrue(bridgeAdded); + final String GOOD_KEY = "GoodKey"; + final String GOOD_VALUE = "GoodValue"; + final String NO_VALUE_FOR_KEY = "NoValueForKey"; - // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store, - // then repeat for OPERATIONAL data store - updateFromConfigurationExternalIds = getBridge(connectionInfo, testBridgeName, - LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds(); - assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromConfigurationExternalIds); - updateFromOperationalExternalIds = getBridge(connectionInfo, testBridgeName).getBridgeExternalIds(); - assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromOperationalExternalIds); - - // UPDATE: update the external_ids - OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder(); - bridgeAugmentationBuilder.setBridgeExternalIds(updateToInputExternalIds); - InstanceIdentifier bridgeIid = - SouthboundMapper.createInstanceIdentifier(connectionInfo, - new OvsdbBridgeName(testBridgeName)); - NodeBuilder bridgeNodeBuilder = new NodeBuilder(); - Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName); - bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId()); - bridgeNodeBuilder.setKey(bridgeNode.getKey()); - bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build()); - boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, - bridgeNodeBuilder.build()); - Thread.sleep(OVSDB_UPDATE_TIMEOUT); - Assert.assertTrue(result); + final String idKey = testName + "Key"; + final String idValue = testName + "Value"; - // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store, - // then repeat for OPERATIONAL data store - updateToConfigurationExternalIds = getBridge(connectionInfo, testBridgeName, - LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds(); - assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds); - updateToOperationalExternalIds = getBridge(connectionInfo, testBridgeName) - .getBridgeExternalIds(); - assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds); - - // Make sure the old bridge external ids aren't present in the CONFIGURATION data store - assertBridgeExternalIdsErased(updateFromInputExternalIds, updateToInputExternalIds, - updateFromExpectedExternalIds, updateToConfigurationExternalIds); - assertBridgeExternalIdsErased(updateFromInputExternalIds, updateToInputExternalIds, - updateFromExpectedExternalIds, updateToConfigurationExternalIds); + // Test Case 1: TestOne + // Test Type: Positive + // Description: Create a termination point with one value + // Expected: A port is created with the single value specified below + final String testOneName = "TestOne" + testName; + testCases.add(new SouthboundTestCaseBuilder() + .name(testOneName) + .input(builder.build(testOneName, idKey, idValue)) + .expectInputAsOutput() + .build()); + builder.reset(); - // DELETE - Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName)); - } + // Test Case 2: TestFive + // Test Type: Positive + // Description: Create a termination point with multiple (five) values + // Expected: A port is created with the five values specified below + final String testFiveName = "TestFive" + testName; + testCases.add(new SouthboundTestCaseBuilder() + .name(testFiveName) + .input( + builder.build(testFiveName, idKey, idValue), + builder.build(testFiveName, idKey, idValue), + builder.build(testFiveName, idKey, idValue), + builder.build(testFiveName, idKey, idValue), + builder.build(testFiveName, idKey, idValue)) + .expectInputAsOutput() + .build()); + builder.reset(); + + if (!builder.isValueMandatory()) { + // Test Case 3: TestOneGoodOneMalformedValue + // Test Type: Negative + // Description: + // One perfectly fine input + // (TestOneGoodOneMalformedValue_GoodKey_1, + // TestOneGoodOneMalformedValue_GoodValue_1) + // and one malformed input which only has key specified + // (TestOneGoodOneMalformedValue_NoValueForKey_2, + // UNSPECIFIED) + // Expected: A port is created without any values + final String testOneGoodOneMalformedValueName = "TestOneGoodOneMalformedValue" + testName; + testCases.add(new SouthboundTestCaseBuilder() + .name(testOneGoodOneMalformedValueName) + .input( + builder.build(testOneGoodOneMalformedValueName, GOOD_KEY, GOOD_VALUE), + builder.build(testOneGoodOneMalformedValueName, NO_VALUE_FOR_KEY, null)) + .expectNoOutput() + .build()); + builder.reset(); + } else { + LOG.info("generateKeyValueTestCases: skipping test case 3 for {}", builder.getClass().getSimpleName()); + } + + return testCases; + } + + private static class PortExternalIdsSouthboundHelper implements SouthboundTerminationPointHelper { + @Override + public void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List values) { + builder.setPortExternalIds(values); + } + + @Override + public List readValues(OvsdbTerminationPointAugmentation augmentation) { + return augmentation.getPortExternalIds(); + } + } + + private static class InterfaceExternalIdsSouthboundHelper implements + SouthboundTerminationPointHelper { + @Override + public void writeValues( + OvsdbTerminationPointAugmentationBuilder builder, List values) { + builder.setInterfaceExternalIds(values); + } + + @Override + public List readValues(OvsdbTerminationPointAugmentation augmentation) { + return augmentation.getInterfaceExternalIds(); + } + } + + private static class InterfaceLldpSouthboundHelper implements + SouthboundTerminationPointHelper { + @Override + public void writeValues( + OvsdbTerminationPointAugmentationBuilder builder, List values) { + builder.setInterfaceLldp(values); + } + + @Override + public List readValues(OvsdbTerminationPointAugmentation augmentation) { + return augmentation.getInterfaceLldp(); + } + } + + private static class OptionsSouthboundHelper implements SouthboundTerminationPointHelper { + @Override + public void writeValues( + OvsdbTerminationPointAugmentationBuilder builder, List values) { + builder.setOptions(values); + } + + @Override + public List readValues(OvsdbTerminationPointAugmentation augmentation) { + return augmentation.getOptions(); + } + } + + private static class InterfaceOtherConfigsSouthboundHelper implements + SouthboundTerminationPointHelper { + @Override + public void writeValues( + OvsdbTerminationPointAugmentationBuilder builder, List values) { + builder.setInterfaceOtherConfigs(values); + } + + @Override + public List readValues(OvsdbTerminationPointAugmentation augmentation) { + return augmentation.getInterfaceOtherConfigs(); + } + } + + private static class PortOtherConfigsSouthboundHelper implements + SouthboundTerminationPointHelper { + @Override + public void writeValues( + OvsdbTerminationPointAugmentationBuilder builder, List values) { + builder.setPortOtherConfigs(values); + } + + @Override + public List readValues(OvsdbTerminationPointAugmentation augmentation) { + return augmentation.getPortOtherConfigs(); + } + } + + private static class BridgeExternalIdsSouthboundHelper implements SouthboundBridgeHelper { + @Override + public void writeValues( + OvsdbBridgeAugmentationBuilder builder, List values) { + builder.setBridgeExternalIds(values); + } + + @Override + public List readValues(OvsdbBridgeAugmentation augmentation) { + return augmentation.getBridgeExternalIds(); + } + } + + private static class BridgeOtherConfigsSouthboundHelper implements SouthboundBridgeHelper { + @Override + public void writeValues( + OvsdbBridgeAugmentationBuilder builder, List values) { + builder.setBridgeOtherConfigs(values); + } + + @Override + public List readValues(OvsdbBridgeAugmentation augmentation) { + return augmentation.getBridgeOtherConfigs(); } - Assert.assertTrue(disconnectOvsdbNode(connectionInfo)); } }