package org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13;
+import com.google.common.util.concurrent.CheckedFuture;
+import java.math.BigInteger;
import java.util.Iterator;
import java.util.List;
+import java.util.StringTokenizer;
+
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
+import com.google.common.net.InetAddresses;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
-import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.PipelineOrchestrator;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
+import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
+import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI;
import org.opendaylight.sfc.sfc_ovs.provider.SfcOvsUtil;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.RspName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.RenderedServicePaths;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.path.first.hop.info.RenderedServicePathFirstHop;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePathKey;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.rendered.service.path.RenderedServicePathHop;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.Acl;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.Ace;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Actions;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Matches;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.actions.packet.handling.Deny;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.actions.packet.handling.Permit;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEth;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.RedirectToSfc;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.bridges.Bridge;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff;
+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.OvsdbTerminationPointAugmentation;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
/**
* Open vSwitch OpenFlow 1.3 Networking Provider for Netvirt SFC
* @author Arun Yerra
public class NetvirtSfcOF13Provider implements INetvirtSfcOF13Provider{
private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcOF13Provider.class);
private static final int DEFAULT_FLOW_PRIORITY = 32768;
+ private static final short TABLE_0_CLASSIFIER = 0;
+ //private static final short TABLE_1_L2FORWARD = 30;
+ //private static final short TABLE_2_L3FORWARD = 40;
+ private static final short TABLE_3_INGR_ACL = 50;
+ private static final String OPENFLOW = "openflow:";
+
+ public static final long REG_VALUE_FROM_LOCAL = 0x1L;
+ public static final long REG_VALUE_FROM_REMOTE = 0x2L;
+ public static final Class<? extends NxmNxReg> REG_FIELD = NxmNxReg0.class;
private volatile NodeCacheManager nodeCacheManager;
private volatile Southbound southbound;
- private MdsalUtils dbutils;
- private PipelineOrchestrator orchestrator;
+ private MdsalUtils mdsalUtils;
+ private DataBroker dataBroker;
+
+ // TBD:: Remove these constants after integrating with openstack.
+ //private static final String NETWORK_TYPE_VXLAN = "vxlan";
+ private static final String NETWORK_SEGMENT_ID = "10";
+ private static final String LOCAL_TP_ID = "vethl-h35_2";
+ private static final String INTERFACE_TYPE_VXLAN_GPE = "vxlangpe";
+ private static final String GPE_IFACE_ID = "sw1-vxlangpe-0";
/**
* {@link NetvirtSfcOF13Provider} constructor.
*/
public NetvirtSfcOF13Provider(final DataBroker dataBroker) {
Preconditions.checkNotNull(dataBroker, "Input dataBroker cannot be NULL!");
-
- //this.dataService = dataBroker;
- dbutils = new MdsalUtils(dataBroker);
-
+ this.dataBroker = dataBroker;
+ mdsalUtils = new MdsalUtils(dataBroker);
this.setDependencies(null);
}
// If a service function forwarder exists, then get the corresponding OVS Bridge details and Openflow NodeId.
// If OVS Bridge augmentation is configured, the following API returns NULL.
- String datapathId = SfcOvsUtil.getOpenFlowNodeIdForSff(serviceForwarder);
+ String datapathId = null;
+ Node node = null;
+ // TODO: Replace with OVSDB methods and not use the SFC API
+ datapathId = SfcOvsUtil.getOpenFlowNodeIdForSff(serviceForwarder);
if (datapathId == null) {
- LOG.debug("Service Function Forwarder = {} is not augemented with "
+ LOG.debug("Service Function Forwarder = {} is not augmented with "
+ "OVS Bridge Information. Skip processing!!", sff.getName());
}
// If openflow Node Id is NULL, get all the bridge nodes using southbound apis and fetch
// SFF with matching name. From this bridge name, get the openflow data path ID.
- if (datapathId == null) {
- Node node = null;
- final List<Node> nodes = nodeCacheManager.getBridgeNodes();
- if (nodes.isEmpty()) {
- LOG.debug("Noop with Classifier Creation on SFF={}. No Bridges configured YET!!", sff.getName());
- } else {
- for (Node dstNode : nodes) {
- LOG.debug("Processing Node={}, sff={}", dstNode.getNodeId().getValue(), sff.getName());
- if (dstNode.getNodeId().getValue().equalsIgnoreCase(sff.getName())) {
- LOG.debug("Found matching OVSDB Bridge Name!!= {}", dstNode.getNodeId().getValue());
- node = dstNode;
- break;
- }
- }
- }
+
+ node = getBridgeNode(serviceForwarder.getName().toString());
+ if (node == null) {
+ LOG.warn("Node doesn't exist for corresponding SFF={}", sff.getName());
+ return;
}
+ datapathId = getDpid(node);
LOG.debug("Processing the Classifier rules on Node={}", datapathId);
if (datapathId != null) {
// Program the OF flow on the corresponding open flow node.
Iterator<Ace> itr = acl.getAccessListEntries().getAce().iterator();
while (itr.hasNext()) {
Ace entry = itr.next();
- programOfRules(entry, datapathId, true);
+ processAclEntry(entry, node, true);
}
+ } else {
+ LOG.warn("Skipping ACL processing on Node={} as DatapathID is NULL!!", sff.getName());
}
}
- private void programOfRules(Ace entry, String datapathId, boolean write) {
- NodeBuilder nodeBuilder = new NodeBuilder();
- nodeBuilder.setId(new NodeId(Constants.OPENFLOW_NODE_PREFIX + datapathId));
- nodeBuilder.setKey(new NodeKey(nodeBuilder.getId()));
+ @Override
+ public void addClassifierRules(Bridge bridge, Acl acl) {
+ Preconditions.checkNotNull(bridge, "Input bridge cannot be NULL!");
+ Preconditions.checkNotNull(acl, "Input accesslist cannot be NULL!");
- //Create the match using match builder, by parsing the Accesslist Entry Match.
- MatchBuilder matchBuilder = null;
- matchBuilder = buildMatch(entry.getRuleName(), entry.getMatches(), datapathId);
+ Node bridgeNode = getBridgeNode(bridge.getName());
+ if (bridgeNode == null) {
+ LOG.debug("bridge {} not yet configured. Skip processing !!", bridge.getName());
+ return;
+ }
- InstructionsBuilder isb = null;
- isb = buildActions(entry.getRuleName(), entry.getActions(), datapathId);
+ // Program the OF flow on the corresponding open flow node.
+ for (Ace ace : acl.getAccessListEntries().getAce()) {
+ processAclEntry(ace, bridgeNode, true);
+ }
+ }
- String flowId = "NETVIRT_SFC_FLOW" + "_" + entry.getRuleName();
+ private void processAclEntry(Ace entry, Node srcNode, boolean write) {
+ RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
+ LOG.debug("Processing ACL entry = {} on Node = {} sfcRedirect = {}", entry.getRuleName(),
+ srcNode.getNodeId(), sfcRedirect);
+ if (sfcRedirect != null) {
+ // Given SFP find the corresponding RSP.
+ String sfcName = sfcRedirect.getRedirectSfc();
+ LOG.debug("Processing Redirect to SFC = {}", sfcRedirect.getRedirectSfc());
+ ServiceFunctionPath sfp = getSfp(sfcName);
+ if (sfp == null || sfp.getName() == null) {
+ LOG.warn("There is no configured SFP with sfcName = {}; so skip installing the ACL entry!!", sfcName);
+ return;
+ }
+ LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcRedirect.getRedirectSfc(), sfp);
+ // If RSP doesn't exist, create an RSP.
+ String sfpName = sfp.getName().getValue();
+ RenderedServicePath rsp = getRspforSfp(sfpName);
+ String rspName = sfp.getName().getValue() + "_rsp";
+ if (rsp == null) {
+ LOG.info("No configured RSP corresponding to SFP = {}, Creating new RSP = {}!!", sfpName, rspName);
+ // Create RSP.
+ CreateRenderedPathInput rspInput = new CreateRenderedPathInputBuilder()
+ .setParentServiceFunctionPath(sfpName)
+ .setName(rspName)
+ .setSymmetric(sfp.isSymmetric())
+ .build();
+ rsp = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, rspInput);
+ if (rsp == null) {
+ LOG.warn("failed to add RSP");
+ return;
+ }
+
+ // If SFP is symmetric, create RSP in the reverse direction.
+ if (sfp.isSymmetric()) {
+ LOG.info("SFP = {} is symmetric, installing RSP in the reverse direction!!", sfpName);
+ String rspNameRev = rspName + "-Reverse";
+ RenderedServicePath rspReverse = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
+ this.getRspId(rspNameRev));
+ if (rspReverse == null) {
+ rspReverse = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp);
+ }
+ }
+ }
+ LOG.info("rsp: {}", rsp);
+
+ // Find the first Hop within a RSP.
+ List<RenderedServicePathHop> pathHopList = rsp.getRenderedServicePathHop();
+ if (pathHopList.isEmpty()) {
+ LOG.info("Service Path = {} has empty hops!!", sfpName);
+ return;
+ }
+
+ RenderedServicePathFirstHop firstRspHop = SfcProviderRenderedPathAPI
+ .readRenderedServicePathFirstHop(new RspName(rspName));
+ //String firstSff = firstHop.getServiceFunctionForwarderLocator();
+
+ LOG.debug("First Hop IPAddress = {}, Port = {}", firstRspHop.getIp().getIpv4Address().getValue(),
+ firstRspHop.getPort().getValue().intValue());
+ OvsdbTerminationPointAugmentation tunnelPort = southbound
+ .getTerminationPointOfBridge(srcNode, GPE_IFACE_ID);
+ if (tunnelPort != null) {
+ long tunnelOfPort = southbound.getOFPort(tunnelPort);
+ LOG.debug("Tunnel Port = {}, OF Port Number = {}", tunnelPort.getName(), tunnelOfPort);
+ if (tunnelOfPort == 0) {
+ LOG.error("programTunnelRules: Could not Identify Tunnel port {} -> OF ({}) on {}",
+ tunnelPort.getName(), tunnelOfPort, srcNode);
+ return;
+ }
+ }
+
+ Matches match = entry.getMatches();
+
+ NshUtils header = new NshUtils();
+ // C1 is the normal overlay dest ip
+ header.setNshMetaC1(convertToLongIp(getDestIp(match)));
+ header.setNshMetaC2(Long.parseLong(NETWORK_SEGMENT_ID));
+ header.setNshNsp(rsp.getPathId());
+
+ RenderedServicePathHop firstHop = pathHopList.get(0);
+ header.setNshNsi(firstHop.getServiceIndex());
+ header.setNshTunIpDst(firstRspHop.getIp().getIpv4Address());
+ header.setNshTunUdpPort(firstRspHop.getPort());
+
+ LOG.debug("The Nsh Header = {}", header);
+ OvsdbTerminationPointAugmentation localPort = getTerminationPoint(srcNode, LOCAL_TP_ID);
+
+ /* String attachedMac = southbound.getInterfaceExternalIdsValue(localPort, Constants.EXTERNAL_ID_VM_MAC);
+ if (attachedMac == null) {
+ LOG.warn("No AttachedMac seen in {}", localPort);
+ // return;
+ }
+ */
+ LOG.debug("LocalPort ID={}, IP Address = {}", localPort.getName(), getSourceIp(match));
+ handleLocalInPort(southbound.getDataPathId(srcNode), TABLE_0_CLASSIFIER, TABLE_3_INGR_ACL,
+ NETWORK_SEGMENT_ID, localPort.getOfport(), getSourceIp(match), true);
+
+ // L2 Dst MAC forwarding flows.
+ // L2 Flood Flows.
+ // Set the Tunnel Destination IP, Dest MAC based on the destination IP address.
+ // Replace SMAC & decrement TTL.
+ // handleL3Flows(southbound.getDataPathId(srcNode), TABLE_1_ISOLATE_TENANT,
+ // TABLE_2_INGRESS_ACL, destIp, l3SegmentId, destMac);
+ // Set NSP & NSI values based on the Classifier Match actions.
+ OvsdbTerminationPointAugmentation outPort = getTerminationPoint(srcNode, INTERFACE_TYPE_VXLAN_GPE);
+ // TODO: commented out for test
+ //handleSfcClassiferFlows(entry.getRuleName(), srcNode, match,
+ // TABLE_3_INGR_ACL, header, outPort.getOfport(), true);
+ // Set NSHC1, NSHC2, Tunnel DestIP, port toward SFF1, output to Tunnel Port.
+
+ }
+ }
+
+ private OvsdbTerminationPointAugmentation getTerminationPoint(Node srcNode, String localTpId) {
+ List<OvsdbTerminationPointAugmentation> ports = southbound.extractTerminationPointAugmentations(srcNode);
+ if (ports != null && !ports.isEmpty()) {
+ for (OvsdbTerminationPointAugmentation port : ports) {
+ // TBD :: For Demo, use the Tunnel ID as 10. Once openstack is integrated,
+ // tunnel ID is created through Network Creation.
+ if (port.getName().contains(localTpId)) {
+ return port;
+ }
+ }
+ }
+ return null;
+ }
+
+ private String getTunnelName(String networkTypeVxlan, Ipv4Address ipv4Address) {
+ return networkTypeVxlan + "-" + ipv4Address.getValue();
+ }
+
+ /*
+ * (TABLE:50) EGRESS VM TRAFFIC TOWARDS TEP with NSH header
+ * MATCH: Match fields passed through ACL entry
+ * INSTRUCTION: SET TUNNELID AND GOTO TABLE TUNNEL TABLE (N)
+ * TABLE=0,IN_PORT=2,DL_SRC=00:00:00:00:00:01 \
+ * ACTIONS=SET_FIELD:5->TUN_ID,GOTO_TABLE=1"
+ */
+ private void handleSfcClassiferFlows(String ruleName, Node node, Matches match,
+ short table3IngrAcl, NshUtils header, long ofPort, boolean write) {
+ // Build the Actions to Add the NSH Header
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshC1Load =
+ NshUtils.nxLoadNshc1RegAction(header.getNshMetaC1());
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshC2Load =
+ NshUtils.nxLoadNshc2RegAction(header.getNshMetaC2());
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nspLoad =
+ NshUtils.nxSetNspAction(header.getNshNsp());
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nsiLoad =
+ NshUtils.nxSetNsiAction(header.getNshNsi());
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunVnid =
+ NshUtils.nxLoadTunIdAction(BigInteger.valueOf(header.getNshMetaC2()), false);
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunDest =
+ NshUtils.nxLoadTunIPv4Action(header.getNshTunIpDst().getValue(), false);
+
+ int count = 0;
+ List<Action> actionList = Lists.newArrayList();
+ actionList.add(new ActionBuilder().setOrder(Integer.valueOf(count++)).setAction(nshC1Load).build());
+ actionList.add(new ActionBuilder().setOrder(Integer.valueOf(count++)).setAction(nshC2Load).build());
+ actionList.add(new ActionBuilder().setOrder(Integer.valueOf(count++)).setAction(nspLoad).build());
+ actionList.add(new ActionBuilder().setOrder(Integer.valueOf(count++)).setAction(nsiLoad).build());
+ actionList.add(new ActionBuilder().setOrder(Integer.valueOf(count++)).setAction(loadChainTunDest).build());
+ actionList.add(new ActionBuilder().setOrder(Integer.valueOf(count++)).setAction(loadChainTunVnid).build());
+
+ ApplyActionsBuilder aab = new ApplyActionsBuilder();
+ aab.setAction(actionList);
+
+ InstructionBuilder ib = new InstructionBuilder();
+ ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+ ib.setOrder(0);
+ ib.setKey(new InstructionKey(0));
+
+ List<Instruction> instructions = Lists.newArrayList();
+ instructions.add(ib.build());
+
+ // Set the Output Port/Iface
+ InstructionUtils.createOutputPortInstructions(ib, southbound.getDataPathId(node), ofPort);
+ ib.setOrder(1);
+ ib.setKey(new InstructionKey(1));
+ instructions.add(ib.build());
+
+ // Add InstructionBuilder to the Instruction(s)Builder List
+ InstructionsBuilder isb = new InstructionsBuilder();
+ isb.setInstruction(instructions);
+
+ String flowId = "NETVIRT_SFC_FLOW" + "_" + ruleName + "_" + header.getNshNsp();
FlowBuilder flowBuilder = new FlowBuilder();
flowBuilder.setId(new FlowId(flowId));
FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setMatch(matchBuilder.build());
+
+ MatchBuilder mb = buildMatch(match);
+ flowBuilder.setMatch(mb.build());
flowBuilder.setPriority(DEFAULT_FLOW_PRIORITY);
flowBuilder.setBarrier(true);
- flowBuilder.setTableId(this.getTable());
+ flowBuilder.setTableId(table3IngrAcl);
flowBuilder.setKey(key);
flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
flowBuilder.setInstructions(isb.build());
+ if (write) {
+ writeFlow(flowBuilder, createNodeBuilder(node.getNodeId().getValue()));
+ } else {
+ removeFlow(flowBuilder, createNodeBuilder(node.getNodeId().getValue()));
+ }
+ }
+
+ /*
+ * (TABLE:0) EGRESS VM TRAFFIC TOWARDS TEP
+ * MATCH: DESTINATION ETHERNET ADDR AND OPENFLOW INPORT
+ * INSTRUCTION: SET TUNNELID AND GOTO TABLE TUNNEL TABLE (N)
+ * TABLE=0,IN_PORT=2,DL_SRC=00:00:00:00:00:01 \
+ * ACTIONS=SET_FIELD:5->TUN_ID,GOTO_TABLE=1"
+ */
+ private void handleLocalInPort(long dpidLong, short writeTable, short goToTableId,
+ String segmentationId, Long inPort, String sourceIp,
+ boolean write) {
+ programDropSrcIface(dpidLong, inPort, true);
+ programLocalInPort(dpidLong, segmentationId, inPort, sourceIp, goToTableId, write);
+ }
+
+ private String getDestIp(Matches match) {
+ if (match.getAceType() instanceof AceIp) {
+ AceIp aceIp = (AceIp)match.getAceType();
+ if (aceIp.getAceIpVersion() instanceof AceIpv4) {
+ AceIpv4 aceIpv4 = (AceIpv4) aceIp.getAceIpVersion();
+ if (aceIpv4.getDestinationIpv4Network() != null) {
+ String ipAddrPrefix = aceIpv4.getDestinationIpv4Network().getValue();
+ String ipAddr = new StringTokenizer(ipAddrPrefix, "/").nextToken();
+ return ipAddr;
+ }
+ }
+ }
+ return null;
+ }
+
+ private String getSourceIp(Matches match) {
+ if (match.getAceType() instanceof AceIp) {
+ AceIp aceIp = (AceIp)match.getAceType();
+ if (aceIp.getAceIpVersion() instanceof AceIpv4) {
+ AceIpv4 aceIpv4 = (AceIpv4) aceIp.getAceIpVersion();
+ if (aceIpv4.getSourceIpv4Network() != null) {
+ String ipAddrPrefix = aceIpv4.getSourceIpv4Network().getValue();
+ //String ipAddr = new StringTokenizer(ipAddrPrefix, "/").nextToken();
+ return ipAddrPrefix;
+ }
+ }
+ }
+ return null;
+ }
+
+ private long convertToLongIp(String ipaddr) {
+ LOG.debug("Converting String={} to Long", ipaddr);
+ return InetAddresses.coerceToInteger(InetAddresses.forString(ipaddr)) & 0xFFFFFFFFL;
+ }
+
+ private void programLocalInPort(Long dpidLong, String segmentationId, Long inPort,
+ String ipAddr, short goToTableId, boolean write) {
+ String nodeName = OPENFLOW + dpidLong;
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+ FlowBuilder flowBuilder = new FlowBuilder();
+
+ // Create the OF Match using MatchBuilder
+ //flowBuilder.setMatch(MatchUtils.createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build());
+ // TODO Broken In_Port Match
+ flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, inPort).build());
+ //flowBuilder.setMatch(MatchUtils.createSrcL3IPv4Match(matchBuilder, new Ipv4Prefix(ipAddr)).build());
+ String flowId = "LocalSfc_" + segmentationId + "_" + inPort;// + "_" + ipAddr.split("/",2)[0];
+ // Add Flow Attributes
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setStrict(true);
+ flowBuilder.setBarrier(false);
+ flowBuilder.setTableId((short)0);//getTable());
+ flowBuilder.setKey(key);
+ flowBuilder.setFlowName(flowId);
+ flowBuilder.setPriority(8192);
+ flowBuilder.setHardTimeout(0);
+ flowBuilder.setIdleTimeout(0);
+
+ if (write) {
+ // Instantiate the Builders for the OF Actions and Instructions
+ InstructionBuilder ib = new InstructionBuilder();
+ InstructionsBuilder isb = new InstructionsBuilder();
+
+ // Instructions List Stores Individual Instructions
+ List<Instruction> instructions = Lists.newArrayList();
+
+ // TODO Broken SetTunID
+ //InstructionUtils.createSetTunnelIdInstructions(ib, new BigInteger(segmentationId));
+ //ApplyActionsCase aac = (ApplyActionsCase) ib.getInstruction();
+ //List<Action> actionList = aac.getApplyActions().getAction();
+
+ //ActionBuilder ab = new ActionBuilder();
+ //ab.setAction(ActionUtils.nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(REG_FIELD).build(),
+ // BigInteger.valueOf(REG_VALUE_FROM_LOCAL)));
+ //ab.setOrder(1);
+ //ab.setKey(new ActionKey(1));
+
+ //actionList.add(ab.build());
+
+ //ib.setOrder(0);
+ //ib.setKey(new InstructionKey(0));
+ //instructions.add(ib.build());
+
+ // Next service GOTO Instructions Need to be appended to the List
+ ib = InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), goToTableId);
+ ib.setOrder(0);//1);
+ ib.setKey(new InstructionKey(0));//1));
+ instructions.add(ib.build());
+
+ // Add InstructionBuilder to the Instruction(s)Builder List
+ isb.setInstruction(instructions);
+
+ // Add InstructionsBuilder to FlowBuilder
+ flowBuilder.setInstructions(isb.build());
+
+ writeFlow(flowBuilder, nodeBuilder);
+ } else {
+ removeFlow(flowBuilder, nodeBuilder);
+ }
+ }
+
+ public void programDropSrcIface(Long dpidLong, Long inPort, boolean write) {
+
+ String nodeName = OPENFLOW + dpidLong;
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+ FlowBuilder flowBuilder = new FlowBuilder();
+
+ // Create the OF Match using MatchBuilder
+ flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, inPort).build());
+
+ if (write) {
+ // Instantiate the Builders for the OF Actions and Instructions
+ InstructionBuilder ib = new InstructionBuilder();
+ InstructionsBuilder isb = new InstructionsBuilder();
+
+ // Instructions List Stores Individual Instructions
+ List<Instruction> instructions = Lists.newArrayList();
+
+ // Call the InstructionBuilder Methods Containing Actions
+ InstructionUtils.createDropInstructions(ib);
+ ib.setOrder(0);
+ ib.setKey(new InstructionKey(0));
+ instructions.add(ib.build());
+
+ // Add InstructionBuilder to the Instruction(s)Builder List
+ isb.setInstruction(instructions);
+
+ // Add InstructionsBuilder to FlowBuilder
+ flowBuilder.setInstructions(isb.build());
+ }
+
+ String flowId = "DropFilter_"+inPort;
+ // Add Flow Attributes
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setStrict(true);
+ flowBuilder.setBarrier(false);
+ flowBuilder.setTableId((short)50);//getTable());
+ flowBuilder.setKey(key);
+ flowBuilder.setFlowName(flowId);
+ flowBuilder.setPriority(8192);
+ flowBuilder.setHardTimeout(0);
+ flowBuilder.setIdleTimeout(0);
if (write) {
writeFlow(flowBuilder, nodeBuilder);
} else {
}
}
+ private Node getBridgeNode(String bridgeName) {
+ //SffOvsBridgeAugmentation sffBridge = sff.getAugmentation(SffOvsBridgeAugmentation.class);
+ //String brName = sffBridge.getOvsBridge().getBridgeName();
+
+ final List<Node> nodes = nodeCacheManager.getBridgeNodes();
+ if (nodes.isEmpty()) {
+ LOG.debug("Noop with Classifier Creation on SFF={}. No Bridges configured YET!!", bridgeName);
+ } else {
+ for (Node node : nodes) {
+ OvsdbBridgeAugmentation bridgeAugmentation = southbound.extractBridgeAugmentation(node);
+ if (bridgeAugmentation != null) {
+ if (bridgeAugmentation.getBridgeName().getValue().equalsIgnoreCase(bridgeName)) {
+ LOG.info("Found matching OVSDB Bridge Name {}", node.getNodeId().getValue());
+ return node;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+/*
private InstructionsBuilder buildActions(String ruleName, Actions actions, String datapathId) {
InstructionBuilder ib = new InstructionBuilder();
InstructionsBuilder isb = new InstructionsBuilder();
isb.setInstruction(instructions);
return isb;
+ }*/
+
+ private ServiceFunctionPath getSfp(String redirectSfc) {
+ ServiceFunctionPaths sfps = SfcProviderServicePathAPI.readAllServiceFunctionPaths();
+ if (sfps != null) {
+ for (ServiceFunctionPath sfp: sfps.getServiceFunctionPath()) {
+ if (sfp.getServiceChainName().getValue().equalsIgnoreCase(redirectSfc)) {
+ return sfp;
+ }
+ }
+ }
+ return null;
+ }
+
+ private RenderedServicePath getRspforSfp(String sfpName) {
+ RenderedServicePaths rsps = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, this.getRspsId());
+ if (rsps == null) {
+ LOG.debug("RSP has not been configured yet for SFP = {}", sfpName);
+ return null;
+ }
+ for (RenderedServicePath rsp : rsps.getRenderedServicePath()) {
+ if (rsp.getParentServiceFunctionPath() != null) {
+ if (rsp.getParentServiceFunctionPath().getValue().equalsIgnoreCase(sfpName)) {
+ return rsp;
+ }
+ }
+ }
+ return null;
}
- private MatchBuilder buildMatch(String ruleName, Matches matches, String dpId) {
+ private MatchBuilder buildMatch(Matches matches) {
MatchBuilder matchBuilder = new MatchBuilder();
if (matches.getAceType() instanceof AceIp) {
if (aceIp.getAceIpVersion() instanceof AceIpv4) {
AceIpv4 aceIpv4 = (AceIpv4) aceIp.getAceIpVersion();
MatchUtils.createSrcL3IPv4Match(matchBuilder, aceIpv4.getSourceIpv4Network());
- MatchUtils.createDstL3IPv4Match(matchBuilder, aceIpv4.getDestinationIpv4Network());
- MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
+ //MatchUtils.createDstL3IPv4Match(matchBuilder, aceIpv4.getDestinationIpv4Network());
+ //MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
MatchUtils.addLayer4Match(matchBuilder, aceIp.getProtocol().intValue(),
- aceIp.getSourcePortRange().getLowerPort().getValue().intValue(),
+ 0,
aceIp.getDestinationPortRange().getLowerPort().getValue().intValue());
}
} else if (matches.getAceType() instanceof AceEth) {
@Override
public void removeClassifierRules(Sff sff, Acl acl) {
// TODO Auto-generated method stub
-
}
-
+ /*
protected void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
LOG.debug("writeFlow: flowBuilder: {}, nodeBuilder: {}",
flowBuilder.build(), nodeBuilder.build());
- dbutils.merge(LogicalDatastoreType.CONFIGURATION, createNodePath(nodeBuilder), nodeBuilder.build());
- dbutils.put(LogicalDatastoreType.CONFIGURATION, createFlowPath(flowBuilder, nodeBuilder), flowBuilder.build());
+ mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, createNodePath(nodeBuilder), nodeBuilder.build());
+ mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, createFlowPath(flowBuilder, nodeBuilder), flowBuilder.build());
+ }
+*/
+ protected void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
+ LOG.debug("writeFlow: flowBuilder: {}, nodeBuilder: {}",
+ flowBuilder.build(), nodeBuilder.build());
+ WriteTransaction modification = dataBroker.newWriteOnlyTransaction();
+ modification.put(LogicalDatastoreType.CONFIGURATION, createNodePath(nodeBuilder),
+ nodeBuilder.build(), true /*createMissingParents*/);
+ modification.put(LogicalDatastoreType.CONFIGURATION, createFlowPath(flowBuilder, nodeBuilder),
+ flowBuilder.build(), true /*createMissingParents*/);
+
+ CheckedFuture<Void, TransactionCommitFailedException> commitFuture = modification.submit();
+ try {
+ commitFuture.get(); // TODO: Make it async (See bug 1362)
+ LOG.debug("Transaction success for write of Flow {}", flowBuilder.getFlowName());
+ } catch (Exception e) {
+ LOG.error(e.getMessage(), e);
+ modification.cancel();
+ }
}
protected void removeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
- dbutils.delete(LogicalDatastoreType.CONFIGURATION, createFlowPath(flowBuilder, nodeBuilder));
+ mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, createFlowPath(flowBuilder, nodeBuilder));
}
private String getDpid(Node node) {
nodeBuilder.getKey()).build();
}
- private short getTable() {
- return Service.INGRESS_ACL.getTable();
+ private NodeBuilder createNodeBuilder(String nodeId) {
+ NodeBuilder builder = new NodeBuilder();
+ builder.setId(new NodeId(nodeId));
+ builder.setKey(new NodeKey(builder.getId()));
+ return builder;
}
- private final InstructionBuilder getMutablePipelineInstructionBuilder() {
- Service nextService = orchestrator.getNextServiceInPipeline(Service.INGRESS_ACL);
- if (nextService != null) {
- return InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), nextService.getTable());
- } else {
- return InstructionUtils.createDropInstructions(new InstructionBuilder());
- }
+ private InstanceIdentifier<RenderedServicePaths> getRspsId() {
+ return InstanceIdentifier.builder(RenderedServicePaths.class).build();
+ }
+
+ private InstanceIdentifier<RenderedServicePath> getRspId(String rspName) {
+ return InstanceIdentifier.builder(RenderedServicePaths.class)
+ .child(RenderedServicePath.class, new RenderedServicePathKey(new RspName(rspName))).build();
+ }
+
+ private short getTable() {
+ return Service.INGRESS_ACL.getTable();
}
private void setDependencies(ServiceReference serviceReference) {
nodeCacheManager = (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
- orchestrator = (PipelineOrchestrator) ServiceHelper.getGlobalInstance(PipelineOrchestrator.class, this);
}
}
import com.google.common.collect.Sets;
import java.io.File;
-import java.lang.reflect.Array;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
private static final Logger LOG = LoggerFactory.getLogger(SouthboundIT.class);
private static final int OVSDB_UPDATE_TIMEOUT = 1000;
private static final String FORMAT_STR = "%s_%s_%d";
- public static final int NUM_THREADS = 1;
private static String addressStr;
private static int portNumber;
private static String connectionType;
@Override
public void setup() throws InterruptedException {
if (setup) {
- LOG.info("Skipping setUp, already initialized");
+ LOG.info("Skipping setup, already initialized");
return;
}
}
private boolean addOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
- InstanceIdentifier<Node> iid = createInstanceIdentifier(connectionInfo);
- // Check that the node doesn't already exist (we don't support connecting twice)
- Assert.assertNull("The OVSDB node has already been added",
- mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, iid));
boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
- iid,
+ createInstanceIdentifier(connectionInfo),
createNode(connectionInfo));
Thread.sleep(OVSDB_UPDATE_TIMEOUT);
return result;
Assert.assertTrue(deleteOvsdbNode(connectionInfo));
Node node = getOvsdbNode(connectionInfo);
Assert.assertNull(node);
+ //Assume.assumeNotNull(node); // Using assumeNotNull because there is no assumeNull
LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
return true;
}
@Test
public void testOvsdbBridgeControllerInfo() throws InterruptedException {
- ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
+ ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portNumber);
Node ovsdbNode = connectOvsdbNode(connectionInfo);
String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
assertNotNull("Failed to get controller target", controllerTarget);
* @param setManagedBy toggles whether to setManagedBy for the bridge
* @param dpType if passed null, this parameter is ignored
* @param externalIds if passed null, this parameter is ignored
- * @param otherConfig if passed null, this parameter is ignored
+ * @param otherConfigs if passed null, this parameter is ignored
* @return success of bridge addition
* @throws InterruptedException
*/
* @return the augmentation (or {@code null} if none)
*/
private OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation(
- ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index ) {
+ ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index) {
List<TerminationPoint> tpList = getBridgeNode(connectionInfo, bridgeName, store).getTerminationPoint();
if (tpList == null) {
Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
}
- private interface KeyValueBuilder<T> {
- T build(String testName, String key, String value);
- T[] build(String testName, int count, String key, String value);
- void reset();
- }
-
- /**
- * Find the real type arguments for the given class (in its hierarchy), with at least {@code nb} arguments.
- *
- * @param clazz The class to start with.
- * @param nb The minimum number of type arguments.
- * @param <T> The type of the starting class.
- * @return The matching type arguments (a {@link RuntimeException} is thrown if none match).
+ /*
+ * @see <code>SouthboundIT.testCRUDPortExternalIds()</code>
+ * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
*/
- private static <T> Type[] findTypeArguments(final Class<T> clazz, final int nb) {
- if (clazz == null || clazz.getSuperclass() == null) {
- throw new RuntimeException("Missing type parameters");
- }
- Type superClassType = clazz.getGenericSuperclass();
- if (superClassType instanceof ParameterizedType && ((ParameterizedType) superClassType)
- .getActualTypeArguments().length >= nb) {
- return ((ParameterizedType) superClassType).getActualTypeArguments();
- }
- return findTypeArguments(clazz.getSuperclass(), nb);
- }
-
- private abstract static class BaseKeyValueBuilder<T> implements KeyValueBuilder<T> {
- private static final int COUNTER_START = 0;
- private int counter = COUNTER_START;
- @SuppressWarnings("unchecked")
- private final Class<T> builtClass = (Class<T>) findTypeArguments(getClass(), 1)[0];
-
- protected abstract Builder<T> builder();
-
- protected abstract void setKey(Builder<T> builder, String key);
-
- protected abstract void setValue(Builder<T> builder, String value);
-
- @Override
- 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();
- }
+ private void assertExpectedPortExternalIdsExist( List<PortExternalIds> expected,
+ List<PortExternalIds> test ) {
- @SuppressWarnings("unchecked")
- @Override
- public final T[] build(final String testName, final int count, final String key, final String value) {
- final T[] instances = (T[]) Array.newInstance(builtClass, count);
- for (int idx = 0; idx < count; idx++) {
- try {
- instances[idx] = build(testName, key, value);
- } catch (ArrayStoreException e) {
- LOG.error("Error storing a value; we think we're managing {}", builtClass, e);
- throw e;
- }
+ if (expected != null) {
+ for (PortExternalIds expectedExternalId : expected) {
+ Assert.assertTrue("The retrieved ids don't contain " + expectedExternalId,
+ test.contains(expectedExternalId));
}
- return instances;
- }
-
- @Override
- public final void reset() {
- this.counter = COUNTER_START;
- }
- }
-
- private static final class SouthboundPortExternalIdsBuilder extends BaseKeyValueBuilder<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);
- }
- }
-
- private static final class SouthboundInterfaceExternalIdsBuilder extends BaseKeyValueBuilder<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);
- }
- }
-
- private static final class SouthboundOptionsBuilder extends BaseKeyValueBuilder<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);
- }
- }
-
- private static final class SouthboundInterfaceOtherConfigsBuilder extends BaseKeyValueBuilder<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);
- }
- }
-
- private static final class SouthboundPortOtherConfigsBuilder extends BaseKeyValueBuilder<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);
- }
- }
-
- private static final class SouthboundBridgeOtherConfigsBuilder extends BaseKeyValueBuilder<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);
- }
- }
-
- private static final class SouthboundBridgeExternalIdsBuilder extends BaseKeyValueBuilder<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);
- }
- }
-
- /*
- * 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 idKey, String idValue) {
- 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 NO_KEY_FOR_VALUE = "NoKeyForValue";
-
- // 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";
- 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";
- testCases.add(new SouthboundTestCaseBuilder<T>()
- .name(testFiveName)
- .input(builder.build(testFiveName, 5, idKey, idValue))
- .expectInputAsOutput()
- .build());
- builder.reset();
-
- // 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";
- testCases.add(new SouthboundTestCaseBuilder<T>()
- .name(testOneGoodOneMalformedValueName)
- .input(
- builder.build(testOneGoodOneMalformedValueName, GOOD_KEY, GOOD_VALUE),
- builder.build(testOneGoodOneMalformedValueName, NO_VALUE_FOR_KEY, null)
- )
- .expect()
- .build());
- builder.reset();
-
- // Test Case 4: TestOneGoodOneMalformedKey
- // Test Type: Negative
- // Description:
- // One perfectly fine input
- // (TestOneGoodOneMalformedKey_GoodKey_1,
- // TestOneGoodOneMalformedKey_GoodValue_1)
- // and one malformed input which only has value specified
- // (UNSPECIFIED,
- // TestOneGoodOneMalformedKey_NoKeyForValue_2)
- // Expected: A port is created without any values
- final String testOneGoodOneMalformedKeyName = "TestOneGoodOneMalformedKey";
- testCases.add(new SouthboundTestCaseBuilder<T>()
- .name(testOneGoodOneMalformedKeyName)
- .input(
- builder.build(testOneGoodOneMalformedKeyName, GOOD_KEY, GOOD_VALUE),
- builder.build(testOneGoodOneMalformedKeyName, null, NO_KEY_FOR_VALUE)
- )
- .expect()
- .build());
- builder.reset();
-
- return testCases;
- }
-
- /*
- * Generates the test cases involved in testing PortExternalIds. See inline comments for descriptions of
- * the particular cases considered.
- */
- private List<SouthboundTestCase<PortExternalIds>> generatePortExternalIdsTestCases() {
- return generateKeyValueTestCases(new SouthboundPortExternalIdsBuilder(), "PortExternalIdKey",
- "PortExternalIdValue");
}
/*
- * Tests the CRUD operations for <code>Port</code>
- * <code>external_ids</code>.
+ * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
*
- * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for
- * specific test case information
+ * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
*/
@Test
- public void testCRUDTerminationPointPortExternalIds()
- throws InterruptedException, ExecutionException {
-
+ public void testCRUDTerminationPointPortExternalIds() throws InterruptedException {
final String TEST_PREFIX = "CRUDTPPortExternalIds";
+ final int TERMINATION_POINT_TEST_INDEX = 0;
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
connectOvsdbNode(connectionInfo);
- // updateFromTestCases represent the original test case value.
- // updateToTestCases represent the new value after the update has been
- // performed.
- List<SouthboundTestCase<PortExternalIds>> updateFromTestCases = generatePortExternalIdsTestCases();
- List<SouthboundTestCase<PortExternalIds>> updateToTestCases = generatePortExternalIdsTestCases();
- String testBridgeName;
- String testPortName;
-
- int counter = 1;
- // multihreads the test using NUM_THREADS
- ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
- for (SouthboundTestCase<PortExternalIds> fromTestCase : updateFromTestCases) {
- for (SouthboundTestCase<PortExternalIds> toTestCase : updateToTestCases) {
- testPortName = testBridgeName = String.format(FORMAT_STR,
- TEST_PREFIX, toTestCase.name, counter);
- counter += 1;
- executor.submit(new TestCRUDTerminationPointRunnable<>(
- new SouthboundTestHelper<PortExternalIds>() {
- @Override
- public List<PortExternalIds> readValues(
- OvsdbTerminationPointAugmentation augmentation) {
- return augmentation.getPortExternalIds();
- }
-
- @Override
- public void writeValues(
- OvsdbTerminationPointAugmentationBuilder augmentationBuilder,
- List<PortExternalIds> updateFromInput) {
- augmentationBuilder.setPortExternalIds(updateFromInput);
- }
- },
- connectionInfo, testBridgeName, testPortName,
- fromTestCase.inputValues,
- fromTestCase.expectedValues,
- toTestCase.inputValues,
- toTestCase.expectedValues));
- }
- }
- executor.shutdown();
- executor.awaitTermination(5, TimeUnit.MINUTES);
- Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
- }
-
- /**
- * Southbound test helper. Classes implementing this interface are used to provide concrete access to the input and
- * output of the underlying augmentation for the type being managed.
- *
- * @param <T> The type of data used for the test case.
- */
- private interface SouthboundTestHelper<T> {
- /**
- * Read the values from the augmentation. These would usually be checked against the expected values provided
- * for the test case.
- *
- * @param augmentation The augmentation to read from.
- * @return The values read.
- */
- List<T> readValues(OvsdbTerminationPointAugmentation augmentation);
-
- /**
- * Write the values to the augmentation (via its builder). This would usually be used to apply the input values
- * provided for the test case.
- *
- * @param augmentationBuilder The augmentation builder.
- * @param values The values to write.
- */
- void writeValues(OvsdbTerminationPointAugmentationBuilder augmentationBuilder, List<T> values);
- }
-
- /**
- * <p>
- * Test runner used to apply a suite of create/read/update/delete tests. Each instance of a runner expects:
- * </p>
- * <ul>
- * <li>a helper used to manipulate the appropriate data structures in the termination point augmentation (see
- * {@link SouthboundTestHelper});</li>
- * <li>connection information for the southbound;</li>
- * <li>a name to use for the test bridge (this allows multiple tests to be conducted in parallel against different
- * bridges);</li>
- * <li>a name to use for the test port;</li>
- * <li>the initial input values to use for the termination point augmentation;</li>
- * <li>the initial expected values to check the augmentation against;</li>
- * <li>the target input values to update the terminal point to;</li>
- * <li>the target expected values to check the augmentation point against.</li>
- * </ul>
- * <p>The following tests are performed:</p>
- * <ol>
- * <li>the bridge is added;</li>
- * <li>the termination point is added, with the provided initial input values;</li>
- * <li>the termination point is read from the <em>configuration</em> data store, and checked against the provided
- * initial expected values;</li>
- * <li>the termination point is read from the <em>operational</em> data store, and checked against the provided
- * initial expected values;</li>
- * <li>the termination point is updated by merging the provided target input values;</li>
- * <li>the termination point is read from the <em>configuration</em> data store, and checked against the provided
- * initial <b>and</b> target expected values;</li>
- * <li>the termination point is read from the <em>operational</em> data store, and checked against the provided
- * initial <b>and</b> target expected values;</li>
- * <li>the bridge is deleted.</li>
- * </ol>
- *
- * @param <T> The type of data used for the test case.
- */
- private final class TestCRUDTerminationPointRunnable<T> implements Runnable {
- private final SouthboundTestHelper<T> helper;
- private final ConnectionInfo connectionInfo;
- private final String testBridgeName;
- private final String testPortName;
- private final List<T> updateFromInput;
- private final List<T> updateFromExpected;
- private final List<T> updateToInput;
- private final List<T> updateToExpected;
-
- private TestCRUDTerminationPointRunnable(
- SouthboundTestHelper<T> helper, ConnectionInfo connectionInfo, String testBridgeName,
- String testPortName, List<T> updateFromInput, List<T> updateFromExpected, List<T> updateToInput,
- List<T> updateToExpected) {
- this.helper = helper;
- this.connectionInfo = connectionInfo;
- this.testBridgeName = testBridgeName;
- this.testPortName = testPortName;
- this.updateFromInput = updateFromInput;
- this.updateFromExpected = updateFromExpected;
- this.updateToInput = updateToInput;
- this.updateToExpected = updateToExpected;
- }
+ // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
+ // the update has been performed.
+ List<SouthboundTestCase<PortExternalIds>> updateFromTestCases =
+ generateKeyValueTestCases(new SouthboundPortExternalIdsBuilder(), "PortExternalIdsFrom");
+ List<SouthboundTestCase<PortExternalIds>> updateToTestCases =
+ generateKeyValueTestCases(new SouthboundPortExternalIdsBuilder(), "PortExternalIdsTo");
+
+ for (SouthboundTestCase<PortExternalIds> updateFromTestCase : updateFromTestCases) {
+ List<PortExternalIds> updateFromInputExternalIds = updateFromTestCase.inputValues;
+ List<PortExternalIds> updateFromExpectedExternalIds = updateFromTestCase.expectedValues;
+ for (SouthboundTestCase<PortExternalIds> updateToTestCase : updateToTestCases) {
+ String testBridgeAndPortName = String.format("%s_%s", TEST_PREFIX, updateToTestCase.name);
+ List<PortExternalIds> updateToInputExternalIds = updateToTestCase.inputValues;
+ List<PortExternalIds> updateToExpectedExternalIds = updateToTestCase.expectedValues;
- @Override
- public void run() {
- try {
- final int TERMINATION_POINT_TEST_INDEX = 0;
// CREATE: Create the test bridge
- Assert.assertTrue(addBridge(connectionInfo, null,
- testBridgeName, null, true,
- SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
- true, null, null, null, null));
+ Assert.assertTrue(addBridge(connectionInfo, null, testBridgeAndPortName, null, true,
+ SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null));
NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
- connectionInfo, new OvsdbBridgeName(testBridgeName)));
+ connectionInfo, new OvsdbBridgeName(testBridgeAndPortName)));
OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
createGenericOvsdbTerminationPointAugmentationBuilder();
- tpCreateAugmentationBuilder.setName(testPortName);
- helper.writeValues(tpCreateAugmentationBuilder, updateFromInput);
- Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
+ tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
+ tpCreateAugmentationBuilder.setPortExternalIds(updateFromInputExternalIds);
+ 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, testBridgeName,
+ getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
- List<T> updateFromConfiguration = null;
if (updateFromConfigurationTerminationPointAugmentation != null) {
- updateFromConfiguration =
- helper.readValues(updateFromConfigurationTerminationPointAugmentation);
- }
- if (updateFromConfiguration != null) {
- Assert.assertTrue(updateFromConfiguration.containsAll(updateFromExpected));
+ List<PortExternalIds> updateFromConfigurationExternalIds =
+ updateFromConfigurationTerminationPointAugmentation.getPortExternalIds();
+ assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds,
+ updateFromConfigurationExternalIds);
}
OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
- getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
+ getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
- List<T> updateFromOperational = null;
if (updateFromOperationalTerminationPointAugmentation != null) {
- updateFromOperational = helper.readValues(updateFromOperationalTerminationPointAugmentation);
- }
- if (updateFromOperational != null) {
- Assert.assertTrue(updateFromOperational.containsAll(updateFromExpected));
+ List<PortExternalIds> updateFromOperationalExternalIds =
+ updateFromOperationalTerminationPointAugmentation.getPortExternalIds();
+ assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateFromOperationalExternalIds);
}
// UPDATE: update the external_ids
- testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
+ testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
new OvsdbTerminationPointAugmentationBuilder();
- helper.writeValues(tpUpdateAugmentationBuilder, updateToInput);
+ tpUpdateAugmentationBuilder.setPortExternalIds(updateToInputExternalIds);
InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
NodeId portUpdateNodeId = createManagedNodeId(portIid);
portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
- tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
+ tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
tpUpdateBuilder.addAugmentation(
OvsdbTerminationPointAugmentation.class,
tpUpdateAugmentationBuilder.build());
portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
- boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
- portIid, portUpdateNodeBuilder.build());
+ Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
+ portIid, portUpdateNodeBuilder.build()));
Thread.sleep(OVSDB_UPDATE_TIMEOUT);
- Assert.assertTrue(result);
// READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
// then repeat for OPERATIONAL data store
OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
- getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
+ getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
- List<T> updateToConfiguration = helper.readValues(updateToConfigurationTerminationPointAugmentation);
- Assert.assertTrue(updateToConfiguration.containsAll(updateToExpected));
- Assert.assertTrue(updateToConfiguration.containsAll(updateFromExpected));
+ if (updateToConfigurationTerminationPointAugmentation != null) {
+ List<PortExternalIds> updateToConfigurationExternalIds =
+ updateToConfigurationTerminationPointAugmentation.getPortExternalIds();
+ assertExpectedPortExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
+ assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateToConfigurationExternalIds);
+ }
OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
- getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
+ getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
- List<T> updateToOperational = helper.readValues(updateToOperationalTerminationPointAugmentation);
- Assert.assertTrue(updateToOperational.containsAll(updateToExpected));
- Assert.assertTrue(updateToOperational.containsAll(updateFromExpected));
+ if (updateToOperationalTerminationPointAugmentation != null) {
+ List<PortExternalIds> updateToOperationalExternalIds =
+ updateToOperationalTerminationPointAugmentation.getPortExternalIds();
+ if (updateFromExpectedExternalIds != null ) {
+ assertExpectedPortExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds);
+ assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds,
+ updateToOperationalExternalIds);
+ }
+ // testCRUDTerminationPointInterfaceExternalIds()'s null assertion of updateToOperationalExternalIds
+ // fails here
+ }
// DELETE
- Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
- } catch (InterruptedException e) {
- LOG.error("Test interrupted", e);
+ Assert.assertTrue(deleteBridge(connectionInfo, testBridgeAndPortName));
}
}
+ Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
}
-
/*
- * Generates the test cases involved in testing InterfaceExternalIds. See inline comments for descriptions of
- * the particular cases considered.
+ * @see <code>SouthboundIT.testCRUDInterfaceExternalIds()</code>
+ * This is helper test method to compare a test "set" of InterfaceExternalIds against an expected "set"
*/
- private static List<SouthboundTestCase<InterfaceExternalIds>> generateInterfaceExternalIdsTestCases() {
- return generateKeyValueTestCases(new SouthboundInterfaceExternalIdsBuilder(), "IntExternalIdKey",
- "IntExternalIdValue");
+ private void assertExpectedInterfaceExternalIdsExist( List<InterfaceExternalIds> expected,
+ List<InterfaceExternalIds> test ) {
+
+ if (expected != null) {
+ for (InterfaceExternalIds expectedExternalId : expected) {
+ Assert.assertTrue(test.contains(expectedExternalId));
+ }
+ }
}
/*
* @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
*/
@Test
- public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException, ExecutionException {
+ public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException {
final String TEST_PREFIX = "CRUDTPInterfaceExternalIds";
+ final int TERMINATION_POINT_TEST_INDEX = 0;
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
connectOvsdbNode(connectionInfo);
// updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
// the update has been performed.
- List<SouthboundTestCase<InterfaceExternalIds>> updateFromTestCases = generateInterfaceExternalIdsTestCases();
- List<SouthboundTestCase<InterfaceExternalIds>> updateToTestCases = generateInterfaceExternalIdsTestCases();
- String testBridgeName;
- String testPortName;
-
- int counter = 1;
- // multithreads the test using NUM_THREADS
- ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
- for (SouthboundTestCase<InterfaceExternalIds> fromTestCase : updateFromTestCases) {
- for (SouthboundTestCase<InterfaceExternalIds> toTestCase : updateToTestCases) {
- testPortName = testBridgeName = String.format(FORMAT_STR,
- TEST_PREFIX, toTestCase.name, counter);
- counter += 1;
- executor.submit(new TestCRUDTerminationPointRunnable<>(
- new SouthboundTestHelper<InterfaceExternalIds>() {
- @Override
- public List<InterfaceExternalIds> readValues(
- OvsdbTerminationPointAugmentation augmentation) {
- return augmentation.getInterfaceExternalIds();
- }
-
- @Override
- public void writeValues(
- OvsdbTerminationPointAugmentationBuilder augmentationBuilder,
- List<InterfaceExternalIds> values) {
- augmentationBuilder.setInterfaceExternalIds(values);
- }
- },
- connectionInfo, testBridgeName, testPortName,
- fromTestCase.inputValues,
- fromTestCase.expectedValues,
- toTestCase.inputValues,
- toTestCase.expectedValues));
+ List<SouthboundTestCase<InterfaceExternalIds>> updateFromTestCases = generateKeyValueTestCases(
+ new SouthboundInterfaceExternalIdsBuilder(), "InterfaceExternalIdsFrom");
+ List<SouthboundTestCase<InterfaceExternalIds>> updateToTestCases = generateKeyValueTestCases(
+ new SouthboundInterfaceExternalIdsBuilder(), "InterfaceExternalIdsTo");
+
+ for (SouthboundTestCase<InterfaceExternalIds> updateFromTestCase : updateFromTestCases) {
+ List<InterfaceExternalIds> updateFromInputExternalIds = updateFromTestCase.inputValues;
+ List<InterfaceExternalIds> updateFromExpectedExternalIds = updateFromTestCase.expectedValues;
+ for (SouthboundTestCase<InterfaceExternalIds> updateToTestCase : updateToTestCases) {
+ String testBridgeAndPortName = String.format("%s_%s", TEST_PREFIX, updateToTestCase.name);
+ List<InterfaceExternalIds> updateToInputExternalIds = updateToTestCase.inputValues;
+ List<InterfaceExternalIds> updateToExpectedExternalIds = updateToTestCase.expectedValues;
+
+ // CREATE: Create the test interface
+ Assert.assertTrue(addBridge(connectionInfo, null, testBridgeAndPortName, null, true,
+ SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null));
+ NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
+ connectionInfo, new OvsdbBridgeName(testBridgeAndPortName)));
+ OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
+ createGenericOvsdbTerminationPointAugmentationBuilder();
+ tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
+ tpCreateAugmentationBuilder.setInterfaceExternalIds(updateFromInputExternalIds);
+ Assert.assertTrue(
+ addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
+
+ // READ: Read the test interface 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<InterfaceExternalIds> updateFromConfigurationExternalIds =
+ updateFromConfigurationTerminationPointAugmentation.getInterfaceExternalIds();
+ assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
+ updateFromConfigurationExternalIds);
+ }
+ OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
+ getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
+ LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
+ if (updateFromOperationalTerminationPointAugmentation != null) {
+ List<InterfaceExternalIds> updateFromOperationalExternalIds =
+ updateFromOperationalTerminationPointAugmentation.getInterfaceExternalIds();
+ assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
+ updateFromOperationalExternalIds);
+ }
+
+ // UPDATE: update the external_ids
+ testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
+ OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
+ new OvsdbTerminationPointAugmentationBuilder();
+ tpUpdateAugmentationBuilder.setInterfaceExternalIds(updateToInputExternalIds);
+ InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
+ NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
+ NodeId portUpdateNodeId = createManagedNodeId(portIid);
+ portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
+ TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
+ tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
+ tpUpdateBuilder.addAugmentation(
+ OvsdbTerminationPointAugmentation.class,
+ tpUpdateAugmentationBuilder.build());
+ portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
+ Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
+ portIid, portUpdateNodeBuilder.build()));
+ Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+
+ // READ: the test interface 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<InterfaceExternalIds> updateToConfigurationExternalIds =
+ updateToConfigurationTerminationPointAugmentation.getInterfaceExternalIds();
+ assertExpectedInterfaceExternalIdsExist(updateToExpectedExternalIds,
+ updateToConfigurationExternalIds);
+ assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
+ updateToConfigurationExternalIds);
+ }
+ OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
+ getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
+ LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
+ if (updateToOperationalTerminationPointAugmentation != null) {
+ List<InterfaceExternalIds> updateToOperationalExternalIds =
+ updateToOperationalTerminationPointAugmentation.getInterfaceExternalIds();
+ if (updateFromExpectedExternalIds != null) {
+ assertExpectedInterfaceExternalIdsExist(updateToExpectedExternalIds,
+ updateToOperationalExternalIds);
+ assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
+ updateToOperationalExternalIds);
+ } else {
+ Assert.assertNull(updateToOperationalExternalIds);
+ }
+ }
+
+ // DELETE
+ Assert.assertTrue(deleteBridge(connectionInfo, testBridgeAndPortName));
}
}
- executor.shutdown();
- executor.awaitTermination(5, TimeUnit.MINUTES);
Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
}
/*
- * Generates the test cases involved in testing TP Options. See inline comments for descriptions of
- * the particular cases considered.
+ * @see <code>SouthboundIT.testCRUDTerminationPointOptions()</code>
+ * This is helper test method to compare a test "set" of Options against an expected "set"
*/
- private List<SouthboundTestCase<Options>> generateTerminationPointOptionsTestCases() {
- return generateKeyValueTestCases(new SouthboundOptionsBuilder(), "TOPOptionsKey", "TPOptionsValue");
+ private void assertExpectedOptionsExist( List<Options> expected,
+ List<Options> test ) {
+
+ if (expected != null) {
+ for (Options expectedOption : expected) {
+ Assert.assertTrue(test.contains(expectedOption));
+ }
+ }
}
/*
@Test
public void testCRUDTerminationPointOptions() throws InterruptedException {
final String TEST_PREFIX = "CRUDTPOptions";
+ final int TERMINATION_POINT_TEST_INDEX = 0;
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
connectOvsdbNode(connectionInfo);
// updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
// the update has been performed.
- List<SouthboundTestCase<Options>> updateFromTestCases = generateTerminationPointOptionsTestCases();
- List<SouthboundTestCase<Options>> updateToTestCases = generateTerminationPointOptionsTestCases();
- String testBridgeName;
- String testPortName;
-
- int counter = 1;
- ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
- for (SouthboundTestCase<Options> fromTestCase : updateFromTestCases) {
- for (SouthboundTestCase<Options> toTestCase : updateToTestCases) {
- testPortName = testBridgeName = String.format(FORMAT_STR,
- TEST_PREFIX, toTestCase.name, counter);
- counter += 1;
- executor.submit(new TestCRUDTerminationPointRunnable<>(
- new SouthboundTestHelper<Options>() {
- @Override
- public List<Options> readValues(
- OvsdbTerminationPointAugmentation augmentation) {
- return augmentation.getOptions();
- }
-
- @Override
- public void writeValues(
- OvsdbTerminationPointAugmentationBuilder augmentationBuilder,
- List<Options> values) {
- augmentationBuilder.setOptions(values);
- }
- },
- connectionInfo, testBridgeName, testPortName,
- fromTestCase.inputValues,
- fromTestCase.expectedValues,
- toTestCase.inputValues,
- toTestCase.expectedValues));
+ List<SouthboundTestCase<Options>> updateFromTestCases =
+ generateKeyValueTestCases(new SouthboundOptionsBuilder(), "OptionsFrom");
+ List<SouthboundTestCase<Options>> updateToTestCases = generateKeyValueTestCases(new SouthboundOptionsBuilder(),
+ "OptionsTo");
+
+ for (SouthboundTestCase<Options> updateFromTestCase : updateFromTestCases) {
+ List<Options> updateFromInputOptions = updateFromTestCase.inputValues;
+ List<Options> updateFromExpectedOptions = updateFromTestCase.expectedValues;
+ for (SouthboundTestCase<Options> updateToTestCase : updateToTestCases) {
+ String testBridgeAndPortName = String.format("%s_%s", TEST_PREFIX, updateToTestCase.name);
+ List<Options> updateToInputOptions = updateToTestCase.inputValues;
+ List<Options> updateToExpectedOptions = updateToTestCase.expectedValues;
+
+ // CREATE: Create the test interface
+ Assert.assertTrue(addBridge(connectionInfo, null, testBridgeAndPortName, null, true,
+ SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null));
+ NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
+ connectionInfo, new OvsdbBridgeName(testBridgeAndPortName)));
+ OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
+ createGenericOvsdbTerminationPointAugmentationBuilder();
+ tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
+ tpCreateAugmentationBuilder.setOptions(updateFromInputOptions);
+ Assert.assertTrue(
+ addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
+
+ // READ: Read the test interface 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<Options> updateFromConfigurationOptions =
+ updateFromConfigurationTerminationPointAugmentation.getOptions();
+ assertExpectedOptionsExist(updateFromExpectedOptions, updateFromConfigurationOptions);
+ }
+ OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
+ getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
+ LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
+ if (updateFromOperationalTerminationPointAugmentation != null) {
+ List<Options> updateFromOperationalOptions =
+ updateFromOperationalTerminationPointAugmentation.getOptions();
+ assertExpectedOptionsExist(updateFromExpectedOptions, updateFromOperationalOptions);
+ }
+
+ // UPDATE: update the external_ids
+ testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
+ OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
+ new OvsdbTerminationPointAugmentationBuilder();
+ tpUpdateAugmentationBuilder.setOptions(updateToInputOptions);
+ InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
+ NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
+ NodeId portUpdateNodeId = createManagedNodeId(portIid);
+ portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
+ TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
+ tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
+ tpUpdateBuilder.addAugmentation(
+ OvsdbTerminationPointAugmentation.class,
+ tpUpdateAugmentationBuilder.build());
+ portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
+ Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
+ portIid, portUpdateNodeBuilder.build()));
+ Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+
+ // READ: the test interface 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<Options> updateToConfigurationOptions =
+ updateToConfigurationTerminationPointAugmentation.getOptions();
+ assertExpectedOptionsExist(updateToExpectedOptions, updateToConfigurationOptions);
+ assertExpectedOptionsExist(updateFromExpectedOptions, updateToConfigurationOptions);
+ }
+ OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
+ getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
+ LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
+ if (updateToOperationalTerminationPointAugmentation != null) {
+ List<Options> updateToOperationalOptions =
+ updateToOperationalTerminationPointAugmentation.getOptions();
+ if (updateFromExpectedOptions != null) {
+ assertExpectedOptionsExist(updateToExpectedOptions, updateToOperationalOptions);
+ assertExpectedOptionsExist(updateFromExpectedOptions, updateToOperationalOptions);
+ }
+ }
+
+ // DELETE
+ Assert.assertTrue(deleteBridge(connectionInfo, testBridgeAndPortName));
}
}
- executor.shutdown();
- executor.awaitTermination(5, TimeUnit.MINUTES);
Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
}
/*
- * Generates the test cases involved in testing Interface other_configs. See inline comments for descriptions of
- * the particular cases considered.
+ * @see <code>SouthboundIT.testCRUDInterfaceOtherConfigs()</code>
+ * This is helper test method to compare a test "set" of Options against an expected "set"
*/
- private List<SouthboundTestCase<InterfaceOtherConfigs>> generateInterfaceOtherConfigsTestCases() {
- return generateKeyValueTestCases(new SouthboundInterfaceOtherConfigsBuilder(), "IntOtherConfigsKey",
- "IntOtherConfigsValue");
+ private void assertExpectedInterfaceOtherConfigsExist( List<InterfaceOtherConfigs> expected,
+ List<InterfaceOtherConfigs> test ) {
+
+ if (expected != null && test != null) {
+ for (InterfaceOtherConfigs expectedOtherConfigs : expected) {
+ Assert.assertTrue(test.contains(expectedOtherConfigs));
+ }
+ }
}
/*
@Test
public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException {
final String TEST_PREFIX = "CRUDTPInterfaceOtherConfigs";
+ final int TERMINATION_POINT_TEST_INDEX = 0;
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
connectOvsdbNode(connectionInfo);
// updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
// the update has been performed.
- List<SouthboundTestCase<InterfaceOtherConfigs>> updateFromTestCases = generateInterfaceOtherConfigsTestCases();
- List<SouthboundTestCase<InterfaceOtherConfigs>> updateToTestCases = generateInterfaceOtherConfigsTestCases();
- String testBridgeName;
- String testPortName;
-
- int counter = 1;
- ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
- for (SouthboundTestCase<InterfaceOtherConfigs> fromTestCase : updateFromTestCases) {
- for (SouthboundTestCase<InterfaceOtherConfigs> toTestCase : updateToTestCases) {
- testPortName = testBridgeName = String.format(FORMAT_STR,
- TEST_PREFIX, toTestCase.name, counter);
- counter += 1;
- executor.submit(new TestCRUDTerminationPointRunnable<>(
- new SouthboundTestHelper<InterfaceOtherConfigs>() {
- @Override
- public List<InterfaceOtherConfigs> readValues(
- OvsdbTerminationPointAugmentation augmentation) {
- return augmentation.getInterfaceOtherConfigs();
- }
-
- @Override
- public void writeValues(
- OvsdbTerminationPointAugmentationBuilder augmentationBuilder,
- List<InterfaceOtherConfigs> values) {
- augmentationBuilder.setInterfaceOtherConfigs(values);
- }
- },
- connectionInfo, testBridgeName, testPortName,
- fromTestCase.inputValues,
- fromTestCase.expectedValues,
- toTestCase.inputValues,
- toTestCase.expectedValues));
+ List<SouthboundTestCase<InterfaceOtherConfigs>> updateFromTestCases =
+ generateKeyValueTestCases(new SouthboundInterfaceOtherConfigsBuilder(), "InterfaceOtherConfigsFrom");
+ List<SouthboundTestCase<InterfaceOtherConfigs>> updateToTestCases =
+ generateKeyValueTestCases(new SouthboundInterfaceOtherConfigsBuilder(), "InterfaceOtherConfigsTo");
+
+ for (SouthboundTestCase<InterfaceOtherConfigs> updateFromTestCase : updateFromTestCases) {
+ List<InterfaceOtherConfigs> updateFromInputOtherConfigs = updateFromTestCase.inputValues;
+ List<InterfaceOtherConfigs> updateFromExpectedOtherConfigs = updateFromTestCase.expectedValues;
+ for (SouthboundTestCase<InterfaceOtherConfigs> updateToTestCase : updateToTestCases) {
+ String testBridgeAndPortName = String.format("%s_%s", TEST_PREFIX, updateToTestCase.name);
+ List<InterfaceOtherConfigs> updateToInputOtherConfigs = updateToTestCase.inputValues;
+ List<InterfaceOtherConfigs> updateToExpectedOtherConfigs = updateToTestCase.expectedValues;
+
+ // CREATE: Create the test interface
+ Assert.assertTrue(addBridge(connectionInfo, null, testBridgeAndPortName, null, true,
+ SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null));
+ NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
+ connectionInfo, new OvsdbBridgeName(testBridgeAndPortName)));
+ OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
+ createGenericOvsdbTerminationPointAugmentationBuilder();
+ tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
+ tpCreateAugmentationBuilder.setInterfaceOtherConfigs(updateFromInputOtherConfigs);
+ Assert.assertTrue(
+ addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
+
+ // READ: Read the test interface 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<InterfaceOtherConfigs> updateFromConfigurationOtherConfigs =
+ updateFromConfigurationTerminationPointAugmentation.getInterfaceOtherConfigs();
+ assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
+ updateFromConfigurationOtherConfigs);
+ }
+ OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
+ getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
+ LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
+ if (updateFromOperationalTerminationPointAugmentation != null) {
+ List<InterfaceOtherConfigs> updateFromOperationalOtherConfigs =
+ updateFromOperationalTerminationPointAugmentation.getInterfaceOtherConfigs();
+ assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
+ updateFromOperationalOtherConfigs);
+ }
+
+ // UPDATE: update the other_configs
+ testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
+ OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
+ new OvsdbTerminationPointAugmentationBuilder();
+ tpUpdateAugmentationBuilder.setInterfaceOtherConfigs(updateToInputOtherConfigs);
+ InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
+ NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
+ NodeId portUpdateNodeId = createManagedNodeId(portIid);
+ portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
+ TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
+ tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
+ tpUpdateBuilder.addAugmentation(
+ OvsdbTerminationPointAugmentation.class,
+ tpUpdateAugmentationBuilder.build());
+ portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
+ Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
+ portIid, portUpdateNodeBuilder.build()));
+ Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+
+ // READ: the test interface 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<InterfaceOtherConfigs> updateToConfigurationOtherConfigs =
+ updateToConfigurationTerminationPointAugmentation.getInterfaceOtherConfigs();
+ assertExpectedInterfaceOtherConfigsExist(updateToExpectedOtherConfigs,
+ updateToConfigurationOtherConfigs);
+ assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
+ updateToConfigurationOtherConfigs);
+ }
+ OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
+ getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
+ LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
+ if (updateToOperationalTerminationPointAugmentation != null) {
+ List<InterfaceOtherConfigs> updateToOperationalOtherConfigs =
+ updateToOperationalTerminationPointAugmentation.getInterfaceOtherConfigs();
+ if (updateFromExpectedOtherConfigs != null) {
+ assertExpectedInterfaceOtherConfigsExist(updateToExpectedOtherConfigs,
+ updateToOperationalOtherConfigs);
+ assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
+ updateToOperationalOtherConfigs);
+ }
+ }
+
+ // DELETE
+ Assert.assertTrue(deleteBridge(connectionInfo, testBridgeAndPortName));
}
}
- executor.shutdown();
- executor.awaitTermination(5, TimeUnit.MINUTES);
Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
}
/*
- * Generates the test cases involved in testing Port other_configs. See inline comments for descriptions of
- * the particular cases considered.
+ * @see <code>SouthboundIT.testCRUDPortOtherConfigs()</code>
+ * This is helper test method to compare a test "set" of Options against an expected "set"
*/
- private List<SouthboundTestCase<PortOtherConfigs>> generatePortOtherConfigsTestCases() {
- return generateKeyValueTestCases(new SouthboundPortOtherConfigsBuilder(), "PortOtherConfigsKey",
- "PortOtherConfigsValue");
+ private void assertExpectedPortOtherConfigsExist( List<PortOtherConfigs> expected,
+ List<PortOtherConfigs> test ) {
+
+ if (expected != null && test != null) {
+ for (PortOtherConfigs expectedOtherConfigs : expected) {
+ Assert.assertTrue(test.contains(expectedOtherConfigs));
+ }
+ }
}
/*
@Test
public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException {
final String TEST_PREFIX = "CRUDTPPortOtherConfigs";
+ final int TERMINATION_POINT_TEST_INDEX = 0;
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
connectOvsdbNode(connectionInfo);
// updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
// the update has been performed.
- List<SouthboundTestCase<PortOtherConfigs>> updateFromTestCases = generatePortOtherConfigsTestCases();
- List<SouthboundTestCase<PortOtherConfigs>> updateToTestCases = generatePortOtherConfigsTestCases();
- String testBridgeName;
- String testPortName;
-
- int counter = 1;
- ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
- for (SouthboundTestCase<PortOtherConfigs> fromTestCase : updateFromTestCases) {
- for (SouthboundTestCase<PortOtherConfigs> toTestCase : updateToTestCases) {
- testPortName = testBridgeName = String.format(FORMAT_STR,
- TEST_PREFIX, toTestCase.name, counter);
- counter += 1;
- executor.submit(new TestCRUDTerminationPointRunnable<>(
- new SouthboundTestHelper<PortOtherConfigs>() {
- @Override
- public List<PortOtherConfigs> readValues(
- OvsdbTerminationPointAugmentation augmentation) {
- return augmentation.getPortOtherConfigs();
- }
-
- @Override
- public void writeValues(
- OvsdbTerminationPointAugmentationBuilder augmentationBuilder,
- List<PortOtherConfigs> values) {
- augmentationBuilder.setPortOtherConfigs(values);
- }
- },
- connectionInfo, testBridgeName, testPortName,
- fromTestCase.inputValues,
- fromTestCase.expectedValues,
- toTestCase.inputValues,
- toTestCase.expectedValues));
+ List<SouthboundTestCase<PortOtherConfigs>> updateFromTestCases =
+ generateKeyValueTestCases(new SouthboundPortOtherConfigsBuilder(), "PortOtherConfigsFrom");
+ List<SouthboundTestCase<PortOtherConfigs>> updateToTestCases =
+ generateKeyValueTestCases(new SouthboundPortOtherConfigsBuilder(), "PortOtherConfigsTo");
+
+ for (SouthboundTestCase<PortOtherConfigs> updateFromTestCase : updateFromTestCases) {
+ List<PortOtherConfigs> updateFromInputOtherConfigs = updateFromTestCase.inputValues;
+ List<PortOtherConfigs> updateFromExpectedOtherConfigs = updateFromTestCase.expectedValues;
+ for (SouthboundTestCase<PortOtherConfigs> updateToTestCase : updateToTestCases) {
+ String testBridgeAndPortName = String.format("%s_%s", TEST_PREFIX, updateToTestCase.name);
+ List<PortOtherConfigs> updateToInputOtherConfigs = updateToTestCase.inputValues;
+ List<PortOtherConfigs> updateToExpectedOtherConfigs = updateToTestCase.expectedValues;
+
+ // CREATE: Create the test port
+ Assert.assertTrue(addBridge(connectionInfo, null, testBridgeAndPortName, null, true,
+ SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null));
+ NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
+ connectionInfo, new OvsdbBridgeName(testBridgeAndPortName)));
+ OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
+ createGenericOvsdbTerminationPointAugmentationBuilder();
+ tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
+ tpCreateAugmentationBuilder.setPortOtherConfigs(updateFromInputOtherConfigs);
+ 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<PortOtherConfigs> updateFromConfigurationOtherConfigs =
+ updateFromConfigurationTerminationPointAugmentation.getPortOtherConfigs();
+ assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
+ updateFromConfigurationOtherConfigs);
+ }
+ OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
+ getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
+ LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
+ if (updateFromOperationalTerminationPointAugmentation != null) {
+ List<PortOtherConfigs> updateFromOperationalOtherConfigs =
+ updateFromOperationalTerminationPointAugmentation.getPortOtherConfigs();
+ assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
+ updateFromOperationalOtherConfigs);
+ }
+
+ // UPDATE: update the other_configs
+ testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
+ OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
+ new OvsdbTerminationPointAugmentationBuilder();
+ tpUpdateAugmentationBuilder.setPortOtherConfigs(updateToInputOtherConfigs);
+ InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
+ NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
+ NodeId portUpdateNodeId = createManagedNodeId(portIid);
+ portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
+ TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
+ tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
+ tpUpdateBuilder.addAugmentation(
+ OvsdbTerminationPointAugmentation.class,
+ tpUpdateAugmentationBuilder.build());
+ portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
+ Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
+ portIid, portUpdateNodeBuilder.build()));
+ Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+
+ // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
+ // then repeat for OPERATIONAL data store
+ OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
+ getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
+ LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
+ if (updateToConfigurationTerminationPointAugmentation != null) {
+ List<PortOtherConfigs> updateToConfigurationOtherConfigs =
+ updateToConfigurationTerminationPointAugmentation.getPortOtherConfigs();
+ assertExpectedPortOtherConfigsExist(updateToExpectedOtherConfigs,
+ updateToConfigurationOtherConfigs);
+ assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
+ updateToConfigurationOtherConfigs);
+ }
+ OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
+ getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
+ LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
+ if (updateToOperationalTerminationPointAugmentation != null) {
+ List<PortOtherConfigs> updateToOperationalOtherConfigs =
+ updateToOperationalTerminationPointAugmentation.getPortOtherConfigs();
+ if (updateFromExpectedOtherConfigs != null) {
+ assertExpectedPortOtherConfigsExist(updateToExpectedOtherConfigs,
+ updateToOperationalOtherConfigs);
+ assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
+ updateToOperationalOtherConfigs);
+ }
+ }
+
+ // DELETE
+ Assert.assertTrue(deleteBridge(connectionInfo, testBridgeAndPortName));
}
}
- executor.shutdown();
- executor.awaitTermination(5, TimeUnit.MINUTES);
Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
}
Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
}
- private ArrayList<Set<Integer>> generateVlanSets() {
- ArrayList<Set<Integer>> vlanSets = new ArrayList<>();
-
- Set<Integer> emptySet = new HashSet<>();
- vlanSets.add(emptySet);
-
- Set<Integer> singleSet = new HashSet<>();
- Integer single = 2222;
- singleSet.add(single);
- vlanSets.add(singleSet);
-
- Set<Integer> minMaxMiddleSet = new HashSet<>();
- Integer min = 0;
- minMaxMiddleSet.add(min);
- Integer max = 4095;
- minMaxMiddleSet.add(max);
- Integer minPlusOne = min + 1;
- minMaxMiddleSet.add(minPlusOne);
- Integer maxMinusOne = max - 1;
- minMaxMiddleSet.add(maxMinusOne);
- Integer middle = (max - min) / 2;
- minMaxMiddleSet.add(middle);
- vlanSets.add(minMaxMiddleSet);
-
- return vlanSets;
+ @SuppressWarnings("unchecked")
+ private List<Set<Integer>> generateVlanSets() {
+ int min = 0;
+ int max = 4095;
+ return Lists.newArrayList(
+ Collections.<Integer>emptySet(),
+ Sets.newHashSet(2222),
+ Sets.newHashSet(min, max, min + 1, max - 1, (max - min) / 2));
}
private List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
}
- /*
- * Generates the test cases involved in testing BridgeOtherConfigs. See inline comments for descriptions of
- * the particular cases considered.
- */
- private List<SouthboundTestCase<BridgeOtherConfigs>> generateBridgeOtherConfigsTestCases() {
- return generateKeyValueTestCases(new SouthboundBridgeOtherConfigsBuilder(), "BridgeOtherConfigsKey",
- "BridgeOtherConfigsValue");
- }
-
/*
* @see <code>SouthboundIT.testCRUDBridgeOtherConfigs()</code>
* This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
connectOvsdbNode(connectionInfo);
// updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
// the update has been performed.
- List<SouthboundTestCase<BridgeOtherConfigs>> updateFromTestCases = generateBridgeOtherConfigsTestCases();
- List<SouthboundTestCase<BridgeOtherConfigs>> updateToTestCases = generateBridgeOtherConfigsTestCases();
- String testBridgeName;
-
- int counter = 1;
- ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
- for (SouthboundTestCase<BridgeOtherConfigs> fromTestCase : updateFromTestCases) {
- for (SouthboundTestCase<BridgeOtherConfigs> toTestCase : updateToTestCases) {
- testBridgeName = String.format(FORMAT_STR, TEST_BRIDGE_PREFIX, toTestCase.name, counter);
- counter += 1;
- TestCRUDBridgeOtherConfigsRunnable testRunnable =
- new TestCRUDBridgeOtherConfigsRunnable(
- connectionInfo, testBridgeName,
- fromTestCase.inputValues,
- fromTestCase.expectedValues,
- toTestCase.inputValues,
- toTestCase.expectedValues);
- executor.submit(testRunnable);
- }
- }
- executor.shutdown();
- executor.awaitTermination(5, TimeUnit.MINUTES);
-
- Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
- }
-
- class TestCRUDBridgeOtherConfigsRunnable implements Runnable {
-
- ConnectionInfo connectionInfo;
- String testBridgeName;
- List<BridgeOtherConfigs> updateFromInputOtherConfigs;
- List<BridgeOtherConfigs> updateFromExpectedOtherConfigs;
- List<BridgeOtherConfigs> updateToInputOtherConfigs;
- List<BridgeOtherConfigs> updateToExpectedOtherConfigs;
+ List<SouthboundTestCase<BridgeOtherConfigs>> updateFromTestCases =
+ generateKeyValueTestCases(new SouthboundBridgeOtherConfigsBuilder(), "BridgeOtherConfigsFrom");
+ List<SouthboundTestCase<BridgeOtherConfigs>> updateToTestCases = generateKeyValueTestCases(
+ new SouthboundBridgeOtherConfigsBuilder(), "BridgeOtherConfigsTo");
+ for (SouthboundTestCase<BridgeOtherConfigs> updateFromTestCase : updateFromTestCases) {
+ List<BridgeOtherConfigs> updateFromInputOtherConfigs = updateFromTestCase.inputValues;
+ List<BridgeOtherConfigs> updateFromExpectedOtherConfigs = updateFromTestCase.expectedValues;
+ for (SouthboundTestCase<BridgeOtherConfigs> updateToTestCase : updateToTestCases) {
+ String testBridgeName = String.format("%s_%s", TEST_BRIDGE_PREFIX, updateToTestCase.name);
+ List<BridgeOtherConfigs> updateToInputOtherConfigs = updateToTestCase.inputValues;
+ List<BridgeOtherConfigs> updateToExpectedOtherConfigs = updateToTestCase.expectedValues;
- TestCRUDBridgeOtherConfigsRunnable(
- ConnectionInfo connectionInfo, String testBridgeName,
- List<BridgeOtherConfigs> updateFromInputOtherConfigs,
- List<BridgeOtherConfigs> updateFromExpectedOtherConfigs,
- List<BridgeOtherConfigs> updateToInputOtherConfigs,
- List<BridgeOtherConfigs> updateToExpectedOtherConfigs) {
-
- this.connectionInfo = connectionInfo;
- this.testBridgeName = testBridgeName;
- this.updateFromInputOtherConfigs = updateFromInputOtherConfigs;
- this.updateFromExpectedOtherConfigs = updateFromExpectedOtherConfigs;
- this.updateToInputOtherConfigs = updateToInputOtherConfigs;
- this.updateToExpectedOtherConfigs = updateToExpectedOtherConfigs;
- }
+ // CREATE: Create the test bridge
+ boolean bridgeAdded = addBridge(connectionInfo, null,
+ testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
+ true, null, null, null, updateFromInputOtherConfigs);
+ Assert.assertTrue(bridgeAdded);
- @Override
- public void run() {
- try {
- test();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
+ // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
+ // then repeat for OPERATIONAL data store
+ List<BridgeOtherConfigs> updateFromConfigurationOtherConfigs = getBridge(connectionInfo, testBridgeName,
+ LogicalDatastoreType.CONFIGURATION).getBridgeOtherConfigs();
+ assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
+ updateFromConfigurationOtherConfigs);
+ List<BridgeOtherConfigs> updateFromOperationalOtherConfigs = getBridge(connectionInfo, testBridgeName).getBridgeOtherConfigs();
+ assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
+ updateFromOperationalOtherConfigs);
- public void test() throws InterruptedException {
- // CREATE: Create the test bridge
- boolean bridgeAdded = addBridge(connectionInfo, null,
- testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
- true, null, null, null, updateFromInputOtherConfigs);
- Assert.assertTrue(bridgeAdded);
-
- // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
- // then repeat for OPERATIONAL data store
- List<BridgeOtherConfigs> updateFromConfigurationOtherConfigs = getBridge(connectionInfo, testBridgeName,
- LogicalDatastoreType.CONFIGURATION).getBridgeOtherConfigs();
- assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
- updateFromConfigurationOtherConfigs);
- List<BridgeOtherConfigs> updateFromOperationalOtherConfigs = getBridge(connectionInfo, testBridgeName)
- .getBridgeOtherConfigs();
- assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
- updateFromOperationalOtherConfigs);
-
- // UPDATE: update the external_ids
- OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
- bridgeAugmentationBuilder.setBridgeOtherConfigs(updateToInputOtherConfigs);
- InstanceIdentifier<Node> bridgeIid =
- createInstanceIdentifier(connectionInfo,
- new OvsdbBridgeName(testBridgeName));
- NodeBuilder bridgeNodeBuilder = new NodeBuilder();
- Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
- bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId());
- bridgeNodeBuilder.setKey(bridgeNode.getKey());
- bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build());
- boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
- bridgeNodeBuilder.build());
- Thread.sleep(OVSDB_UPDATE_TIMEOUT);
- Assert.assertTrue(result);
+ // UPDATE: update the external_ids
+ OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
+ bridgeAugmentationBuilder.setBridgeOtherConfigs(updateToInputOtherConfigs);
+ InstanceIdentifier<Node> bridgeIid =
+ createInstanceIdentifier(connectionInfo,
+ new OvsdbBridgeName(testBridgeName));
+ NodeBuilder bridgeNodeBuilder = new NodeBuilder();
+ Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
+ bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId());
+ bridgeNodeBuilder.setKey(bridgeNode.getKey());
+ bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build());
+ boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
+ bridgeNodeBuilder.build());
+ Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+ Assert.assertTrue(result);
- // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
- // then repeat for OPERATIONAL data store
- List<BridgeOtherConfigs> updateToConfigurationOtherConfigs = getBridge(connectionInfo, testBridgeName,
- LogicalDatastoreType.CONFIGURATION).getBridgeOtherConfigs();
- assertExpectedBridgeOtherConfigsExist(updateToExpectedOtherConfigs, updateToConfigurationOtherConfigs);
- assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
- updateToConfigurationOtherConfigs);
- List<BridgeOtherConfigs> updateToOperationalOtherConfigs = getBridge(connectionInfo, testBridgeName)
- .getBridgeOtherConfigs();
- if (updateFromExpectedOtherConfigs != null) {
- assertExpectedBridgeOtherConfigsExist(updateToExpectedOtherConfigs,
- updateToOperationalOtherConfigs);
+ // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
+ // then repeat for OPERATIONAL data store
+ List<BridgeOtherConfigs> updateToConfigurationOtherConfigs = getBridge(connectionInfo, testBridgeName,
+ LogicalDatastoreType.CONFIGURATION).getBridgeOtherConfigs();
+ assertExpectedBridgeOtherConfigsExist(updateToExpectedOtherConfigs, updateToConfigurationOtherConfigs);
assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
- updateToOperationalOtherConfigs);
- }
+ updateToConfigurationOtherConfigs);
+ List<BridgeOtherConfigs> updateToOperationalOtherConfigs = getBridge(connectionInfo, testBridgeName)
+ .getBridgeOtherConfigs();
+ if (updateFromExpectedOtherConfigs != null) {
+ assertExpectedBridgeOtherConfigsExist(updateToExpectedOtherConfigs,
+ updateToOperationalOtherConfigs);
+ assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
+ updateToOperationalOtherConfigs);
+ }
- // DELETE
- Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
+ // DELETE
+ Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
+ }
}
- }
-
- /*
- * Generates the test cases involved in testing BridgeExternalIds. See inline comments for descriptions of
- * the particular cases considered.
- */
- private List<SouthboundTestCase<BridgeExternalIds>> generateBridgeExternalIdsTestCases() {
- return generateKeyValueTestCases(new SouthboundBridgeExternalIdsBuilder(), "BridgeExternalIdsKey",
- "BridgeExternalIdsValue");
+ Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
}
/*
connectOvsdbNode(connectionInfo);
// updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
// the update has been performed.
- List<SouthboundTestCase<BridgeExternalIds>> updateFromTestCases = generateBridgeExternalIdsTestCases();
- List<SouthboundTestCase<BridgeExternalIds>> updateToTestCases = generateBridgeExternalIdsTestCases();
- String testBridgeName;
-
- int counter = 1;
- ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
- for (SouthboundTestCase<BridgeExternalIds> fromTestCase : updateFromTestCases) {
- for (SouthboundTestCase<BridgeExternalIds> toTestCase : updateToTestCases) {
- testBridgeName = String.format(FORMAT_STR, TEST_BRIDGE_PREFIX, toTestCase.name, counter);
- counter += 1;
- TestCRUDBridgeExternalIdsRunnable testRunnable =
- new TestCRUDBridgeExternalIdsRunnable(
- connectionInfo, testBridgeName,
- fromTestCase.inputValues,
- fromTestCase.expectedValues,
- toTestCase.inputValues,
- toTestCase.expectedValues);
- executor.submit(testRunnable);
- }
- }
- executor.shutdown();
- executor.awaitTermination(5, TimeUnit.MINUTES);
-
- Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
- }
+ List<SouthboundTestCase<BridgeExternalIds>> updateFromTestCases = generateKeyValueTestCases(
+ new SouthboundBridgeExternalIdsBuilder(), "BridgeExternalIdsFrom");
+ List<SouthboundTestCase<BridgeExternalIds>> updateToTestCases = generateKeyValueTestCases(
+ new SouthboundBridgeExternalIdsBuilder(), "BridgeExternalIdsTo");
+ for (SouthboundTestCase<BridgeExternalIds> updateFromTestCase : updateFromTestCases) {
+ List<BridgeExternalIds> updateFromInputExternalIds = updateFromTestCase.inputValues;
+ List<BridgeExternalIds> updateFromExpectedExternalIds = updateFromTestCase.expectedValues;
+ for (SouthboundTestCase<BridgeExternalIds> updateToTestCase : updateToTestCases) {
+ String testBridgeName = String.format("%s_%s", TEST_BRIDGE_PREFIX, updateToTestCase.name);
+ List<BridgeExternalIds> updateToInputExternalIds = updateToTestCase.inputValues;
+ List<BridgeExternalIds> updateToExpectedExternalIds = updateToTestCase.expectedValues;
- class TestCRUDBridgeExternalIdsRunnable implements Runnable {
- ConnectionInfo connectionInfo;
- String testBridgeName;
- List<BridgeExternalIds> updateFromInputExternalIds;
- List<BridgeExternalIds> updateFromExpectedExternalIds;
- List<BridgeExternalIds> updateToInputExternalIds;
- List<BridgeExternalIds> updateToExpectedExternalIds;
-
- TestCRUDBridgeExternalIdsRunnable(
- ConnectionInfo connectionInfo, String testBridgeName,
- List<BridgeExternalIds> updateFromInputExternalIds,
- List<BridgeExternalIds> updateFromExpectedExternalIds,
- List<BridgeExternalIds> updateToInputExternalIds,
- List<BridgeExternalIds> updateToExpectedExternalIds) {
+ // CREATE: Create the test bridge
+ boolean bridgeAdded = addBridge(connectionInfo, null,
+ testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
+ true, null, updateFromInputExternalIds, null, null);
+ Assert.assertTrue(bridgeAdded);
- this.connectionInfo = connectionInfo;
- this.testBridgeName = testBridgeName;
- this.updateFromInputExternalIds = updateFromInputExternalIds;
- this.updateFromExpectedExternalIds = updateFromExpectedExternalIds;
- this.updateToInputExternalIds = updateToInputExternalIds;
- this.updateToExpectedExternalIds = updateToExpectedExternalIds;
- }
+ // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
+ // then repeat for OPERATIONAL data store
+ List<BridgeExternalIds> updateFromConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
+ LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
+ assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromConfigurationExternalIds);
+ List<BridgeExternalIds> updateFromOperationalExternalIds = getBridge(connectionInfo, testBridgeName).getBridgeExternalIds();
+ assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromOperationalExternalIds);
- @Override
- public void run() {
- try {
- test();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
+ // UPDATE: update the external_ids
+ OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
+ bridgeAugmentationBuilder.setBridgeExternalIds(updateToInputExternalIds);
+ InstanceIdentifier<Node> bridgeIid =
+ createInstanceIdentifier(connectionInfo,
+ new OvsdbBridgeName(testBridgeName));
+ NodeBuilder bridgeNodeBuilder = new NodeBuilder();
+ Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
+ bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId());
+ bridgeNodeBuilder.setKey(bridgeNode.getKey());
+ bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build());
+ boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
+ bridgeNodeBuilder.build());
+ Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+ Assert.assertTrue(result);
- public void test() throws InterruptedException {
- // CREATE: Create the test bridge
- boolean bridgeAdded = addBridge(connectionInfo, null,
- testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
- true, null, updateFromInputExternalIds, null, null);
- Assert.assertTrue(bridgeAdded);
-
- // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
- // then repeat for OPERATIONAL data store
- List<BridgeExternalIds> updateFromConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
- LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
- assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromConfigurationExternalIds);
- List<BridgeExternalIds> updateFromOperationalExternalIds = getBridge(connectionInfo, testBridgeName)
- .getBridgeExternalIds();
- assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromOperationalExternalIds);
-
- // UPDATE: update the external_ids
- OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
- bridgeAugmentationBuilder.setBridgeExternalIds(updateToInputExternalIds);
- InstanceIdentifier<Node> bridgeIid =
- createInstanceIdentifier(connectionInfo,
- new OvsdbBridgeName(testBridgeName));
- NodeBuilder bridgeNodeBuilder = new NodeBuilder();
- Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
- bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId());
- bridgeNodeBuilder.setKey(bridgeNode.getKey());
- bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build());
- boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
- bridgeNodeBuilder.build());
- Thread.sleep(OVSDB_UPDATE_TIMEOUT);
- Assert.assertTrue(result);
+ // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
+ // then repeat for OPERATIONAL data store
+ List<BridgeExternalIds> updateToConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
+ LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
+ assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
+ assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateToConfigurationExternalIds);
+ List<BridgeExternalIds> updateToOperationalExternalIds = getBridge(connectionInfo, testBridgeName)
+ .getBridgeExternalIds();
+ if (updateFromExpectedExternalIds != null) {
+ assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds);
+ assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateToOperationalExternalIds);
+ }
- // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
- // then repeat for OPERATIONAL data store
- List<BridgeExternalIds> updateToConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
- LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
- assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
- assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateToConfigurationExternalIds);
- List<BridgeExternalIds> updateToOperationalExternalIds = getBridge(connectionInfo, testBridgeName)
- .getBridgeExternalIds();
- if (updateFromExpectedExternalIds != null) {
- assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds);
- assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateToOperationalExternalIds);
+ // DELETE
+ Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
}
-
- // DELETE
- Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
}
+ Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
}
public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
}
/**
- * Sets the expected output values.
+ * Indicates that the provided input values should be expected as output values.
*
- * @param expectedValues The expected output values.
* @return The builder.
*/
- @SafeVarargs
- public final SouthboundTestCaseBuilder<T> expect(final T... expectedValues) {
- this.expectedValues = Lists.newArrayList(expectedValues);
+ public SouthboundTestCaseBuilder<T> expectInputAsOutput() {
+ this.expectedValues = this.inputValues;
return this;
}
/**
- * Indicates that the provided input values should be expected as output values.
+ * Indicates that no output should be expected.
*
* @return The builder.
*/
- public SouthboundTestCaseBuilder<T> expectInputAsOutput() {
- this.expectedValues = this.inputValues;
+ public SouthboundTestCaseBuilder<T> expectNoOutput() {
+ this.expectedValues = null;
return this;
}
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);
+
+ 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 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);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ /*
+ * 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());
+
+ // 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;
+ builder.reset();
+ 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());
+
+ // 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;
+ builder.reset();
+ 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();
+
+ return testCases;
+ }
}