/*
* Copyright © 2015, 2017 Red Hat, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.ovsdb.southbound.it;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
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.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
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.Collections;
import java.util.HashSet;
import java.util.List;
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.notation.Version;
import org.opendaylight.ovsdb.schema.openvswitch.Queue;
import org.opendaylight.ovsdb.southbound.SouthboundConstants;
import org.opendaylight.ovsdb.southbound.SouthboundMapper;
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;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbQueueRef;
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;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.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;
import org.ops4j.pax.exam.karaf.options.LogLevelOption;
import org.ops4j.pax.exam.options.MavenUrlReference;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerClass;
import org.ops4j.pax.exam.util.Filter;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Integration tests for southbound-impl
*
* @author Sam Hague (shague@redhat.com)
*/
@RunWith(PaxExam.class)
@ExamReactorStrategy(PerClass.class)
public class SouthboundIT extends AbstractMdsalTestBase {
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 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 final Long MAX_BACKOFF = 10000L;
private static final Long INACTIVITY_PROBE = 30000L;
private static String addressStr;
private static int portNumber;
private static String connectionType;
private static boolean setup = false;
private static MdsalUtils mdsalUtils = null;
private static Node ovsdbNode;
private static int testMethodsRemaining;
private static Version schemaVersion;
@Inject @Filter(timeout=60000)
private static DataBroker dataBroker = null;
@Inject
private BundleContext bundleContext;
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<InstanceIdentifier<?>> createdIids = new HashSet<>();
private final Set<InstanceIdentifier<?>> removedIids = new HashSet<>();
private final Set<InstanceIdentifier<?>> 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<InstanceIdentifier<?>, 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);
}
}
}
@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 getKarafDistro() {
return maven()
.groupId("org.opendaylight.ovsdb")
.artifactId("southbound-karaf")
.versionAsInProject()
.type("zip")
.getURL();
}
@Override
public MavenUrlReference getFeatureRepo() {
return maven()
.groupId("org.opendaylight.ovsdb")
.artifactId("southbound-features")
.classifier("features")
.type("xml")
.versionAsInProject();
}
@Override
public String getFeatureName() {
return "odl-ovsdb-southbound-test";
}
protected String usage() {
return "Integration Test needs a valid connection configuration as follows :\n"
+ "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
+ "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
}
@Override
public Option getLoggingOption() {
return composite(
editConfigurationFilePut(SouthboundITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
"log4j.logger.org.opendaylight.ovsdb",
LogLevelOption.LogLevel.TRACE.name()),
super.getLoggingOption());
}
private Option[] getPropertiesOptions() {
Properties props = new Properties(System.getProperties());
String addressStr = props.getProperty(SouthboundITConstants.SERVER_IPADDRESS,
SouthboundITConstants.DEFAULT_SERVER_IPADDRESS);
String portStr = props.getProperty(SouthboundITConstants.SERVER_PORT,
SouthboundITConstants.DEFAULT_SERVER_PORT);
String connectionType = props.getProperty(SouthboundITConstants.CONNECTION_TYPE,
SouthboundITConstants.CONNECTION_TYPE_ACTIVE);
LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
connectionType, addressStr, portStr);
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,
SouthboundITConstants.SERVER_PORT, portStr),
editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
SouthboundITConstants.CONNECTION_TYPE, connectionType),
};
}
@Before
@Override
public void setup() throws InterruptedException {
if (setup) {
LOG.info("Skipping setup, already initialized");
return;
}
try {
super.setup();
} catch (Exception e) {
LOG.warn("Failed to setup test", e);
}
Assert.assertNotNull("db should not be null", dataBroker);
LOG.info("sleeping for 10s to let the features finish installing");
Thread.sleep(10000);
addressStr = bundleContext.getProperty(SouthboundITConstants.SERVER_IPADDRESS);
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, portNumber);
if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_ACTIVE)) {
if (addressStr == null) {
fail(usage());
}
}
mdsalUtils = new MdsalUtils(dataBroker);
assertTrue("Did not find " + SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue(), getOvsdbTopology());
final ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
final InstanceIdentifier<Node> 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);
OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
assertNotNull("The OvsdbNodeAugmentation cannot be null", ovsdbNodeAugmentation);
schemaVersion = Version.fromString(ovsdbNodeAugmentation.getDbVersion());
LOG.info("schemaVersion = {}", schemaVersion);
// 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);
}
}
}
private Boolean getOvsdbTopology() {
LOG.info("getOvsdbTopology: looking for {}...", SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue());
Boolean found = false;
final TopologyId topologyId = SouthboundUtils.OVSDB_TOPOLOGY_ID;
InstanceIdentifier<Topology> path =
InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, new TopologyKey(topologyId));
for (int i = 0; i < 60; i++) {
Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
if (topology != null) {
LOG.info("getOvsdbTopology: found {}...", SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue());
found = true;
break;
} else {
LOG.info("getOvsdbTopology: still looking ({})...", i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
LOG.warn("Interrupted while waiting for {}", SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue(), e);
}
}
}
return found;
}
/**
* 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.
*
* @throws InterruptedException
*/
@Test
public void testPassiveNode() throws InterruptedException {
if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_PASSIVE)) {
//Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
Thread.sleep(SouthboundITConstants.CONNECTION_INIT_TIMEOUT);
}
}
private static ConnectionInfo getConnectionInfo(final String addressStr, final int portNumber) {
InetAddress inetAddress = null;
try {
inetAddress = InetAddress.getByName(addressStr);
} catch (UnknownHostException e) {
fail("Could not resolve " + addressStr + ": " + e);
}
IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
PortNumber port = new PortNumber(portNumber);
final ConnectionInfo connectionInfo = new ConnectionInfoBuilder()
.setRemoteIp(address)
.setRemotePort(port)
.build();
LOG.info("connectionInfo: {}", connectionInfo);
return connectionInfo;
}
@Test
public void testNetworkTopology() throws InterruptedException {
NetworkTopology networkTopology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION,
InstanceIdentifier.create(NetworkTopology.class));
Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.CONFIGURATION,
networkTopology);
networkTopology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
InstanceIdentifier.create(NetworkTopology.class));
Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.OPERATIONAL,
networkTopology);
}
@Test
public void testOvsdbTopology() throws InterruptedException {
InstanceIdentifier<Topology> path = InstanceIdentifier
.create(NetworkTopology.class)
.child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
Topology topology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
topology);
topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
topology);
}
private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
final InstanceIdentifier<Node> 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 void waitForOperationalCreation(InstanceIdentifier<Node> 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 static void waitForOperationalDeletion(InstanceIdentifier<Node> 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 void waitForOperationalUpdate(InstanceIdentifier<Node> 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 static void disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
waitForOperationalDeletion(iid);
Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
Assert.assertNull(node);
LOG.info("Disconnected from {}", SouthboundUtils.connectionInfoToString(connectionInfo));
}
@Test
public void testAddDeleteOvsdbNode() throws InterruptedException {
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, portNumber);
List<DatapathTypeEntry> datapathTypeEntries = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class)
.getDatapathTypeEntry();
if (datapathTypeEntries == null) {
LOG.info("DPDK not supported on this node.");
} else {
for (DatapathTypeEntry dpTypeEntry : datapathTypeEntries) {
Class<? extends DatapathTypeBase> 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<Node> bridgeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo,
new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
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<String> 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<? extends InterfaceTypeBase> 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<Node> 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<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
.get(dpdkType);
List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
for (TerminationPoint terminationPoint : terminationPoints) {
OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint
.getAugmentation(OvsdbTerminationPointAugmentation.class);
if (ovsdbTerminationPointAugmentation.getName().equals(testPortname)) {
Class<? extends InterfaceTypeBase> opPort = ovsdbTerminationPointAugmentation
.getInterfaceType();
Assert.assertEquals(dpdkIfType, opPort);
}
}
}
}
}
break;
}
}
}
@Test
public void testOvsdbNodeOvsVersion() throws InterruptedException {
OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
Assert.assertNotNull(ovsdbNodeAugmentation);
assertNotNull(ovsdbNodeAugmentation.getOvsVersion());
}
@Test
public void testOvsdbNodeDbVersion() throws InterruptedException {
OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
Assert.assertNotNull(ovsdbNodeAugmentation);
assertNotNull(ovsdbNodeAugmentation.getDbVersion());
}
@Test
public void testOpenVSwitchOtherConfig() throws InterruptedException {
OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
Assert.assertNotNull(ovsdbNodeAugmentation);
List<OpenvswitchOtherConfigs> otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
if (otherConfigsList != null) {
for (OpenvswitchOtherConfigs otherConfig : otherConfigsList) {
if (otherConfig.getOtherConfigKey().equals("local_ip")) {
LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
break;
} else {
LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
}
}
} else {
LOG.info("other_config is not present");
}
}
@Test
public void testOvsdbBridgeControllerInfo() throws InterruptedException {
ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portNumber);
String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
assertNotNull("Failed to get controller target", controllerTarget);
List<ControllerEntry> 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<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
for (ControllerEntry entry : getControllerEntries) {
if (entry.getTarget() != null) {
Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
}
if (entry.getMaxBackoff() != null) {
Assert.assertEquals(entry.getMaxBackoff(), MAX_BACKOFF);
}
if (entry.getInactivityProbe() != null) {
Assert.assertEquals(entry.getInactivityProbe(),INACTIVITY_PROBE);
}
}
}
}
private List<ControllerEntry> createControllerEntry(String controllerTarget) {
List<ControllerEntry> controllerEntriesList = new ArrayList<>();
controllerEntriesList.add(new ControllerEntryBuilder()
.setTarget(new Uri(controllerTarget))
.setMaxBackoff(MAX_BACKOFF)
.setInactivityProbe(INACTIVITY_PROBE)
.build());
return controllerEntriesList;
}
private static void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
final ConnectionInfo connectionInfo) {
InstanceIdentifier<Node> connectionNodePath = SouthboundUtils.createInstanceIdentifier(connectionInfo);
ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
}
private static List<ProtocolEntry> createMdsalProtocols() {
List<ProtocolEntry> protocolList = new ArrayList<>();
ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
return protocolList;
}
private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
new OvsdbTerminationPointAugmentationBuilder();
ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
new InterfaceTypeEntryBuilder()
.setInterfaceType(
SouthboundMapper.createInterfaceType("internal"))
.build().getInterfaceType());
return ovsdbTerminationPointAugmentationBuilder;
}
private OvsdbTerminationPointAugmentationBuilder createGenericDpdkOvsdbTerminationPointAugmentationBuilder(
final String portName) {
OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
createGenericOvsdbTerminationPointAugmentationBuilder();
ovsdbTerminationBuilder.setName(portName);
Class<? extends InterfaceTypeBase> ifType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
.get("dpdk");
ovsdbTerminationBuilder.setInterfaceType(ifType);
return ovsdbTerminationBuilder;
}
private OvsdbTerminationPointAugmentationBuilder createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(
String testPortname,Class<? extends InterfaceTypeBase> 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 {
InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
NodeBuilder portNodeBuilder = new NodeBuilder();
NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
portNodeBuilder.setNodeId(portNodeId);
TerminationPointBuilder entry = new TerminationPointBuilder();
entry.setKey(new TerminationPointKey(new TpId(portName)));
entry.addAugmentation(
OvsdbTerminationPointAugmentation.class,
ovsdbTerminationPointAugmentationBuilder.build());
portNodeBuilder.setTerminationPoint(Collections.singletonList(entry.build()));
boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
portIid, portNodeBuilder.build());
Thread.sleep(OVSDB_UPDATE_TIMEOUT);
return result;
}
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<Node> bridgeIid,
final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
@Nullable final Class<? extends DatapathTypeBase> dpType,
@Nullable final List<BridgeExternalIds> externalIds,
@Nullable final List<ControllerEntry> controllerEntries,
@Nullable final List<BridgeOtherConfigs> 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);
}
}
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);
}
@Override
public void close() {
final InstanceIdentifier<Node> 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);
}
}
}
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> mappings,
@Nullable final List<AutoattachExternalIds> 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<Autoattach> 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);
}
}
@Override
public void close() {
final InstanceIdentifier<Autoattach> 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 = "testAutoattachEntry";
String testSystemName = "testSystemName";
String testSystemDescription = "testSystemDescription";
String testAutoattachExternalKey = "testAutoattachExternalKey";
String testAutoattachExternalValue = "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> mappings = ImmutableList.of(new MappingsBuilder().setMappingsKey(100L).setMappingsValue(200).build());
Autoattach updatedAa = new AutoattachBuilder()
.setAutoattachId(new Uri(testAutoattachId))
.setMappings(mappings)
.build();
InstanceIdentifier<Autoattach> 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<AutoattachExternalIds> 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<Mappings> 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<AutoattachExternalIds> 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<? extends QosTypeBase> qosType,
@Nullable final List<QosExternalIds> externalIds,
@Nullable final List<QosOtherConfig> otherConfigs) {
this.connectionInfo = connectionInfo;
this.qosId = qosId;
QosEntries qosEntry = new QosEntriesBuilder()
.setQosId(qosId)
.setQosType(qosType)
.setQosExternalIds(externalIds)
.setQosOtherConfig(otherConfigs)
.build();
InstanceIdentifier<QosEntries> 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<QosEntries> 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);
}
}
}
private static class TestQueue implements AutoCloseable {
private final ConnectionInfo connectionInfo;
private final Uri queueId;
private final InstanceIdentifier<Queues> qIid;
/**
* 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<QueuesExternalIds> externalIds,
@Nullable final List<QueuesOtherConfig> otherConfigs) {
this.connectionInfo = connectionInfo;
this.queueId = queueId;
Queues queue = new QueuesBuilder()
.setQueueId(queueId)
.setDscp(queueDscp)
.setQueuesExternalIds(externalIds)
.setQueuesOtherConfig(otherConfigs)
.build();
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);
}
}
public InstanceIdentifier<Queues> getInstanceIdentifier() {
return qIid;
}
@Override
public void close() {
InstanceIdentifier<Queues> 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);
}
}
}
private OvsdbNodeAugmentation getOvsdbNode(ConnectionInfo connectionInfo, LogicalDatastoreType store) {
InstanceIdentifier<Node> 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) {
return getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
}
/**
* Extract the <code>store</code> type data store contents for the particular bridge identified by
* <code>bridgeName</code>.
*
* @param connectionInfo the connection information
* @param bridgeName the bridge name
* @param store defined by the <code>LogicalDatastoreType</code> enumeration
* @return <code>store</code> type data store contents
*/
private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
LogicalDatastoreType store) {
Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
Assert.assertNotNull(bridgeNode);
OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
Assert.assertNotNull(ovsdbBridgeAugmentation);
return ovsdbBridgeAugmentation;
}
/**
* extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
* identified by <code>bridgeName</code>
*
* @param connectionInfo the connection information
* @param bridgeName the bridge name
* @see <code>SouthboundIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
* @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
*/
private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
}
/**
* Extract the node contents from <code>store</code> type data store for the
* bridge identified by <code>bridgeName</code>
*
* @param connectionInfo the connection information
* @param bridgeName the bridge name
* @param store defined by the <code>LogicalDatastoreType</code> enumeration
* @return <code>store</code> type data store contents
*/
private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
InstanceIdentifier<Node> bridgeIid =
SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
return mdsalUtils.read(store, bridgeIid);
}
/**
* Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
* bridge identified by <code>bridgeName</code>
*
* @param connectionInfo the connection information
* @param bridgeName the bridge name
* @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
*/
private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
}
@Test
public void testAddDeleteBridge() throws InterruptedException {
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
Assert.assertNotNull(bridge);
LOG.info("bridge: {}", bridge);
}
}
private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
return SouthboundUtils.createInstanceIdentifier(connectionInfo, bridge.getBridgeName());
}
/**
* Extracts the <code>TerminationPointAugmentation</code> for the <code>index</code> <code>TerminationPoint</code>
* on <code>bridgeName</code>
*
* @param connectionInfo the connection information
* @param bridgeName the bridge name
* @param store defined by the <code>LogicalDatastoreType</code> 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) {
List<TerminationPoint> tpList = getBridgeNode(connectionInfo, bridgeName, store).getTerminationPoint();
if (tpList == null) {
return null;
}
return tpList.get(index).getAugmentation(OvsdbTerminationPointAugmentation.class);
}
@Test
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(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
Assert.assertNotNull(terminationPointNode);
// Test read ifIndex
List<TerminationPoint> 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);
}
}
}
}
@Test
public void testCRDTerminationPointOfPort() throws InterruptedException {
final Long OFPORT_EXPECTED = 45002L;
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
// 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);
ovsdbTerminationBuilder.setOfport(OFPORT_EXPECTED);
Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
Assert.assertNotNull(terminationPointNode);
// READ
List<TerminationPoint> 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);
}
}
// 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."
// DELETE handled by TestBridge
}
}
@Test
public void testCRDTerminationPointOfPortRequest() throws InterruptedException {
final Long OFPORT_EXPECTED = 45008L;
final Long OFPORT_INPUT = 45008L;
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
// 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<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
Assert.assertNotNull(terminationPointNode);
// READ
List<TerminationPoint> 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);
}
}
// 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. "
// DELETE handled by TestBridge
}
}
private <T> void assertExpectedExist(List<T> expected, List<T> test) {
if (expected != null && test != null) {
for (T exp : expected) {
Assert.assertTrue("The retrieved values don't contain " + exp, test.contains(exp));
}
}
}
private interface SouthboundTerminationPointHelper<T> {
void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<T> values);
List<T> readValues(OvsdbTerminationPointAugmentation augmentation);
}
/*
* Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
*
* @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
*/
private <T> void testCRUDTerminationPoint(
KeyValueBuilder<T> builder, String prefix, SouthboundTerminationPointHelper<T> helper)
throws InterruptedException {
final int TERMINATION_POINT_TEST_INDEX = 0;
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
// updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
// the update has been performed.
List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
String testBridgeAndPortName = String.format("%s_%s", prefix, updateToTestCase.name);
// 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<T> updateFromConfigurationValues =
helper.readValues(updateFromConfigurationTerminationPointAugmentation);
assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues);
}
OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
if (updateFromOperationalTerminationPointAugmentation != null) {
List<T> 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<Node> 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(Collections.singletonList(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<T> 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<T> updateToOperationalValues =
helper.readValues(updateToOperationalTerminationPointAugmentation);
if (updateFromTestCase.expectedValues != null) {
assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalValues);
}
}
// DELETE handled by TestBridge
}
}
}
}
/*
* Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
*
* @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
*/
@Test
public void testCRUDTerminationPointPortExternalIds() throws InterruptedException {
testCRUDTerminationPoint(new SouthboundPortExternalIdsBuilder(), "TPPortExternalIds",
new PortExternalIdsSouthboundHelper());
}
/*
* Tests the CRUD operations for <code>Interface</code> <code>external_ids</code>.
*
* @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
*/
@Test
public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException {
testCRUDTerminationPoint(new SouthboundInterfaceExternalIdsBuilder(), "TPInterfaceExternalIds",
new InterfaceExternalIdsSouthboundHelper());
}
/*
* Tests the CRUD operations for <code>Interface</code> <code>lldp</code>.
*
* @see <code>SouthboundIT.generateInterfaceLldpTestCases()</code> for specific test case information
*/
@Test
public void testCRUDTerminationPointInterfaceLldp() throws InterruptedException {
testCRUDTerminationPoint(new SouthboundInterfaceLldpBuilder(), "TPInterfaceLldp",
new InterfaceLldpSouthboundHelper());
}
/*
* Tests the CRUD operations for <code>TerminationPoint</code> <code>options</code>.
*
* @see <code>SouthboundIT.generateTerminationPointOptions()</code> for specific test case information
*/
@Test
public void testCRUDTerminationPointOptions() throws InterruptedException {
testCRUDTerminationPoint(new SouthboundOptionsBuilder(), "TPOptions", new OptionsSouthboundHelper());
}
/*
* Tests the CRUD operations for <code>Interface</code> <code>other_configs</code>.
*
* @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
*/
@Test
public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException {
testCRUDTerminationPoint(new SouthboundInterfaceOtherConfigsBuilder(), "TPInterfaceOtherConfigs",
new InterfaceOtherConfigsSouthboundHelper());
}
/*
* Tests the CRUD operations for <code>Port</code> <code>other_configs</code>.
*
* @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
*/
@Test
public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException {
testCRUDTerminationPoint(new SouthboundPortOtherConfigsBuilder(), "TPPortOtherConfigs",
new PortOtherConfigsSouthboundHelper());
}
@Test
public void testCRUDTerminationPoints() throws InterruptedException {
String port1 = "vx1";
String port2 = "vxlanport";
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
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();
// add and delete a single port
String portName = port1;
ovsdbTerminationBuilder.setName(portName);
Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
InstanceIdentifier<Node> 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<TerminationPoint> 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
}
}
@Test
public void testCRUDTerminationPointVlan() throws InterruptedException {
final Integer CREATED_VLAN_ID = 4000;
final Integer UPDATED_VLAN_ID = 4001;
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 = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
connectionInfo, bridge.getBridgeName()));
OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
createGenericOvsdbTerminationPointAugmentationBuilder();
String portName = "testTerminationPointVlanId";
ovsdbTerminationBuilder.setName(portName);
ovsdbTerminationBuilder.setVlanTag(new VlanId(CREATED_VLAN_ID));
Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
Assert.assertNotNull(terminationPointNode);
// READ
List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation;
for (TerminationPoint terminationPoint : terminationPoints) {
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<Node> 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(Collections.singletonList(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)) {
VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
Assert.assertNotNull(actualVlanId);
Integer actualVlanIdInt = actualVlanId.getValue();
Assert.assertEquals(UPDATED_VLAN_ID, actualVlanIdInt);
}
}
// DELETE handled by TestBridge
}
}
@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<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
Assert.assertNotNull(terminationPointNode);
// READ
List<TerminationPoint> 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));
}
}
// UPDATE
NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
new OvsdbTerminationPointAugmentationBuilder();
tpUpdateAugmentationBuilder.setVlanMode(UPDATED_VLAN_MODE);
InstanceIdentifier<Node> 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(Collections.singletonList(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_VLAN_MODE, ovsdbTerminationPointAugmentation.getVlanMode());
}
}
// DELETE handled by TestBridge
}
}
}
@SuppressWarnings("unchecked")
private List<Set<Integer>> generateVlanSets() {
int min = 0;
int max = 4095;
return Lists.newArrayList(
Collections.<Integer>emptySet(),
Collections.singleton(2222),
Sets.newHashSet(min, max, min + 1, max - 1, (max - min) / 2));
}
private List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
List<Trunks> trunkList = new ArrayList<>();
for (Integer trunk : trunkSet) {
TrunksBuilder trunkBuilder = new TrunksBuilder();
trunkBuilder.setTrunk(new VlanId(trunk));
trunkList.add(trunkBuilder.build());
}
return trunkList;
}
@Test
public void testCRUDTerminationPointVlanTrunks() throws InterruptedException {
final List<Trunks> UPDATED_TRUNKS = buildTrunkList(Collections.singleton(2011));
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
Iterable<Set<Integer>> vlanSets = generateVlanSets();
int testCase = 0;
for (Set<Integer> vlanSet : vlanSets) {
++testCase;
// 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> trunks = buildTrunkList(vlanSet);
ovsdbTerminationBuilder.setTrunks(trunks);
Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
Assert.assertNotNull(terminationPointNode);
// READ
List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
for (TerminationPoint terminationPoint : terminationPoints) {
OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
List<Trunks> 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<Node> 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(Collections.singletonList(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
}
}
}
/*
* Tests setting and deleting <code>qos</code> field in a <code>port</code>.
*/
@Test
public void testCRUDTerminationPointQos() throws InterruptedException {
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
String testQosId = "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());
OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
Assert.assertNotNull(bridge);
NodeId nodeId = SouthboundUtils.createManagedNodeId(connectionInfo, bridge.getBridgeName());
OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
createGenericOvsdbTerminationPointAugmentationBuilder();
String portName = "testTerminationPointQos";
ovsdbTerminationBuilder.setName(portName);
Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
// READ and check that qos uuid has been added to the port
InstanceIdentifier<TerminationPoint> tpEntryIid = getTpIid(connectionInfo, bridge)
.child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
TerminationPoint terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpEntryIid);
Assert.assertNotNull(terminationPoint);
// 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);
// DELETE handled by TestBridge
}
}
@Test
public void testGetOvsdbNodes() throws InterruptedException {
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
InstanceIdentifier<Topology> topologyPath = InstanceIdentifier
.create(NetworkTopology.class)
.child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath);
InstanceIdentifier<Node> expectedNodeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class).getNodeId();
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);
}
/*
* @see <code>SouthboundIT.generateBridgeOtherConfigsTestCases()</code> for specific test case information.
*/
@Test
public void testCRUDBridgeOtherConfigs() throws InterruptedException {
testCRUDBridge("BridgeOtherConfigs", new SouthboundBridgeOtherConfigsBuilder(),
new BridgeOtherConfigsSouthboundHelper());
}
private interface SouthboundBridgeHelper<T> {
void writeValues(OvsdbBridgeAugmentationBuilder builder, List<T> values);
List<T> readValues(OvsdbBridgeAugmentation augmentation);
}
private <T> void testCRUDBridge(String prefix, KeyValueBuilder<T> builder, SouthboundBridgeHelper<T> 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<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
String testBridgeName = String.format("%s_%s", prefix, updateToTestCase.name);
// CREATE: Create the test bridge
final OvsdbBridgeName ovsdbBridgeName = new OvsdbBridgeName(testBridgeName);
final InstanceIdentifier<Node> 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<T> updateFromConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
LogicalDatastoreType.CONFIGURATION));
assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationExternalIds);
List<T> 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<T> updateToConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
LogicalDatastoreType.CONFIGURATION));
assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationExternalIds);
assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationExternalIds);
List<T> updateToOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName));
if (updateFromTestCase.expectedValues != null) {
assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalExternalIds);
assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalExternalIds);
}
// DELETE
Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, bridgeIid));
Thread.sleep(OVSDB_UPDATE_TIMEOUT);
}
}
}
/*
* @see <code>SouthboundIT.generateBridgeExternalIdsTestCases()</code> for specific test case information
*/
@Test
public void testCRUDBridgeExternalIds() throws InterruptedException {
testCRUDBridge("BridgeExternalIds", new SouthboundBridgeExternalIdsBuilder(),
new BridgeExternalIdsSouthboundHelper());
}
@Test
public void testAddDeleteQos() throws InterruptedException {
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
OvsdbNodeAugmentation ovsdbNodeAugmentation;
Uri qosUri = new Uri("QOS-ROW");
List<String> 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
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);
}
private static class SouthboundQueuesExternalIdsHelper implements SouthboundQueueHelper<QueuesExternalIds> {
@Override
public void writeValues(QueuesBuilder builder, List<QueuesExternalIds> values) {
builder.setQueuesExternalIds(values);
}
@Override
public List<QueuesExternalIds> readValues(Queues queue) {
return queue.getQueuesExternalIds();
}
}
private static class SouthboundQueuesOtherConfigHelper implements SouthboundQueueHelper<QueuesOtherConfig> {
@Override
public void writeValues(QueuesBuilder builder, List<QueuesOtherConfig> values) {
builder.setQueuesOtherConfig(values);
}
@Override
public List<QueuesOtherConfig> readValues(Queues queue) {
return queue.getQueuesOtherConfig();
}
}
private interface SouthboundQueueHelper<T> {
void writeValues(QueuesBuilder builder, List<T> values);
List<T> 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<QosExternalIds> {
@Override
public void writeValues(QosEntriesBuilder builder, List<QosExternalIds> values) {
builder.setQosExternalIds(values);
}
@Override
public List<QosExternalIds> readValues(QosEntries qos) {
return qos.getQosExternalIds();
}
}
private static class SouthboundQosOtherConfigHelper implements SouthboundQosHelper<QosOtherConfig> {
@Override
public void writeValues(QosEntriesBuilder builder, List<QosOtherConfig> values) {
builder.setQosOtherConfig(values);
}
@Override
public List<QosOtherConfig> readValues(QosEntries qos) {
return qos.getQosOtherConfig();
}
}
private interface SouthboundQosHelper<T> {
void writeValues(QosEntriesBuilder builder, List<T> values);
List<T> 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 <T> void testCRUDQueue(
KeyValueBuilder<T> builder, String prefix, SouthboundQueueHelper<T> 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<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
for (SouthboundTestCase<T> 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<Queues> 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<T> 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<T> 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<T> 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<T> updateToOperationalValues =
helper.readValues(queueToOper);
assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
}
// DELETE handled by TestQueue
}
}
}
}
@Test
public void testCRUDQueueExternalIds() throws InterruptedException {
testCRUDQueue(new SouthboundQueuesExternalIdsBuilder(), "QueueExternalIds",
new SouthboundQueuesExternalIdsHelper());
}
@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<Queues> 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 <T> void testCRUDQos(
KeyValueBuilder<T> builder, String prefix, SouthboundQosHelper<T> 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<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
for (SouthboundTestCase<T> 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<QosEntries> 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<T> 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<T> 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<T> 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<T> updateToOperationalValues =
helper.readValues(qosToOper);
assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
}
// DELETE handled by TestQueue
}
}
}
}
@Test
public void testCRUDQosExternalIds() throws InterruptedException {
testCRUDQos(new SouthboundQosExternalIdsBuilder(), "QosExternalIds",
new SouthboundQosExternalIdsHelper());
}
@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<QosEntries> 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);
InstanceIdentifier<Queues> queue1Iid = testQueue1.getInstanceIdentifier();
OvsdbQueueRef queue1Ref = new OvsdbQueueRef(queue1Iid);
Queues operQueue2 = getQueue(new Uri("queue2"), ovsdbNodeAugmentation);
Assert.assertNotNull(operQueue2);
InstanceIdentifier<Queues> queue2Iid = testQueue2.getInstanceIdentifier();
OvsdbQueueRef queue2Ref = new OvsdbQueueRef(queue2Iid);
List<QueueList> queueList = new ArrayList<>();
queueList.add(new QueueListBuilder().setQueueNumber(new Long("1")).setQueueRef(queue1Ref).build());
queueList.add(new QueueListBuilder().setQueueNumber(new Long("2")).setQueueRef(queue2Ref).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<QueueList> operQueueList = operQos.getQueueList();
Assert.assertNotNull(operQueueList);
for (QueueList queueEntry : queueList) {
Assert.assertTrue(isQueueInList(operQueueList, queueEntry));
}
// DELETE one queue from queue list and check that one remains
KeyedInstanceIdentifier<QueueList, QueueListKey> qosQueueIid = qosIid
.child(QueueList.class, new QueueListKey(new Long("1")));
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.getQueueRef().equals(queue2Ref)) {
Assert.assertTrue(isQueueInList(operQueueList, queueEntry));
} else if (queueEntry.getQueueRef().equals(queue1Ref)) {
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());
}
}
private Boolean isQueueInList(List<QueueList> queueList, QueueList queue) {
for (QueueList queueEntry : queueList) {
if (queueEntry.getQueueNumber().equals(queue.getQueueNumber())&& queueEntry.getQueueRef().equals(queue.getQueueRef())) {
return true;
}
}
return false;
}
/**
* <p>
* 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.
* </p>
* <p>
* Instances of this class are immutable.
* </p>
*
* @param <T> The type of data used for the test case.
*/
private static final class SouthboundTestCase<T> {
private final String name;
private final List<T> inputValues;
private final List<T> 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<T> inputValues, final List<T> expectedValues) {
this.name = name;
this.inputValues = inputValues;
this.expectedValues = expectedValues;
}
}
/**
* Southbound test case builder.
*
* @param <T> The type of data used for the test case.
*/
private static final class SouthboundTestCaseBuilder<T> {
private String name;
private List<T> inputValues;
private List<T> 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<T> 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<T> 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<T> expectInputAsOutput() {
this.expectedValues = this.inputValues;
return this;
}
/**
* Indicates that no output should be expected.
*
* @return The builder.
*/
public SouthboundTestCaseBuilder<T> expectNoOutput() {
this.expectedValues = null;
return this;
}
/**
* Builds an immutable instance representing the test case.
*
* @return The test case.
*/
@SuppressWarnings("unchecked")
public SouthboundTestCase<T> build() {
return new SouthboundTestCase<>(name, inputValues, expectedValues);
}
}
private abstract static class KeyValueBuilder<T> {
private static final int COUNTER_START = 0;
private int counter = COUNTER_START;
protected abstract Builder<T> builder();
protected abstract void setKey(Builder<T> builder, String key);
protected abstract void setValue(Builder<T> builder, String value);
protected abstract boolean isValueMandatory();
public final T build(final String testName, final String key, final String value) {
final Builder<T> 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<QueuesExternalIds> {
@Override
protected Builder<QueuesExternalIds> builder() {
return new QueuesExternalIdsBuilder();
}
@Override
protected void setKey(Builder<QueuesExternalIds> builder, String key) {
((QueuesExternalIdsBuilder) builder).setQueuesExternalIdKey(key);
}
@Override
protected void setValue(Builder<QueuesExternalIds> builder, String value) {
((QueuesExternalIdsBuilder) builder).setQueuesExternalIdValue(value);
}
@Override
protected boolean isValueMandatory() {
return true;
}
}
private static final class SouthboundQueuesOtherConfigBuilder extends KeyValueBuilder<QueuesOtherConfig> {
@Override
protected Builder<QueuesOtherConfig> builder() {
return new QueuesOtherConfigBuilder();
}
@Override
protected void setKey(Builder<QueuesOtherConfig> builder, String key) {
((QueuesOtherConfigBuilder) builder).setQueueOtherConfigKey(key);
}
@Override
protected void setValue(Builder<QueuesOtherConfig> builder, String value) {
((QueuesOtherConfigBuilder) builder).setQueueOtherConfigValue(value);
}
@Override
protected boolean isValueMandatory() {
return false;
}
}
private static final class SouthboundQosExternalIdsBuilder extends KeyValueBuilder<QosExternalIds> {
@Override
protected Builder<QosExternalIds> builder() {
return new QosExternalIdsBuilder();
}
@Override
protected void setKey(Builder<QosExternalIds> builder, String key) {
((QosExternalIdsBuilder) builder).setQosExternalIdKey(key);
}
@Override
protected void setValue(Builder<QosExternalIds> builder, String value) {
((QosExternalIdsBuilder) builder).setQosExternalIdValue(value);
}
@Override
protected boolean isValueMandatory() {
return true;
}
}
private static final class SouthboundQosOtherConfigBuilder extends KeyValueBuilder<QosOtherConfig> {
@Override
protected Builder<QosOtherConfig> builder() {
return new QosOtherConfigBuilder();
}
@Override
protected void setKey(Builder<QosOtherConfig> builder, String key) {
((QosOtherConfigBuilder) builder).setOtherConfigKey(key);
}
@Override
protected void setValue(Builder<QosOtherConfig> builder, String value) {
((QosOtherConfigBuilder) builder).setOtherConfigValue(value);
}
@Override
protected boolean isValueMandatory() {
return false;
}
}
private static final class SouthboundPortExternalIdsBuilder extends KeyValueBuilder<PortExternalIds> {
@Override
protected Builder<PortExternalIds> builder() {
return new PortExternalIdsBuilder();
}
@Override
protected void setKey(Builder<PortExternalIds> builder, String key) {
((PortExternalIdsBuilder) builder).setExternalIdKey(key);
}
@Override
protected void setValue(Builder<PortExternalIds> builder, String value) {
((PortExternalIdsBuilder) builder).setExternalIdValue(value);
}
@Override
protected boolean isValueMandatory() {
return true;
}
}
private static final class SouthboundInterfaceExternalIdsBuilder extends KeyValueBuilder<InterfaceExternalIds> {
@Override
protected Builder<InterfaceExternalIds> builder() {
return new InterfaceExternalIdsBuilder();
}
@Override
protected void setKey(Builder<InterfaceExternalIds> builder, String key) {
((InterfaceExternalIdsBuilder) builder).setExternalIdKey(key);
}
@Override
protected void setValue(Builder<InterfaceExternalIds> builder, String value) {
((InterfaceExternalIdsBuilder) builder).setExternalIdValue(value);
}
@Override
protected boolean isValueMandatory() {
return true;
}
}
private static final class SouthboundInterfaceLldpBuilder extends KeyValueBuilder<InterfaceLldp> {
@Override
protected Builder<InterfaceLldp> builder() {
return new InterfaceLldpBuilder();
}
@Override
protected void setKey(Builder<InterfaceLldp> builder, String key) {
((InterfaceLldpBuilder) builder).setLldpKey((key));
}
@Override
protected void setValue(Builder<InterfaceLldp> builder, String value) {
((InterfaceLldpBuilder) builder).setLldpValue(value);
}
@Override
protected boolean isValueMandatory() {
return true;
}
}
private static final class SouthboundOptionsBuilder extends KeyValueBuilder<Options> {
@Override
protected Builder<Options> builder() {
return new OptionsBuilder();
}
@Override
protected void setKey(Builder<Options> builder, String key) {
((OptionsBuilder) builder).setOption(key);
}
@Override
protected void setValue(Builder<Options> builder, String value) {
((OptionsBuilder) builder).setValue(value);
}
@Override
protected boolean isValueMandatory() {
return false;
}
}
private static final class SouthboundInterfaceOtherConfigsBuilder extends KeyValueBuilder<InterfaceOtherConfigs> {
@Override
protected Builder<InterfaceOtherConfigs> builder() {
return new InterfaceOtherConfigsBuilder();
}
@Override
protected void setKey(Builder<InterfaceOtherConfigs> builder, String key) {
((InterfaceOtherConfigsBuilder) builder).setOtherConfigKey(key);
}
@Override
protected void setValue(Builder<InterfaceOtherConfigs> builder, String value) {
((InterfaceOtherConfigsBuilder) builder).setOtherConfigValue(value);
}
@Override
protected boolean isValueMandatory() {
return false;
}
}
private static final class SouthboundPortOtherConfigsBuilder extends KeyValueBuilder<PortOtherConfigs> {
@Override
protected Builder<PortOtherConfigs> builder() {
return new PortOtherConfigsBuilder();
}
@Override
protected void setKey(Builder<PortOtherConfigs> builder, String key) {
((PortOtherConfigsBuilder) builder).setOtherConfigKey(key);
}
@Override
protected void setValue(Builder<PortOtherConfigs> builder, String value) {
((PortOtherConfigsBuilder) builder).setOtherConfigValue(value);
}
@Override
protected boolean isValueMandatory() {
return false;
}
}
private static final class SouthboundBridgeOtherConfigsBuilder extends KeyValueBuilder<BridgeOtherConfigs> {
@Override
protected Builder<BridgeOtherConfigs> builder() {
return new BridgeOtherConfigsBuilder();
}
@Override
protected void setKey(Builder<BridgeOtherConfigs> builder, String key) {
((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigKey(key);
}
@Override
protected void setValue(Builder<BridgeOtherConfigs> builder, String value) {
((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigValue(value);
}
@Override
protected boolean isValueMandatory() {
return false;
}
}
private static final class SouthboundBridgeExternalIdsBuilder extends KeyValueBuilder<BridgeExternalIds> {
@Override
protected Builder<BridgeExternalIds> builder() {
return new BridgeExternalIdsBuilder();
}
@Override
protected void setKey(Builder<BridgeExternalIds> builder, String key) {
((BridgeExternalIdsBuilder) builder).setBridgeExternalIdKey(key);
}
@Override
protected void setValue(Builder<BridgeExternalIds> builder, String value) {
((BridgeExternalIdsBuilder) builder).setBridgeExternalIdValue(value);
}
@Override
protected boolean isValueMandatory() {
return true;
}
}
/*
* Generates the test cases involved in testing key-value-based data. See inline comments for descriptions of
* the particular cases considered.
*/
private static <T> List<SouthboundTestCase<T>> generateKeyValueTestCases(
KeyValueBuilder<T> builder, String testName) {
List<SouthboundTestCase<T>> testCases = new ArrayList<>();
final String GOOD_KEY = "GoodKey";
final String GOOD_VALUE = "GoodValue";
final String NO_VALUE_FOR_KEY = "NoValueForKey";
final String idKey = testName + "Key";
final String idValue = testName + "Value";
// 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<T>()
.name(testOneName)
.input(builder.build(testOneName, idKey, idValue))
.expectInputAsOutput()
.build());
builder.reset();
// 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<T>()
.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<T>()
.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<PortExternalIds> {
@Override
public void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<PortExternalIds> values) {
builder.setPortExternalIds(values);
}
@Override
public List<PortExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
return augmentation.getPortExternalIds();
}
}
private static class InterfaceExternalIdsSouthboundHelper implements
SouthboundTerminationPointHelper<InterfaceExternalIds> {
@Override
public void writeValues(
OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceExternalIds> values) {
builder.setInterfaceExternalIds(values);
}
@Override
public List<InterfaceExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
return augmentation.getInterfaceExternalIds();
}
}
private static class InterfaceLldpSouthboundHelper implements
SouthboundTerminationPointHelper<InterfaceLldp> {
@Override
public void writeValues(
OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceLldp> values) {
builder.setInterfaceLldp(values);
}
@Override
public List<InterfaceLldp> readValues(OvsdbTerminationPointAugmentation augmentation) {
return augmentation.getInterfaceLldp();
}
}
private static class OptionsSouthboundHelper implements SouthboundTerminationPointHelper<Options> {
@Override
public void writeValues(
OvsdbTerminationPointAugmentationBuilder builder, List<Options> values) {
builder.setOptions(values);
}
@Override
public List<Options> readValues(OvsdbTerminationPointAugmentation augmentation) {
return augmentation.getOptions();
}
}
private static class InterfaceOtherConfigsSouthboundHelper implements
SouthboundTerminationPointHelper<InterfaceOtherConfigs> {
@Override
public void writeValues(
OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceOtherConfigs> values) {
builder.setInterfaceOtherConfigs(values);
}
@Override
public List<InterfaceOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
return augmentation.getInterfaceOtherConfigs();
}
}
private static class PortOtherConfigsSouthboundHelper implements
SouthboundTerminationPointHelper<PortOtherConfigs> {
@Override
public void writeValues(
OvsdbTerminationPointAugmentationBuilder builder, List<PortOtherConfigs> values) {
builder.setPortOtherConfigs(values);
}
@Override
public List<PortOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
return augmentation.getPortOtherConfigs();
}
}
private static class BridgeExternalIdsSouthboundHelper implements SouthboundBridgeHelper<BridgeExternalIds> {
@Override
public void writeValues(
OvsdbBridgeAugmentationBuilder builder, List<BridgeExternalIds> values) {
builder.setBridgeExternalIds(values);
}
@Override
public List<BridgeExternalIds> readValues(OvsdbBridgeAugmentation augmentation) {
return augmentation.getBridgeExternalIds();
}
}
private static class BridgeOtherConfigsSouthboundHelper implements SouthboundBridgeHelper<BridgeOtherConfigs> {
@Override
public void writeValues(
OvsdbBridgeAugmentationBuilder builder, List<BridgeOtherConfigs> values) {
builder.setBridgeOtherConfigs(values);
}
@Override
public List<BridgeOtherConfigs> readValues(OvsdbBridgeAugmentation augmentation) {
return augmentation.getBridgeOtherConfigs();
}
}
}