2 * Copyright (c) 2015 Red Hat, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.ovsdb.southbound.it;
10 import static org.junit.Assert.assertNotNull;
11 import static org.junit.Assert.fail;
12 import static org.ops4j.pax.exam.CoreOptions.composite;
13 import static org.ops4j.pax.exam.CoreOptions.maven;
14 import static org.ops4j.pax.exam.CoreOptions.vmOption;
15 import static org.ops4j.pax.exam.CoreOptions.when;
16 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
17 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration;
18 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
20 import com.google.common.collect.ImmutableBiMap;
21 import com.google.common.collect.Lists;
22 import com.google.common.collect.Sets;
25 import java.lang.reflect.Array;
26 import java.net.InetAddress;
27 import java.net.UnknownHostException;
28 import java.util.ArrayList;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Properties;
33 import java.util.concurrent.ExecutionException;
34 import java.util.concurrent.ExecutorService;
35 import java.util.concurrent.Executors;
36 import java.util.concurrent.TimeUnit;
38 import javax.inject.Inject;
40 import org.junit.Assert;
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.junit.runner.RunWith;
44 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
45 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
46 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
47 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
48 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
49 import org.opendaylight.ovsdb.southbound.SouthboundProvider;
50 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntry;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
93 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
94 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
95 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
96 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
97 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
98 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
99 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
100 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
101 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
102 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
103 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
104 import org.opendaylight.yangtools.concepts.Builder;
105 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
106 import org.ops4j.pax.exam.Configuration;
107 import org.ops4j.pax.exam.Option;
108 import org.ops4j.pax.exam.junit.PaxExam;
109 import org.ops4j.pax.exam.karaf.options.KarafDistributionOption;
110 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
111 import org.ops4j.pax.exam.options.MavenUrlReference;
112 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
113 import org.ops4j.pax.exam.spi.reactors.PerClass;
114 import org.osgi.framework.BundleContext;
115 import org.slf4j.Logger;
116 import org.slf4j.LoggerFactory;
119 * Integration tests for southbound-impl
121 * @author Sam Hague (shague@redhat.com)
123 @RunWith(PaxExam.class)
124 @ExamReactorStrategy(PerClass.class)
125 public class SouthboundIT extends AbstractMdsalTestBase {
126 private static final String NETDEV_DP_TYPE = "netdev";
127 private static final Logger LOG = LoggerFactory.getLogger(SouthboundIT.class);
128 private static final int OVSDB_UPDATE_TIMEOUT = 1000;
129 private static final String FORMAT_STR = "%s_%s_%d";
130 public static final int NUM_THREADS = 4;
131 private static String addressStr;
132 private static int portNumber;
133 private static String connectionType;
134 private static Boolean setup = false;
135 private static MdsalUtils mdsalUtils = null;
137 // TODO Constants copied from AbstractConfigTestBase, need to be removed (see TODO below)
138 private static final String PAX_EXAM_UNPACK_DIRECTORY = "target/exam";
139 private static final String KARAF_DEBUG_PORT = "5005";
140 private static final String KARAF_DEBUG_PROP = "karaf.debug";
141 private static final String KEEP_UNPACK_DIRECTORY_PROP = "karaf.keep.unpack";
144 private BundleContext bundleContext;
147 public Option[] config() {
148 // TODO Figure out how to use the parent Karaf setup, then just use super.config()
149 Option[] options = new Option[] {
150 when(Boolean.getBoolean(KARAF_DEBUG_PROP))
151 .useOptions(KarafDistributionOption.debugConfiguration(KARAF_DEBUG_PORT, true)),
152 karafDistributionConfiguration().frameworkUrl(getKarafDistro())
153 .unpackDirectory(new File(PAX_EXAM_UNPACK_DIRECTORY))
154 .useDeployFolder(false),
155 when(Boolean.getBoolean(KEEP_UNPACK_DIRECTORY_PROP)).useOptions(keepRuntimeFolder()),
156 // Works only if we don't specify the feature repo and name
158 Option[] propertyOptions = getPropertiesOptions();
159 Option[] otherOptions = getOtherOptions();
160 Option[] combinedOptions = new Option[options.length + propertyOptions.length + otherOptions.length];
161 System.arraycopy(options, 0, combinedOptions, 0, options.length);
162 System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length);
163 System.arraycopy(otherOptions, 0, combinedOptions, options.length + propertyOptions.length,
164 otherOptions.length);
165 return combinedOptions;
168 private Option[] getOtherOptions() {
169 return new Option[] {
170 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
176 public String getKarafDistro() {
178 .groupId("org.opendaylight.ovsdb")
179 .artifactId("southbound-karaf")
180 .versionAsInProject()
186 public String getModuleName() {
187 return "southbound-impl";
191 public String getInstanceName() {
192 return "southbound-default";
196 public MavenUrlReference getFeatureRepo() {
198 .groupId("org.opendaylight.ovsdb")
199 .artifactId("southbound-features")
200 .classifier("features")
202 .versionAsInProject();
206 public String getFeatureName() {
207 return "odl-ovsdb-southbound-impl-ui";
210 protected String usage() {
211 return "Integration Test needs a valid connection configuration as follows :\n"
212 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
213 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
217 public Option getLoggingOption() {
219 editConfigurationFilePut(SouthboundITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
220 "log4j.logger.org.opendaylight.ovsdb",
221 LogLevelOption.LogLevel.TRACE.name()),
222 super.getLoggingOption());
225 private Option[] getPropertiesOptions() {
226 Properties props = new Properties(System.getProperties());
227 String addressStr = props.getProperty(SouthboundITConstants.SERVER_IPADDRESS,
228 SouthboundITConstants.DEFAULT_SERVER_IPADDRESS);
229 String portStr = props.getProperty(SouthboundITConstants.SERVER_PORT,
230 SouthboundITConstants.DEFAULT_SERVER_PORT);
231 String connectionType = props.getProperty(SouthboundITConstants.CONNECTION_TYPE,
232 SouthboundITConstants.CONNECTION_TYPE_ACTIVE);
234 LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
235 connectionType, addressStr, portStr);
237 return new Option[] {
238 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
239 SouthboundITConstants.SERVER_IPADDRESS, addressStr),
240 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
241 SouthboundITConstants.SERVER_PORT, portStr),
242 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
243 SouthboundITConstants.CONNECTION_TYPE, connectionType),
249 public void setup() throws InterruptedException {
251 LOG.info("Skipping setUp, already initialized");
257 } catch (Exception e) {
260 //dataBroker = getSession().getSALService(DataBroker.class);
262 DataBroker dataBroker = SouthboundProvider.getDb();
263 Assert.assertNotNull("db should not be null", dataBroker);
265 addressStr = bundleContext.getProperty(SouthboundITConstants.SERVER_IPADDRESS);
266 String portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT);
268 portNumber = Integer.parseInt(portStr);
269 } catch (NumberFormatException e) {
270 fail("Invalid port number " + portStr + System.lineSeparator() + usage());
272 connectionType = bundleContext.getProperty(SouthboundITConstants.CONNECTION_TYPE);
274 LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
275 connectionType, addressStr, portNumber);
276 if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_ACTIVE)) {
277 if (addressStr == null) {
282 mdsalUtils = new MdsalUtils(dataBroker);
287 * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
288 * 6640. This test will wait for incoming connections for {@link SouthboundITConstants#CONNECTION_INIT_TIMEOUT} ms.
290 * @throws InterruptedException
293 public void testPassiveNode() throws InterruptedException {
294 if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_PASSIVE)) {
295 //Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
296 Thread.sleep(SouthboundITConstants.CONNECTION_INIT_TIMEOUT);
300 private ConnectionInfo getConnectionInfo(final String addressStr, final int portNumber) {
301 InetAddress inetAddress = null;
303 inetAddress = InetAddress.getByName(addressStr);
304 } catch (UnknownHostException e) {
305 fail("Could not resolve " + addressStr + ": " + e);
308 IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
309 PortNumber port = new PortNumber(portNumber);
311 final ConnectionInfo connectionInfo = new ConnectionInfoBuilder()
312 .setRemoteIp(address)
315 LOG.info("connectionInfo: {}", connectionInfo);
316 return connectionInfo;
319 private String connectionInfoToString(final ConnectionInfo connectionInfo) {
320 return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
324 public void testNetworkTopology() throws InterruptedException {
325 NetworkTopology networkTopology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION,
326 InstanceIdentifier.create(NetworkTopology.class));
327 Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.CONFIGURATION,
330 networkTopology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
331 InstanceIdentifier.create(NetworkTopology.class));
332 Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.OPERATIONAL,
337 public void testOvsdbTopology() throws InterruptedException {
338 InstanceIdentifier<Topology> path = InstanceIdentifier
339 .create(NetworkTopology.class)
340 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
342 Topology topology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
343 Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
346 topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
348 Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
352 private boolean addOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
353 InstanceIdentifier<Node> iid = createInstanceIdentifier(connectionInfo);
354 // Check that the node doesn't already exist (we don't support connecting twice)
355 Assert.assertNull("The OVSDB node has already been added",
356 mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, iid));
357 boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
359 createNode(connectionInfo));
360 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
364 private InstanceIdentifier<Node> createInstanceIdentifier(
365 ConnectionInfo connectionInfo) {
366 return InstanceIdentifier
367 .create(NetworkTopology.class)
368 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
370 createNodeKey(connectionInfo.getRemoteIp(), connectionInfo.getRemotePort()));
373 private Node getOvsdbNode(final ConnectionInfo connectionInfo) {
374 return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
375 createInstanceIdentifier(connectionInfo));
378 private boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
379 boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
380 createInstanceIdentifier(connectionInfo));
381 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
385 private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
386 Assert.assertTrue(addOvsdbNode(connectionInfo));
387 Node node = getOvsdbNode(connectionInfo);
388 Assert.assertNotNull(node);
389 LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
393 private boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
394 Assert.assertTrue(deleteOvsdbNode(connectionInfo));
395 Node node = getOvsdbNode(connectionInfo);
396 Assert.assertNull(node);
397 LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
402 public void testAddDeleteOvsdbNode() throws InterruptedException {
403 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
404 connectOvsdbNode(connectionInfo);
405 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
409 public void testDpdkSwitch() throws InterruptedException {
410 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
411 Node ovsdbNode = connectOvsdbNode(connectionInfo);
412 List<DatapathTypeEntry> datapathTypeEntries = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class)
413 .getDatapathTypeEntry();
414 if (datapathTypeEntries == null) {
415 LOG.info("DPDK not supported on this node.");
417 for (DatapathTypeEntry dpTypeEntry : datapathTypeEntries) {
418 Class<? extends DatapathTypeBase> dpType = dpTypeEntry.getDatapathType();
419 String dpTypeStr = SouthboundConstants.DATAPATH_TYPE_MAP.get(dpType);
420 LOG.info("dp type is {}", dpTypeStr);
421 if (dpTypeStr.equals(NETDEV_DP_TYPE)) {
422 LOG.info("Found a DPDK node; adding a corresponding netdev device");
423 InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo,
424 new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
425 NodeId bridgeNodeId = createManagedNodeId(bridgeIid);
426 addBridge(connectionInfo, bridgeIid, SouthboundITConstants.BRIDGE_NAME, bridgeNodeId, false, null,
427 true, dpType, null, null, null);
429 // Verify that the device is netdev
430 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
431 Assert.assertNotNull(bridge);
432 Assert.assertEquals(dpType, bridge.getDatapathType());
435 final String TEST_PORT_NAME = "testDPDKPort";
436 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
437 createGenericDpdkOvsdbTerminationPointAugmentationBuilder(TEST_PORT_NAME);
438 Assert.assertTrue(addTerminationPoint(bridgeNodeId, TEST_PORT_NAME, ovsdbTerminationBuilder));
440 // Verify that DPDK port was created
441 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
442 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
443 terminationPointIid);
444 Assert.assertNotNull(terminationPointNode);
446 // Verify that each termination point has DPDK ifType
447 Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
449 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
450 for (TerminationPoint terminationPoint : terminationPoints) {
451 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint
452 .getAugmentation(OvsdbTerminationPointAugmentation.class);
453 if (ovsdbTerminationPointAugmentation.getName().equals(TEST_PORT_NAME)) {
454 Class<? extends InterfaceTypeBase> opPort = ovsdbTerminationPointAugmentation
456 Assert.assertEquals(dpdkIfType, opPort);
459 Assert.assertTrue(deleteBridge(connectionInfo));
464 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
468 public void testOvsdbNodeOvsVersion() throws InterruptedException {
469 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
470 Node ovsdbNode = connectOvsdbNode(connectionInfo);
471 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
472 Assert.assertNotNull(ovsdbNodeAugmentation);
473 assertNotNull(ovsdbNodeAugmentation.getOvsVersion());
474 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
478 public void testOpenVSwitchOtherConfig() throws InterruptedException {
479 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
480 Node ovsdbNode = connectOvsdbNode(connectionInfo);
481 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
482 Assert.assertNotNull(ovsdbNodeAugmentation);
483 List<OpenvswitchOtherConfigs> otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
484 if (otherConfigsList != null) {
485 for (OpenvswitchOtherConfigs otherConfig : otherConfigsList) {
486 if (otherConfig.getOtherConfigKey().equals("local_ip")) {
487 LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
490 LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
494 LOG.info("other_config is not present");
496 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
500 public void testOvsdbBridgeControllerInfo() throws InterruptedException {
501 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
502 Node ovsdbNode = connectOvsdbNode(connectionInfo);
503 String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
504 assertNotNull("Failed to get controller target", controllerTarget);
505 List<ControllerEntry> setControllerEntry = createControllerEntry(controllerTarget);
506 Uri setUri = new Uri(controllerTarget);
507 Assert.assertTrue(addBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true,
508 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
509 setControllerEntry, null));
510 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
511 Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME, bridge);
512 Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
513 bridge.getControllerEntry());
514 List<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
515 for (ControllerEntry entry : getControllerEntries) {
516 if (entry.getTarget() != null) {
517 Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
521 Assert.assertTrue(deleteBridge(connectionInfo));
522 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
525 private List<ControllerEntry> createControllerEntry(String controllerTarget) {
526 List<ControllerEntry> controllerEntriesList = new ArrayList<>();
527 controllerEntriesList.add(new ControllerEntryBuilder()
528 .setTarget(new Uri(controllerTarget))
530 return controllerEntriesList;
533 private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
534 final ConnectionInfo connectionInfo) {
535 InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
536 ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
539 private List<ProtocolEntry> createMdsalProtocols() {
540 List<ProtocolEntry> protocolList = new ArrayList<>();
541 ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
542 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
543 protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
547 private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
548 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
549 new OvsdbTerminationPointAugmentationBuilder();
550 ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
551 new InterfaceTypeEntryBuilder()
553 SouthboundMapper.createInterfaceType("internal"))
554 .build().getInterfaceType());
555 return ovsdbTerminationPointAugmentationBuilder;
558 private OvsdbTerminationPointAugmentationBuilder createGenericDpdkOvsdbTerminationPointAugmentationBuilder(
559 final String portName) {
560 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
561 createGenericOvsdbTerminationPointAugmentationBuilder();
562 ovsdbTerminationBuilder.setName(portName);
563 Class<? extends InterfaceTypeBase> ifType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
565 ovsdbTerminationBuilder.setInterfaceType(ifType);
566 return ovsdbTerminationBuilder;
569 private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
570 final OvsdbTerminationPointAugmentationBuilder
571 ovsdbTerminationPointAugmentationBuilder)
572 throws InterruptedException {
574 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
575 NodeBuilder portNodeBuilder = new NodeBuilder();
576 NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
577 portNodeBuilder.setNodeId(portNodeId);
578 TerminationPointBuilder entry = new TerminationPointBuilder();
579 entry.setKey(new TerminationPointKey(new TpId(portName)));
580 entry.addAugmentation(
581 OvsdbTerminationPointAugmentation.class,
582 ovsdbTerminationPointAugmentationBuilder.build());
583 portNodeBuilder.setTerminationPoint(Lists.newArrayList(entry.build()));
584 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
585 portIid, portNodeBuilder.build());
586 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
591 * base method for adding test bridges. Other helper methods used to create bridges should utilize this method.
593 * @param connectionInfo
594 * @param bridgeIid if passed null, one is created
595 * @param bridgeName cannot be null
596 * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
597 * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
598 * @param failMode toggles whether default fail mode is set for the bridge
599 * @param setManagedBy toggles whether to setManagedBy for the bridge
600 * @param dpType if passed null, this parameter is ignored
601 * @param externalIds if passed null, this parameter is ignored
602 * @param otherConfig if passed null, this parameter is ignored
603 * @return success of bridge addition
604 * @throws InterruptedException
606 private boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
607 final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
608 final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
609 final Class<? extends DatapathTypeBase> dpType,
610 final List<BridgeExternalIds> externalIds,
611 final List<ControllerEntry> controllerEntries,
612 final List<BridgeOtherConfigs> otherConfigs) throws InterruptedException {
614 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
615 if (bridgeIid == null) {
616 bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
618 if (bridgeNodeId == null) {
619 bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
621 bridgeNodeBuilder.setNodeId(bridgeNodeId);
622 OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
623 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
624 if (setProtocolEntries) {
625 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
627 if (failMode != null) {
628 ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
631 setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
633 if (dpType != null) {
634 ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
636 if (externalIds != null) {
637 ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
639 if (controllerEntries != null) {
640 ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
642 if (otherConfigs != null) {
643 ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
645 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
646 LOG.debug("Built with the intent to store bridge data {}",
647 ovsdbBridgeAugmentationBuilder.toString());
648 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
649 bridgeIid, bridgeNodeBuilder.build());
650 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
654 private boolean addBridge(final ConnectionInfo connectionInfo, final String bridgeName)
655 throws InterruptedException {
657 return addBridge(connectionInfo, null, bridgeName, null, true,
658 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
661 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
662 return getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
666 * Extract the <code>store</code> type data store contents for the particular bridge identified by
667 * <code>bridgeName</code>.
669 * @param connectionInfo the connection information
670 * @param bridgeName the bridge name
671 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
672 * @return <code>store</code> type data store contents
674 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
675 LogicalDatastoreType store) {
676 Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
677 Assert.assertNotNull(bridgeNode);
678 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
679 Assert.assertNotNull(ovsdbBridgeAugmentation);
680 return ovsdbBridgeAugmentation;
684 * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
685 * identified by <code>bridgeName</code>
687 * @param connectionInfo the connection information
688 * @param bridgeName the bridge name
689 * @see <code>SouthboundIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
690 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
692 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
693 return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
697 * Extract the node contents from <code>store</code> type data store for the
698 * bridge identified by <code>bridgeName</code>
700 * @param connectionInfo the connection information
701 * @param bridgeName the bridge name
702 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
703 * @return <code>store</code> type data store contents
705 private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
706 InstanceIdentifier<Node> bridgeIid =
707 createInstanceIdentifier(connectionInfo,
708 new OvsdbBridgeName(bridgeName));
709 return mdsalUtils.read(store, bridgeIid);
713 * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
714 * bridge identified by <code>bridgeName</code>
716 * @param connectionInfo the connection information
717 * @param bridgeName the bridge name
718 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
720 private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
721 return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
724 private boolean deleteBridge(ConnectionInfo connectionInfo) throws InterruptedException {
725 return deleteBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
728 private boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName)
729 throws InterruptedException {
731 boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
732 createInstanceIdentifier(connectionInfo,
733 new OvsdbBridgeName(bridgeName)));
734 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
739 public void testAddDeleteBridge() throws InterruptedException {
740 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
741 connectOvsdbNode(connectionInfo);
743 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
744 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
745 Assert.assertNotNull(bridge);
746 LOG.info("bridge: {}", bridge);
748 Assert.assertTrue(deleteBridge(connectionInfo));
750 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
753 private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
754 return createInstanceIdentifier(connectionInfo,
755 bridge.getBridgeName());
759 * Extracts the <code>TerminationPointAugmentation</code> for the <code>index</code> <code>TerminationPoint</code>
760 * on <code>bridgeName</code>
762 * @param connectionInfo the connection information
763 * @param bridgeName the bridge name
764 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
765 * @param index the index we're interested in
766 * @return the augmentation (or {@code null} if none)
768 private OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation(
769 ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index ) {
771 List<TerminationPoint> tpList = getBridgeNode(connectionInfo, bridgeName, store).getTerminationPoint();
772 if (tpList == null) {
775 return tpList.get(index).getAugmentation(OvsdbTerminationPointAugmentation.class);
779 public void testCRDTerminationPointOfPort() throws InterruptedException {
780 final Long OFPORT_EXPECTED = 45002L;
782 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
783 connectOvsdbNode(connectionInfo);
786 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
787 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
788 Assert.assertNotNull(bridge);
789 LOG.info("bridge: {}", bridge);
790 NodeId nodeId = SouthboundMapper.createManagedNodeId(createInstanceIdentifier(
791 connectionInfo, bridge.getBridgeName()));
792 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
793 createGenericOvsdbTerminationPointAugmentationBuilder();
794 String portName = "testOfPort";
795 ovsdbTerminationBuilder.setName(portName);
797 ovsdbTerminationBuilder.setOfport(OFPORT_EXPECTED);
798 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
799 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
800 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
801 Assert.assertNotNull(terminationPointNode);
804 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
805 for (TerminationPoint terminationPoint : terminationPoints) {
806 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
807 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
808 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
809 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
810 // if ephemeral port 45002 is in use, ofPort is set to 1
811 Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(new Long(1)));
812 LOG.info("ofPort: {}", ofPort);
816 // UPDATE- Not Applicable. From the OpenVSwitch Documentation:
817 // "A client should ideally set this column’s value in the same database transaction that it uses to create
821 Assert.assertTrue(deleteBridge(connectionInfo));
822 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
826 public void testCRDTerminationPointOfPortRequest() throws InterruptedException {
827 final Long OFPORT_EXPECTED = 45008L;
828 final Long OFPORT_INPUT = 45008L;
830 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
831 connectOvsdbNode(connectionInfo);
834 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
835 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
836 Assert.assertNotNull(bridge);
837 NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
838 connectionInfo, bridge.getBridgeName()));
839 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
840 createGenericOvsdbTerminationPointAugmentationBuilder();
841 String portName = "testOfPortRequest";
842 ovsdbTerminationBuilder.setName(portName);
843 Integer ofPortRequestExpected = OFPORT_EXPECTED.intValue();
844 ovsdbTerminationBuilder.setOfport(OFPORT_INPUT);
845 ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected);
846 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
847 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
848 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
849 Assert.assertNotNull(terminationPointNode);
852 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
853 for (TerminationPoint terminationPoint : terminationPoints) {
854 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
855 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
856 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
857 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
858 // if ephemeral port 45008 is in use, ofPort is set to 1
859 Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(new Long(1)));
860 LOG.info("ofPort: {}", ofPort);
862 Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest();
863 Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected));
864 LOG.info("ofPortRequest: {}", ofPortRequest);
868 // UPDATE- Not Applicable. From the OpenVSwitch documentation:
869 // "A client should ideally set this column’s value in the same database transaction that it uses to create
873 Assert.assertTrue(deleteBridge(connectionInfo));
874 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
877 private interface KeyValueBuilder<T> {
878 T build(String testName, String key, String value);
879 T[] build(String testName, int count, String key, String value);
883 private abstract static class BaseKeyValueBuilder<T> implements KeyValueBuilder<T> {
884 private static final int COUNTER_START = 0;
885 private int counter = COUNTER_START;
886 private final Class<T> builtClass;
888 protected abstract Builder<T> builder();
890 protected abstract void setKey(Builder<T> builder, String key);
892 protected abstract void setValue(Builder<T> builder, String value);
894 @SuppressWarnings("unchecked")
895 private BaseKeyValueBuilder() {
896 builtClass = (Class<T>) this.getClass().getSuperclass().getTypeParameters()[0].getClass();
900 public final T build(final String testName, final String key, final String value) {
901 final Builder<T> builder = builder();
904 setKey(builder, String.format(FORMAT_STR, testName, key, this.counter));
907 setValue(builder, String.format(FORMAT_STR, testName, value, this.counter));
909 return builder.build();
912 @SuppressWarnings("unchecked")
914 public final T[] build(final String testName, final int count, final String key, final String value) {
915 final T[] instances = (T[]) Array.newInstance(builtClass, count);
916 for (int idx = 0; idx < count; idx++) {
917 instances[idx] = build(testName, key, value);
923 public final void reset() {
924 this.counter = COUNTER_START;
928 private static final class SouthboundPortExternalIdsBuilder extends BaseKeyValueBuilder<PortExternalIds> {
930 protected Builder<PortExternalIds> builder() {
931 return new PortExternalIdsBuilder();
935 protected void setKey(Builder<PortExternalIds> builder, String key) {
936 ((PortExternalIdsBuilder) builder).setExternalIdKey(key);
940 protected void setValue(Builder<PortExternalIds> builder, String value) {
941 ((PortExternalIdsBuilder) builder).setExternalIdValue(value);
945 private static final class SouthboundInterfaceExternalIdsBuilder extends BaseKeyValueBuilder<InterfaceExternalIds> {
947 protected Builder<InterfaceExternalIds> builder() {
948 return new InterfaceExternalIdsBuilder();
952 protected void setKey(Builder<InterfaceExternalIds> builder, String key) {
953 ((InterfaceExternalIdsBuilder) builder).setExternalIdKey(key);
957 protected void setValue(Builder<InterfaceExternalIds> builder, String value) {
958 ((InterfaceExternalIdsBuilder) builder).setExternalIdValue(value);
962 private static final class SouthboundOptionsBuilder extends BaseKeyValueBuilder<Options> {
964 protected Builder<Options> builder() {
965 return new OptionsBuilder();
969 protected void setKey(Builder<Options> builder, String key) {
970 ((OptionsBuilder) builder).setOption(key);
974 protected void setValue(Builder<Options> builder, String value) {
975 ((OptionsBuilder) builder).setValue(value);
979 private static final class SouthboundInterfaceOtherConfigsBuilder extends BaseKeyValueBuilder<InterfaceOtherConfigs> {
981 protected Builder<InterfaceOtherConfigs> builder() {
982 return new InterfaceOtherConfigsBuilder();
986 protected void setKey(Builder<InterfaceOtherConfigs> builder, String key) {
987 ((InterfaceOtherConfigsBuilder) builder).setOtherConfigKey(key);
991 protected void setValue(Builder<InterfaceOtherConfigs> builder, String value) {
992 ((InterfaceOtherConfigsBuilder) builder).setOtherConfigValue(value);
996 private static final class SouthboundPortOtherConfigsBuilder extends BaseKeyValueBuilder<PortOtherConfigs> {
998 protected Builder<PortOtherConfigs> builder() {
999 return new PortOtherConfigsBuilder();
1003 protected void setKey(Builder<PortOtherConfigs> builder, String key) {
1004 ((PortOtherConfigsBuilder) builder).setOtherConfigKey(key);
1008 protected void setValue(Builder<PortOtherConfigs> builder, String value) {
1009 ((PortOtherConfigsBuilder) builder).setOtherConfigValue(value);
1013 private static final class SouthboundBridgeOtherConfigsBuilder extends BaseKeyValueBuilder<BridgeOtherConfigs> {
1015 protected Builder<BridgeOtherConfigs> builder() {
1016 return new BridgeOtherConfigsBuilder();
1020 protected void setKey(Builder<BridgeOtherConfigs> builder, String key) {
1021 ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigKey(key);
1025 protected void setValue(Builder<BridgeOtherConfigs> builder, String value) {
1026 ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigValue(value);
1030 private static final class SouthboundBridgeExternalIdsBuilder extends BaseKeyValueBuilder<BridgeExternalIds> {
1032 protected Builder<BridgeExternalIds> builder() {
1033 return new BridgeExternalIdsBuilder();
1037 protected void setKey(Builder<BridgeExternalIds> builder, String key) {
1038 ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdKey(key);
1042 protected void setValue(Builder<BridgeExternalIds> builder, String value) {
1043 ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdValue(value);
1048 * Generates the test cases involved in testing key-value-based data. See inline comments for descriptions of
1049 * the particular cases considered.
1051 private static <T> List<SouthboundTestCase<T>> generateKeyValueTestCases(
1052 KeyValueBuilder<T> builder, String idKey, String idValue) {
1053 List<SouthboundTestCase<T>> testCases = new ArrayList<>();
1055 final String GOOD_KEY = "GoodKey";
1056 final String GOOD_VALUE = "GoodValue";
1057 final String NO_VALUE_FOR_KEY = "NoValueForKey";
1058 final String NO_KEY_FOR_VALUE = "NoKeyForValue";
1060 // Test Case 1: TestOne
1061 // Test Type: Positive
1062 // Description: Create a termination point with one value
1063 // Expected: A port is created with the single value specified below
1064 final String testOneName = "TestOne";
1065 testCases.add(new SouthboundTestCaseBuilder<T>()
1067 .input(builder.build(testOneName, idKey, idValue))
1068 .expectInputAsOutput()
1072 // Test Case 2: TestFive
1073 // Test Type: Positive
1074 // Description: Create a termination point with multiple (five) values
1075 // Expected: A port is created with the five values specified below
1076 final String testFiveName = "TestFive";
1077 testCases.add(new SouthboundTestCaseBuilder<T>()
1079 .input(builder.build(testFiveName, 5, idKey, idValue))
1080 .expectInputAsOutput()
1084 // Test Case 3: TestOneGoodOneMalformedValue
1085 // Test Type: Negative
1087 // One perfectly fine input
1088 // (TestOneGoodOneMalformedValue_GoodKey_1,
1089 // TestOneGoodOneMalformedValue_GoodValue_1)
1090 // and one malformed input which only has key specified
1091 // (TestOneGoodOneMalformedValue_NoValueForKey_2,
1093 // Expected: A port is created without any values
1094 final String testOneGoodOneMalformedValueName = "TestOneGoodOneMalformedValue";
1095 testCases.add(new SouthboundTestCaseBuilder<T>()
1096 .name(testOneGoodOneMalformedValueName)
1098 builder.build(testOneGoodOneMalformedValueName, GOOD_KEY, GOOD_VALUE),
1099 builder.build(testOneGoodOneMalformedValueName, NO_VALUE_FOR_KEY, null)
1105 // Test Case 4: TestOneGoodOneMalformedKey
1106 // Test Type: Negative
1108 // One perfectly fine input
1109 // (TestOneGoodOneMalformedKey_GoodKey_1,
1110 // TestOneGoodOneMalformedKey_GoodValue_1)
1111 // and one malformed input which only has value specified
1113 // TestOneGoodOneMalformedKey_NoKeyForValue_2)
1114 // Expected: A port is created without any values
1115 final String testOneGoodOneMalformedKeyName = "TestOneGoodOneMalformedKey";
1116 testCases.add(new SouthboundTestCaseBuilder<T>()
1117 .name(testOneGoodOneMalformedKeyName)
1119 builder.build(testOneGoodOneMalformedKeyName, GOOD_KEY, GOOD_VALUE),
1120 builder.build(testOneGoodOneMalformedKeyName, null, NO_KEY_FOR_VALUE)
1130 * Generates the test cases involved in testing PortExternalIds. See inline comments for descriptions of
1131 * the particular cases considered.
1133 private List<SouthboundTestCase<PortExternalIds>> generatePortExternalIdsTestCases() {
1134 return generateKeyValueTestCases(new SouthboundPortExternalIdsBuilder(), "PortExternalIdKey",
1135 "PortExternalIdValue");
1139 * Tests the CRUD operations for <code>Port</code>
1140 * <code>external_ids</code>.
1142 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for
1143 * specific test case information
1146 public void testCRUDTerminationPointPortExternalIds()
1147 throws InterruptedException, ExecutionException {
1149 final String TEST_PREFIX = "CRUDTPPortExternalIds";
1151 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1152 connectOvsdbNode(connectionInfo);
1154 // updateFromTestCases represent the original test case value.
1155 // updateToTestCases represent the new value after the update has been
1157 List<SouthboundTestCase<PortExternalIds>> updateFromTestCases = generatePortExternalIdsTestCases();
1158 List<SouthboundTestCase<PortExternalIds>> updateToTestCases = generatePortExternalIdsTestCases();
1159 String testBridgeName;
1160 String testPortName;
1163 // multihreads the test using NUM_THREADS
1164 ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
1165 for (SouthboundTestCase<PortExternalIds> fromTestCase : updateFromTestCases) {
1166 for (SouthboundTestCase<PortExternalIds> toTestCase : updateToTestCases) {
1167 testPortName = testBridgeName = String.format(FORMAT_STR,
1168 TEST_PREFIX, toTestCase.name, counter);
1170 executor.submit(new TestCRUDTerminationPointRunnable<>(
1171 new SouthboundTestHelper<PortExternalIds>() {
1173 public List<PortExternalIds> readValues(
1174 OvsdbTerminationPointAugmentation augmentation) {
1175 return augmentation.getPortExternalIds();
1179 public void writeValues(
1180 OvsdbTerminationPointAugmentationBuilder augmentationBuilder,
1181 List<PortExternalIds> updateFromInput) {
1182 augmentationBuilder.setPortExternalIds(updateFromInput);
1185 connectionInfo, testBridgeName, testPortName,
1186 fromTestCase.inputValues,
1187 fromTestCase.expectedValues,
1188 toTestCase.inputValues,
1189 toTestCase.expectedValues));
1192 executor.shutdown();
1193 executor.awaitTermination(5, TimeUnit.MINUTES);
1194 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1198 * Southbound test helper. Classes implementing this interface are used to provide concrete access to the input and
1199 * output of the underlying augmentation for the type being managed.
1201 * @param <T> The type of data used for the test case.
1203 private interface SouthboundTestHelper<T> {
1205 * Read the values from the augmentation. These would usually be checked against the expected values provided
1206 * for the test case.
1208 * @param augmentation The augmentation to read from.
1209 * @return The values read.
1211 List<T> readValues(OvsdbTerminationPointAugmentation augmentation);
1214 * Write the values to the augmentation (via its builder). This would usually be used to apply the input values
1215 * provided for the test case.
1217 * @param augmentationBuilder The augmentation builder.
1218 * @param values The values to write.
1220 void writeValues(OvsdbTerminationPointAugmentationBuilder augmentationBuilder, List<T> values);
1225 * Test runner used to apply a suite of create/read/update/delete tests. Each instance of a runner expects:
1228 * <li>a helper used to manipulate the appropriate data structures in the termination point augmentation (see
1229 * {@link SouthboundTestHelper});</li>
1230 * <li>connection information for the southbound;</li>
1231 * <li>a name to use for the test bridge (this allows multiple tests to be conducted in parallel against different
1233 * <li>a name to use for the test port;</li>
1234 * <li>the initial input values to use for the termination point augmentation;</li>
1235 * <li>the initial expected values to check the augmentation against;</li>
1236 * <li>the target input values to update the terminal point to;</li>
1237 * <li>the target expected values to check the augmentation point against.</li>
1239 * <p>The following tests are performed:</p>
1241 * <li>the bridge is added;</li>
1242 * <li>the termination point is added, with the provided initial input values;</li>
1243 * <li>the termination point is read from the <em>configuration</em> data store, and checked against the provided
1244 * initial expected values;</li>
1245 * <li>the termination point is read from the <em>operational</em> data store, and checked against the provided
1246 * initial expected values;</li>
1247 * <li>the termination point is updated by merging the provided target input values;</li>
1248 * <li>the termination point is read from the <em>configuration</em> data store, and checked against the provided
1249 * initial <b>and</b> target expected values;</li>
1250 * <li>the termination point is read from the <em>operational</em> data store, and checked against the provided
1251 * initial <b>and</b> target expected values;</li>
1252 * <li>the bridge is deleted.</li>
1255 * @param <T> The type of data used for the test case.
1257 private final class TestCRUDTerminationPointRunnable<T> implements Runnable {
1258 private final SouthboundTestHelper<T> helper;
1259 private final ConnectionInfo connectionInfo;
1260 private final String testBridgeName;
1261 private final String testPortName;
1262 private final List<T> updateFromInput;
1263 private final List<T> updateFromExpected;
1264 private final List<T> updateToInput;
1265 private final List<T> updateToExpected;
1267 private TestCRUDTerminationPointRunnable(
1268 SouthboundTestHelper<T> helper, ConnectionInfo connectionInfo, String testBridgeName,
1269 String testPortName, List<T> updateFromInput, List<T> updateFromExpected, List<T> updateToInput,
1270 List<T> updateToExpected) {
1271 this.helper = helper;
1272 this.connectionInfo = connectionInfo;
1273 this.testBridgeName = testBridgeName;
1274 this.testPortName = testPortName;
1275 this.updateFromInput = updateFromInput;
1276 this.updateFromExpected = updateFromExpected;
1277 this.updateToInput = updateToInput;
1278 this.updateToExpected = updateToExpected;
1284 final int TERMINATION_POINT_TEST_INDEX = 0;
1285 // CREATE: Create the test bridge
1286 Assert.assertTrue(addBridge(connectionInfo, null,
1287 testBridgeName, null, true,
1288 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
1289 true, null, null, null, null));
1290 NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
1291 connectionInfo, new OvsdbBridgeName(testBridgeName)));
1292 OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
1293 createGenericOvsdbTerminationPointAugmentationBuilder();
1294 tpCreateAugmentationBuilder.setName(testPortName);
1295 helper.writeValues(tpCreateAugmentationBuilder, updateFromInput);
1296 Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
1298 // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
1299 // then repeat for OPERATIONAL data store
1300 OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
1301 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1302 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1303 List<T> updateFromConfiguration = null;
1304 if (updateFromConfigurationTerminationPointAugmentation != null) {
1305 updateFromConfiguration =
1306 helper.readValues(updateFromConfigurationTerminationPointAugmentation);
1308 if (updateFromConfiguration != null) {
1309 Assert.assertTrue(updateFromConfiguration.containsAll(updateFromExpected));
1311 OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
1312 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1313 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1314 List<T> updateFromOperational = null;
1315 if (updateFromOperationalTerminationPointAugmentation != null) {
1316 updateFromOperational = helper.readValues(updateFromOperationalTerminationPointAugmentation);
1318 if (updateFromOperational != null) {
1319 Assert.assertTrue(updateFromOperational.containsAll(updateFromExpected));
1322 // UPDATE: update the external_ids
1323 testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
1324 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1325 new OvsdbTerminationPointAugmentationBuilder();
1326 helper.writeValues(tpUpdateAugmentationBuilder, updateToInput);
1327 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1328 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1329 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1330 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1331 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1332 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
1333 tpUpdateBuilder.addAugmentation(
1334 OvsdbTerminationPointAugmentation.class,
1335 tpUpdateAugmentationBuilder.build());
1336 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1337 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1338 portIid, portUpdateNodeBuilder.build());
1339 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1340 Assert.assertTrue(result);
1342 // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
1343 // then repeat for OPERATIONAL data store
1344 OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1345 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1346 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1347 List<T> updateToConfiguration = helper.readValues(updateToConfigurationTerminationPointAugmentation);
1348 Assert.assertTrue(updateToConfiguration.containsAll(updateToExpected));
1349 Assert.assertTrue(updateToConfiguration.containsAll(updateFromExpected));
1350 OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1351 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1352 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1353 List<T> updateToOperational = helper.readValues(updateToOperationalTerminationPointAugmentation);
1354 Assert.assertTrue(updateToOperational.containsAll(updateToExpected));
1355 Assert.assertTrue(updateToOperational.containsAll(updateFromExpected));
1358 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
1359 } catch (InterruptedException e) {
1360 LOG.error("Test interrupted", e);
1367 * Generates the test cases involved in testing InterfaceExternalIds. See inline comments for descriptions of
1368 * the particular cases considered.
1370 private static List<SouthboundTestCase<InterfaceExternalIds>> generateInterfaceExternalIdsTestCases() {
1371 return generateKeyValueTestCases(new SouthboundInterfaceExternalIdsBuilder(), "IntExternalIdKey",
1372 "IntExternalIdValue");
1376 * Tests the CRUD operations for <code>Interface</code> <code>external_ids</code>.
1378 * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1381 public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException, ExecutionException {
1382 final String TEST_PREFIX = "CRUDTPInterfaceExternalIds";
1384 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1385 connectOvsdbNode(connectionInfo);
1387 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
1388 // the update has been performed.
1389 List<SouthboundTestCase<InterfaceExternalIds>> updateFromTestCases = generateInterfaceExternalIdsTestCases();
1390 List<SouthboundTestCase<InterfaceExternalIds>> updateToTestCases = generateInterfaceExternalIdsTestCases();
1391 String testBridgeName;
1392 String testPortName;
1395 // multithreads the test using NUM_THREADS
1396 ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
1397 for (SouthboundTestCase<InterfaceExternalIds> fromTestCase : updateFromTestCases) {
1398 for (SouthboundTestCase<InterfaceExternalIds> toTestCase : updateToTestCases) {
1399 testPortName = testBridgeName = String.format(FORMAT_STR,
1400 TEST_PREFIX, toTestCase.name, counter);
1402 executor.submit(new TestCRUDTerminationPointRunnable<>(
1403 new SouthboundTestHelper<InterfaceExternalIds>() {
1405 public List<InterfaceExternalIds> readValues(
1406 OvsdbTerminationPointAugmentation augmentation) {
1407 return augmentation.getInterfaceExternalIds();
1411 public void writeValues(
1412 OvsdbTerminationPointAugmentationBuilder augmentationBuilder,
1413 List<InterfaceExternalIds> values) {
1414 augmentationBuilder.setInterfaceExternalIds(values);
1417 connectionInfo, testBridgeName, testPortName,
1418 fromTestCase.inputValues,
1419 fromTestCase.expectedValues,
1420 toTestCase.inputValues,
1421 toTestCase.expectedValues));
1424 executor.shutdown();
1425 executor.awaitTermination(5, TimeUnit.MINUTES);
1426 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1430 * Generates the test cases involved in testing TP Options. See inline comments for descriptions of
1431 * the particular cases considered.
1433 private List<SouthboundTestCase<Options>> generateTerminationPointOptionsTestCases() {
1434 return generateKeyValueTestCases(new SouthboundOptionsBuilder(), "TOPOptionsKey", "TPOptionsValue");
1438 * Tests the CRUD operations for <code>TerminationPoint</code> <code>options</code>.
1440 * @see <code>SouthboundIT.generateTerminationPointOptions()</code> for specific test case information
1443 public void testCRUDTerminationPointOptions() throws InterruptedException {
1444 final String TEST_PREFIX = "CRUDTPOptions";
1446 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1447 connectOvsdbNode(connectionInfo);
1449 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
1450 // the update has been performed.
1451 List<SouthboundTestCase<Options>> updateFromTestCases = generateTerminationPointOptionsTestCases();
1452 List<SouthboundTestCase<Options>> updateToTestCases = generateTerminationPointOptionsTestCases();
1453 String testBridgeName;
1454 String testPortName;
1457 ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
1458 for (SouthboundTestCase<Options> fromTestCase : updateFromTestCases) {
1459 for (SouthboundTestCase<Options> toTestCase : updateToTestCases) {
1460 testPortName = testBridgeName = String.format(FORMAT_STR,
1461 TEST_PREFIX, toTestCase.name, counter);
1463 executor.submit(new TestCRUDTerminationPointRunnable<>(
1464 new SouthboundTestHelper<Options>() {
1466 public List<Options> readValues(
1467 OvsdbTerminationPointAugmentation augmentation) {
1468 return augmentation.getOptions();
1472 public void writeValues(
1473 OvsdbTerminationPointAugmentationBuilder augmentationBuilder,
1474 List<Options> values) {
1475 augmentationBuilder.setOptions(values);
1478 connectionInfo, testBridgeName, testPortName,
1479 fromTestCase.inputValues,
1480 fromTestCase.expectedValues,
1481 toTestCase.inputValues,
1482 toTestCase.expectedValues));
1485 executor.shutdown();
1486 executor.awaitTermination(5, TimeUnit.MINUTES);
1487 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1491 * Generates the test cases involved in testing Interface other_configs. See inline comments for descriptions of
1492 * the particular cases considered.
1494 private List<SouthboundTestCase<InterfaceOtherConfigs>> generateInterfaceOtherConfigsTestCases() {
1495 return generateKeyValueTestCases(new SouthboundInterfaceOtherConfigsBuilder(), "IntOtherConfigsKey",
1496 "IntOtherConfigsValue");
1500 * Tests the CRUD operations for <code>Interface</code> <code>other_configs</code>.
1502 * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1505 public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException {
1506 final String TEST_PREFIX = "CRUDTPInterfaceOtherConfigs";
1508 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1509 connectOvsdbNode(connectionInfo);
1511 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
1512 // the update has been performed.
1513 List<SouthboundTestCase<InterfaceOtherConfigs>> updateFromTestCases = generateInterfaceOtherConfigsTestCases();
1514 List<SouthboundTestCase<InterfaceOtherConfigs>> updateToTestCases = generateInterfaceOtherConfigsTestCases();
1515 String testBridgeName;
1516 String testPortName;
1519 ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
1520 for (SouthboundTestCase<InterfaceOtherConfigs> fromTestCase : updateFromTestCases) {
1521 for (SouthboundTestCase<InterfaceOtherConfigs> toTestCase : updateToTestCases) {
1522 testPortName = testBridgeName = String.format(FORMAT_STR,
1523 TEST_PREFIX, toTestCase.name, counter);
1525 executor.submit(new TestCRUDTerminationPointRunnable<>(
1526 new SouthboundTestHelper<InterfaceOtherConfigs>() {
1528 public List<InterfaceOtherConfigs> readValues(
1529 OvsdbTerminationPointAugmentation augmentation) {
1530 return augmentation.getInterfaceOtherConfigs();
1534 public void writeValues(
1535 OvsdbTerminationPointAugmentationBuilder augmentationBuilder,
1536 List<InterfaceOtherConfigs> values) {
1537 augmentationBuilder.setInterfaceOtherConfigs(values);
1540 connectionInfo, testBridgeName, testPortName,
1541 fromTestCase.inputValues,
1542 fromTestCase.expectedValues,
1543 toTestCase.inputValues,
1544 toTestCase.expectedValues));
1547 executor.shutdown();
1548 executor.awaitTermination(5, TimeUnit.MINUTES);
1549 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1553 * Generates the test cases involved in testing Port other_configs. See inline comments for descriptions of
1554 * the particular cases considered.
1556 private List<SouthboundTestCase<PortOtherConfigs>> generatePortOtherConfigsTestCases() {
1557 return generateKeyValueTestCases(new SouthboundPortOtherConfigsBuilder(), "PortOtherConfigsKey",
1558 "PortOtherConfigsValue");
1562 * Tests the CRUD operations for <code>Port</code> <code>other_configs</code>.
1564 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1567 public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException {
1568 final String TEST_PREFIX = "CRUDTPPortOtherConfigs";
1570 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1571 connectOvsdbNode(connectionInfo);
1573 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
1574 // the update has been performed.
1575 List<SouthboundTestCase<PortOtherConfigs>> updateFromTestCases = generatePortOtherConfigsTestCases();
1576 List<SouthboundTestCase<PortOtherConfigs>> updateToTestCases = generatePortOtherConfigsTestCases();
1577 String testBridgeName;
1578 String testPortName;
1581 ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
1582 for (SouthboundTestCase<PortOtherConfigs> fromTestCase : updateFromTestCases) {
1583 for (SouthboundTestCase<PortOtherConfigs> toTestCase : updateToTestCases) {
1584 testPortName = testBridgeName = String.format(FORMAT_STR,
1585 TEST_PREFIX, toTestCase.name, counter);
1587 executor.submit(new TestCRUDTerminationPointRunnable<>(
1588 new SouthboundTestHelper<PortOtherConfigs>() {
1590 public List<PortOtherConfigs> readValues(
1591 OvsdbTerminationPointAugmentation augmentation) {
1592 return augmentation.getPortOtherConfigs();
1596 public void writeValues(
1597 OvsdbTerminationPointAugmentationBuilder augmentationBuilder,
1598 List<PortOtherConfigs> values) {
1599 augmentationBuilder.setPortOtherConfigs(values);
1602 connectionInfo, testBridgeName, testPortName,
1603 fromTestCase.inputValues,
1604 fromTestCase.expectedValues,
1605 toTestCase.inputValues,
1606 toTestCase.expectedValues));
1609 executor.shutdown();
1610 executor.awaitTermination(5, TimeUnit.MINUTES);
1611 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1615 public void testCRUDTerminationPointVlan() throws InterruptedException {
1616 final Integer CREATED_VLAN_ID = 4000;
1617 final Integer UPDATED_VLAN_ID = 4001;
1619 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1620 connectOvsdbNode(connectionInfo);
1623 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1624 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1625 Assert.assertNotNull(bridge);
1626 NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
1627 connectionInfo, bridge.getBridgeName()));
1628 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1629 createGenericOvsdbTerminationPointAugmentationBuilder();
1630 String portName = "testTerminationPointVlanId";
1631 ovsdbTerminationBuilder.setName(portName);
1632 ovsdbTerminationBuilder.setVlanTag(new VlanId(CREATED_VLAN_ID));
1633 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1634 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1635 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1636 Assert.assertNotNull(terminationPointNode);
1639 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1640 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation;
1641 for (TerminationPoint terminationPoint : terminationPoints) {
1642 ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1643 OvsdbTerminationPointAugmentation.class);
1644 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1645 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1646 Assert.assertNotNull(actualVlanId);
1647 Integer actualVlanIdInt = actualVlanId.getValue();
1648 Assert.assertEquals(CREATED_VLAN_ID, actualVlanIdInt);
1653 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1654 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1655 new OvsdbTerminationPointAugmentationBuilder();
1656 tpUpdateAugmentationBuilder.setVlanTag(new VlanId(UPDATED_VLAN_ID));
1657 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1658 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1659 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1660 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1661 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1662 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1663 tpUpdateBuilder.addAugmentation(
1664 OvsdbTerminationPointAugmentation.class,
1665 tpUpdateAugmentationBuilder.build());
1666 tpUpdateBuilder.setTpId(new TpId(portName));
1667 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1668 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1669 portIid, portUpdateNodeBuilder.build());
1670 Assert.assertTrue(result);
1671 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1673 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1674 terminationPoints = terminationPointNode.getTerminationPoint();
1675 for (TerminationPoint terminationPoint : terminationPoints) {
1676 ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1677 OvsdbTerminationPointAugmentation.class);
1678 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1679 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1680 Assert.assertNotNull(actualVlanId);
1681 Integer actualVlanIdInt = actualVlanId.getValue();
1682 Assert.assertEquals(UPDATED_VLAN_ID, actualVlanIdInt);
1687 Assert.assertTrue(deleteBridge(connectionInfo));
1688 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1692 public void testCRUDTerminationPointVlanModes() throws InterruptedException {
1693 final VlanMode UPDATED_VLAN_MODE = VlanMode.Access;
1694 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1695 connectOvsdbNode(connectionInfo);
1696 VlanMode []vlanModes = VlanMode.values();
1697 for (VlanMode vlanMode : vlanModes) {
1699 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1700 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1701 Assert.assertNotNull(bridge);
1702 NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
1703 connectionInfo, bridge.getBridgeName()));
1704 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1705 createGenericOvsdbTerminationPointAugmentationBuilder();
1706 String portName = "testTerminationPointVlanMode" + vlanMode.toString();
1707 ovsdbTerminationBuilder.setName(portName);
1708 ovsdbTerminationBuilder.setVlanMode(vlanMode);
1709 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1710 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1711 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1712 Assert.assertNotNull(terminationPointNode);
1715 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1716 for (TerminationPoint terminationPoint : terminationPoints) {
1717 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1718 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1719 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1721 Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode));
1726 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1727 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1728 new OvsdbTerminationPointAugmentationBuilder();
1729 tpUpdateAugmentationBuilder.setVlanMode(UPDATED_VLAN_MODE);
1730 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1731 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1732 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1733 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1734 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1735 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1736 tpUpdateBuilder.addAugmentation(
1737 OvsdbTerminationPointAugmentation.class,
1738 tpUpdateAugmentationBuilder.build());
1739 tpUpdateBuilder.setTpId(new TpId(portName));
1740 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1741 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1742 portIid, portUpdateNodeBuilder.build());
1743 Assert.assertTrue(result);
1744 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1746 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1747 terminationPoints = terminationPointNode.getTerminationPoint();
1748 for (TerminationPoint terminationPoint : terminationPoints) {
1749 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1750 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1751 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1753 Assert.assertEquals(UPDATED_VLAN_MODE, ovsdbTerminationPointAugmentation.getVlanMode());
1758 Assert.assertTrue(deleteBridge(connectionInfo));
1760 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1763 private ArrayList<Set<Integer>> generateVlanSets() {
1764 ArrayList<Set<Integer>> vlanSets = new ArrayList<>();
1766 Set<Integer> emptySet = new HashSet<>();
1767 vlanSets.add(emptySet);
1769 Set<Integer> singleSet = new HashSet<>();
1770 Integer single = 2222;
1771 singleSet.add(single);
1772 vlanSets.add(singleSet);
1774 Set<Integer> minMaxMiddleSet = new HashSet<>();
1776 minMaxMiddleSet.add(min);
1778 minMaxMiddleSet.add(max);
1779 Integer minPlusOne = min + 1;
1780 minMaxMiddleSet.add(minPlusOne);
1781 Integer maxMinusOne = max - 1;
1782 minMaxMiddleSet.add(maxMinusOne);
1783 Integer middle = (max - min) / 2;
1784 minMaxMiddleSet.add(middle);
1785 vlanSets.add(minMaxMiddleSet);
1790 private List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
1791 List<Trunks> trunkList = Lists.newArrayList();
1792 for (Integer trunk : trunkSet) {
1793 TrunksBuilder trunkBuilder = new TrunksBuilder();
1794 trunkBuilder.setTrunk(new VlanId(trunk));
1795 trunkList.add(trunkBuilder.build());
1801 public void testCRUDTerminationPointVlanTrunks() throws InterruptedException {
1802 final List<Trunks> UPDATED_TRUNKS = buildTrunkList(Sets.newHashSet(2011));
1803 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1804 connectOvsdbNode(connectionInfo);
1805 Iterable<Set<Integer>> vlanSets = generateVlanSets();
1807 for (Set<Integer> vlanSet : vlanSets) {
1810 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1811 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1812 Assert.assertNotNull(bridge);
1813 NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
1814 connectionInfo, bridge.getBridgeName()));
1815 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1816 createGenericOvsdbTerminationPointAugmentationBuilder();
1817 String portName = "testTerminationPointVlanTrunks" + testCase;
1818 ovsdbTerminationBuilder.setName(portName);
1819 List<Trunks> trunks = buildTrunkList(vlanSet);
1820 ovsdbTerminationBuilder.setTrunks(trunks);
1821 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1822 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1823 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1824 Assert.assertNotNull(terminationPointNode);
1827 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1828 for (TerminationPoint terminationPoint : terminationPoints) {
1829 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1830 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1831 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1832 List<Trunks> actualTrunks = ovsdbTerminationPointAugmentation.getTrunks();
1833 for (Trunks trunk : trunks) {
1834 Assert.assertTrue(actualTrunks.contains(trunk));
1841 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1842 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1843 new OvsdbTerminationPointAugmentationBuilder();
1844 tpUpdateAugmentationBuilder.setTrunks(UPDATED_TRUNKS);
1845 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1846 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1847 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1848 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1849 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1850 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1851 tpUpdateBuilder.addAugmentation(
1852 OvsdbTerminationPointAugmentation.class,
1853 tpUpdateAugmentationBuilder.build());
1854 tpUpdateBuilder.setTpId(new TpId(portName));
1855 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1856 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1857 portIid, portUpdateNodeBuilder.build());
1858 Assert.assertTrue(result);
1859 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1861 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1862 terminationPoints = terminationPointNode.getTerminationPoint();
1863 for (TerminationPoint terminationPoint : terminationPoints) {
1864 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1865 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1866 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1868 Assert.assertEquals(UPDATED_TRUNKS, ovsdbTerminationPointAugmentation.getTrunks());
1873 Assert.assertTrue(deleteBridge(connectionInfo));
1875 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1879 public void testGetOvsdbNodes() throws InterruptedException {
1880 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1881 connectOvsdbNode(connectionInfo);
1882 InstanceIdentifier<Topology> topologyPath = InstanceIdentifier
1883 .create(NetworkTopology.class)
1884 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
1886 Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath);
1887 InstanceIdentifier<Node> expectedNodeIid = createInstanceIdentifier(connectionInfo);
1888 NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class, NodeKey.class).getNodeId();
1889 Node foundNode = null;
1890 Assert.assertNotNull("Expected to find topology: " + topologyPath, topology);
1891 Assert.assertNotNull("Expected to find some nodes" + topology.getNode());
1892 LOG.info("expectedNodeId: {}, getNode: {}", expectedNodeId, topology.getNode());
1893 for (Node node : topology.getNode()) {
1894 if (node.getNodeId().getValue().equals(expectedNodeId.getValue())) {
1899 Assert.assertNotNull("Expected to find Node: " + expectedNodeId, foundNode);
1900 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1904 * Generates the test cases involved in testing BridgeOtherConfigs. See inline comments for descriptions of
1905 * the particular cases considered.
1907 private List<SouthboundTestCase<BridgeOtherConfigs>> generateBridgeOtherConfigsTestCases() {
1908 return generateKeyValueTestCases(new SouthboundBridgeOtherConfigsBuilder(), "BridgeOtherConfigsKey",
1909 "BridgeOtherConfigsValue");
1913 * @see <code>SouthboundIT.testCRUDBridgeOtherConfigs()</code>
1914 * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
1916 private void assertExpectedBridgeOtherConfigsExist( List<BridgeOtherConfigs> expected,
1917 List<BridgeOtherConfigs> test ) {
1919 if (expected != null) {
1920 for (BridgeOtherConfigs expectedOtherConfig : expected) {
1921 Assert.assertTrue(test.contains(expectedOtherConfig));
1927 * @see <code>SouthboundIT.generateBridgeOtherConfigsTestCases()</code> for specific test case information.
1930 public void testCRUDBridgeOtherConfigs() throws InterruptedException {
1931 final String TEST_BRIDGE_PREFIX = "CRUDBridgeOtherConfigs";
1932 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1933 connectOvsdbNode(connectionInfo);
1934 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
1935 // the update has been performed.
1936 List<SouthboundTestCase<BridgeOtherConfigs>> updateFromTestCases = generateBridgeOtherConfigsTestCases();
1937 List<SouthboundTestCase<BridgeOtherConfigs>> updateToTestCases = generateBridgeOtherConfigsTestCases();
1938 String testBridgeName;
1941 ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
1942 for (SouthboundTestCase<BridgeOtherConfigs> fromTestCase : updateFromTestCases) {
1943 for (SouthboundTestCase<BridgeOtherConfigs> toTestCase : updateToTestCases) {
1944 testBridgeName = String.format(FORMAT_STR, TEST_BRIDGE_PREFIX, toTestCase.name, counter);
1946 TestCRUDBridgeOtherConfigsRunnable testRunnable =
1947 new TestCRUDBridgeOtherConfigsRunnable(
1948 connectionInfo, testBridgeName,
1949 fromTestCase.inputValues,
1950 fromTestCase.expectedValues,
1951 toTestCase.inputValues,
1952 toTestCase.expectedValues);
1953 executor.submit(testRunnable);
1956 executor.shutdown();
1957 executor.awaitTermination(5, TimeUnit.MINUTES);
1959 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1962 class TestCRUDBridgeOtherConfigsRunnable implements Runnable {
1964 ConnectionInfo connectionInfo;
1965 String testBridgeName;
1966 List<BridgeOtherConfigs> updateFromInputOtherConfigs;
1967 List<BridgeOtherConfigs> updateFromExpectedOtherConfigs;
1968 List<BridgeOtherConfigs> updateToInputOtherConfigs;
1969 List<BridgeOtherConfigs> updateToExpectedOtherConfigs;
1971 TestCRUDBridgeOtherConfigsRunnable(
1972 ConnectionInfo connectionInfo, String testBridgeName,
1973 List<BridgeOtherConfigs> updateFromInputOtherConfigs,
1974 List<BridgeOtherConfigs> updateFromExpectedOtherConfigs,
1975 List<BridgeOtherConfigs> updateToInputOtherConfigs,
1976 List<BridgeOtherConfigs> updateToExpectedOtherConfigs) {
1978 this.connectionInfo = connectionInfo;
1979 this.testBridgeName = testBridgeName;
1980 this.updateFromInputOtherConfigs = updateFromInputOtherConfigs;
1981 this.updateFromExpectedOtherConfigs = updateFromExpectedOtherConfigs;
1982 this.updateToInputOtherConfigs = updateToInputOtherConfigs;
1983 this.updateToExpectedOtherConfigs = updateToExpectedOtherConfigs;
1990 } catch (InterruptedException e) {
1991 e.printStackTrace();
1995 public void test() throws InterruptedException {
1996 // CREATE: Create the test bridge
1997 boolean bridgeAdded = addBridge(connectionInfo, null,
1998 testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
1999 true, null, null, null, updateFromInputOtherConfigs);
2000 Assert.assertTrue(bridgeAdded);
2002 // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2003 // then repeat for OPERATIONAL data store
2004 List<BridgeOtherConfigs> updateFromConfigurationOtherConfigs = getBridge(connectionInfo, testBridgeName,
2005 LogicalDatastoreType.CONFIGURATION).getBridgeOtherConfigs();
2006 assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
2007 updateFromConfigurationOtherConfigs);
2008 List<BridgeOtherConfigs> updateFromOperationalOtherConfigs = getBridge(connectionInfo, testBridgeName)
2009 .getBridgeOtherConfigs();
2010 assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
2011 updateFromOperationalOtherConfigs);
2013 // UPDATE: update the external_ids
2014 OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
2015 bridgeAugmentationBuilder.setBridgeOtherConfigs(updateToInputOtherConfigs);
2016 InstanceIdentifier<Node> bridgeIid =
2017 createInstanceIdentifier(connectionInfo,
2018 new OvsdbBridgeName(testBridgeName));
2019 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
2020 Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
2021 bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId());
2022 bridgeNodeBuilder.setKey(bridgeNode.getKey());
2023 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build());
2024 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
2025 bridgeNodeBuilder.build());
2026 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2027 Assert.assertTrue(result);
2029 // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2030 // then repeat for OPERATIONAL data store
2031 List<BridgeOtherConfigs> updateToConfigurationOtherConfigs = getBridge(connectionInfo, testBridgeName,
2032 LogicalDatastoreType.CONFIGURATION).getBridgeOtherConfigs();
2033 assertExpectedBridgeOtherConfigsExist(updateToExpectedOtherConfigs, updateToConfigurationOtherConfigs);
2034 assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
2035 updateToConfigurationOtherConfigs);
2036 List<BridgeOtherConfigs> updateToOperationalOtherConfigs = getBridge(connectionInfo, testBridgeName)
2037 .getBridgeOtherConfigs();
2038 if (updateFromExpectedOtherConfigs != null) {
2039 assertExpectedBridgeOtherConfigsExist(updateToExpectedOtherConfigs,
2040 updateToOperationalOtherConfigs);
2041 assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
2042 updateToOperationalOtherConfigs);
2046 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
2051 * Generates the test cases involved in testing BridgeExternalIds. See inline comments for descriptions of
2052 * the particular cases considered.
2054 private List<SouthboundTestCase<BridgeExternalIds>> generateBridgeExternalIdsTestCases() {
2055 return generateKeyValueTestCases(new SouthboundBridgeExternalIdsBuilder(), "BridgeExternalIdsKey",
2056 "BridgeExternalIdsValue");
2060 * @see <code>SouthboundIT.testCRUDBridgeExternalIds()</code>
2061 * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
2063 private void assertExpectedBridgeExternalIdsExist( List<BridgeExternalIds> expected,
2064 List<BridgeExternalIds> test ) {
2066 if (expected != null) {
2067 for (BridgeExternalIds expectedExternalId : expected) {
2068 Assert.assertTrue(test.contains(expectedExternalId));
2074 * @see <code>SouthboundIT.generateBridgeExternalIdsTestCases()</code> for specific test case information
2077 public void testCRUDBridgeExternalIds() throws InterruptedException {
2078 final String TEST_BRIDGE_PREFIX = "CRUDBridgeExternalIds";
2079 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2080 connectOvsdbNode(connectionInfo);
2081 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
2082 // the update has been performed.
2083 List<SouthboundTestCase<BridgeExternalIds>> updateFromTestCases = generateBridgeExternalIdsTestCases();
2084 List<SouthboundTestCase<BridgeExternalIds>> updateToTestCases = generateBridgeExternalIdsTestCases();
2085 String testBridgeName;
2088 ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
2089 for (SouthboundTestCase<BridgeExternalIds> fromTestCase : updateFromTestCases) {
2090 for (SouthboundTestCase<BridgeExternalIds> toTestCase : updateToTestCases) {
2091 testBridgeName = String.format(FORMAT_STR, TEST_BRIDGE_PREFIX, toTestCase.name, counter);
2093 TestCRUDBridgeExternalIdsRunnable testRunnable =
2094 new TestCRUDBridgeExternalIdsRunnable(
2095 connectionInfo, testBridgeName,
2096 fromTestCase.inputValues,
2097 fromTestCase.expectedValues,
2098 toTestCase.inputValues,
2099 toTestCase.expectedValues);
2100 executor.submit(testRunnable);
2103 executor.shutdown();
2104 executor.awaitTermination(5, TimeUnit.MINUTES);
2106 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
2109 class TestCRUDBridgeExternalIdsRunnable implements Runnable {
2110 ConnectionInfo connectionInfo;
2111 String testBridgeName;
2112 List<BridgeExternalIds> updateFromInputExternalIds;
2113 List<BridgeExternalIds> updateFromExpectedExternalIds;
2114 List<BridgeExternalIds> updateToInputExternalIds;
2115 List<BridgeExternalIds> updateToExpectedExternalIds;
2117 TestCRUDBridgeExternalIdsRunnable(
2118 ConnectionInfo connectionInfo, String testBridgeName,
2119 List<BridgeExternalIds> updateFromInputExternalIds,
2120 List<BridgeExternalIds> updateFromExpectedExternalIds,
2121 List<BridgeExternalIds> updateToInputExternalIds,
2122 List<BridgeExternalIds> updateToExpectedExternalIds) {
2124 this.connectionInfo = connectionInfo;
2125 this.testBridgeName = testBridgeName;
2126 this.updateFromInputExternalIds = updateFromInputExternalIds;
2127 this.updateFromExpectedExternalIds = updateFromExpectedExternalIds;
2128 this.updateToInputExternalIds = updateToInputExternalIds;
2129 this.updateToExpectedExternalIds = updateToExpectedExternalIds;
2136 } catch (InterruptedException e) {
2137 e.printStackTrace();
2141 public void test() throws InterruptedException {
2142 // CREATE: Create the test bridge
2143 boolean bridgeAdded = addBridge(connectionInfo, null,
2144 testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
2145 true, null, updateFromInputExternalIds, null, null);
2146 Assert.assertTrue(bridgeAdded);
2148 // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2149 // then repeat for OPERATIONAL data store
2150 List<BridgeExternalIds> updateFromConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
2151 LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
2152 assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromConfigurationExternalIds);
2153 List<BridgeExternalIds> updateFromOperationalExternalIds = getBridge(connectionInfo, testBridgeName)
2154 .getBridgeExternalIds();
2155 assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromOperationalExternalIds);
2157 // UPDATE: update the external_ids
2158 OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
2159 bridgeAugmentationBuilder.setBridgeExternalIds(updateToInputExternalIds);
2160 InstanceIdentifier<Node> bridgeIid =
2161 createInstanceIdentifier(connectionInfo,
2162 new OvsdbBridgeName(testBridgeName));
2163 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
2164 Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
2165 bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId());
2166 bridgeNodeBuilder.setKey(bridgeNode.getKey());
2167 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build());
2168 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
2169 bridgeNodeBuilder.build());
2170 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2171 Assert.assertTrue(result);
2173 // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2174 // then repeat for OPERATIONAL data store
2175 List<BridgeExternalIds> updateToConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
2176 LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
2177 assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
2178 assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateToConfigurationExternalIds);
2179 List<BridgeExternalIds> updateToOperationalExternalIds = getBridge(connectionInfo, testBridgeName)
2180 .getBridgeExternalIds();
2181 if (updateFromExpectedExternalIds != null) {
2182 assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds);
2183 assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateToOperationalExternalIds);
2187 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
2191 public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
2192 return SouthboundMapper.createInstanceIdentifier(createManagedNodeId(key, bridgeName));
2195 public static NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
2196 return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
2199 public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
2200 return new NodeId(createNodeId(ip,port).getValue()
2201 + "/" + SouthboundConstants.BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
2204 public static NodeId createNodeId(IpAddress ip, PortNumber port) {
2205 String uriString = SouthboundConstants.OVSDB_URI_PREFIX + "://"
2206 + new String(ip.getValue()) + ":" + port.getValue();
2207 Uri uri = new Uri(uriString);
2208 return new NodeId(uri);
2211 public static NodeKey createNodeKey(IpAddress ip, PortNumber port) {
2212 return new NodeKey(createNodeId(ip,port));
2215 public static Node createNode(ConnectionInfo key) {
2216 NodeBuilder nodeBuilder = new NodeBuilder();
2217 nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(),key.getRemotePort()));
2218 nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
2219 return nodeBuilder.build();
2222 public static OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
2223 OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
2224 ovsdbNodeBuilder.setConnectionInfo(key);
2225 return ovsdbNodeBuilder.build();
2228 public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
2229 NodeKey nodeKey = iid.firstKeyOf(Node.class, NodeKey.class);
2230 return nodeKey.getNodeId();
2235 * Representation of a southbound test case. Each test case has a name, a list of input values and a list of
2236 * expected values. The input values are provided to the augmentation builder, and the expected values are checked
2237 * against the output of the resulting augmentation.
2240 * Instances of this class are immutable.
2243 * @param <T> The type of data used for the test case.
2245 private static final class SouthboundTestCase<T> {
2246 private final String name;
2247 private final List<T> inputValues;
2248 private final List<T> expectedValues;
2251 * Creates an instance of a southbound test case.
2253 * @param name The test case's name.
2254 * @param inputValues The input values (provided as input to the underlying augmentation builder).
2255 * @param expectedValues The expected values (checked against the output of the underlying augmentation).
2257 public SouthboundTestCase(
2258 final String name, final List<T> inputValues, final List<T> expectedValues) {
2260 this.inputValues = inputValues;
2261 this.expectedValues = expectedValues;
2266 * Southbound test case builder.
2268 * @param <T> The type of data used for the test case.
2270 private static final class SouthboundTestCaseBuilder<T> {
2271 private String name;
2272 private List<T> inputValues;
2273 private List<T> expectedValues;
2276 * Creates a builder. Builders may be reused, the generated immutable instances are independent of the
2277 * builders. There are no default values.
2279 public SouthboundTestCaseBuilder() {
2284 * Sets the test case's name.
2286 * @param name The test case's name.
2287 * @return The builder.
2289 public SouthboundTestCaseBuilder<T> name(final String name) {
2295 * Sets the input values.
2297 * @param inputValues The input values.
2298 * @return The builder.
2301 public final SouthboundTestCaseBuilder<T> input(final T... inputValues) {
2302 this.inputValues = Lists.newArrayList(inputValues);
2307 * Sets the expected output values.
2309 * @param expectedValues The expected output values.
2310 * @return The builder.
2313 public final SouthboundTestCaseBuilder<T> expect(final T... expectedValues) {
2314 this.expectedValues = Lists.newArrayList(expectedValues);
2319 * Indicates that the provided input values should be expected as output values.
2321 * @return The builder.
2323 public SouthboundTestCaseBuilder<T> expectInputAsOutput() {
2324 this.expectedValues = this.inputValues;
2329 * Builds an immutable instance representing the test case.
2331 * @return The test case.
2333 @SuppressWarnings("unchecked")
2334 public SouthboundTestCase<T> build() {
2335 return new SouthboundTestCase<>(name, inputValues, expectedValues);