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.lang.reflect.ParameterizedType;
27 import java.lang.reflect.Type;
28 import java.net.InetAddress;
29 import java.net.UnknownHostException;
30 import java.util.ArrayList;
31 import java.util.HashSet;
32 import java.util.List;
33 import java.util.Properties;
35 import java.util.concurrent.ExecutionException;
36 import java.util.concurrent.ExecutorService;
37 import java.util.concurrent.Executors;
38 import java.util.concurrent.TimeUnit;
40 import javax.inject.Inject;
42 import org.junit.Assert;
43 import org.junit.Before;
44 import org.junit.Test;
45 import org.junit.runner.RunWith;
46 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
47 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
48 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
49 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
50 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
51 import org.opendaylight.ovsdb.southbound.SouthboundProvider;
52 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntry;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
95 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
96 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
97 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
98 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
99 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
100 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
101 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
102 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
103 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
104 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
105 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
106 import org.opendaylight.yangtools.concepts.Builder;
107 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
108 import org.ops4j.pax.exam.Configuration;
109 import org.ops4j.pax.exam.Option;
110 import org.ops4j.pax.exam.junit.PaxExam;
111 import org.ops4j.pax.exam.karaf.options.KarafDistributionOption;
112 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
113 import org.ops4j.pax.exam.options.MavenUrlReference;
114 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
115 import org.ops4j.pax.exam.spi.reactors.PerClass;
116 import org.osgi.framework.BundleContext;
117 import org.slf4j.Logger;
118 import org.slf4j.LoggerFactory;
121 * Integration tests for southbound-impl
123 * @author Sam Hague (shague@redhat.com)
125 @RunWith(PaxExam.class)
126 @ExamReactorStrategy(PerClass.class)
127 public class SouthboundIT extends AbstractMdsalTestBase {
128 private static final String NETDEV_DP_TYPE = "netdev";
129 private static final Logger LOG = LoggerFactory.getLogger(SouthboundIT.class);
130 private static final int OVSDB_UPDATE_TIMEOUT = 1000;
131 private static final String FORMAT_STR = "%s_%s_%d";
132 public static final int NUM_THREADS = 1;
133 private static String addressStr;
134 private static int portNumber;
135 private static String connectionType;
136 private static Boolean setup = false;
137 private static MdsalUtils mdsalUtils = null;
139 // TODO Constants copied from AbstractConfigTestBase, need to be removed (see TODO below)
140 private static final String PAX_EXAM_UNPACK_DIRECTORY = "target/exam";
141 private static final String KARAF_DEBUG_PORT = "5005";
142 private static final String KARAF_DEBUG_PROP = "karaf.debug";
143 private static final String KEEP_UNPACK_DIRECTORY_PROP = "karaf.keep.unpack";
146 private BundleContext bundleContext;
149 public Option[] config() {
150 // TODO Figure out how to use the parent Karaf setup, then just use super.config()
151 Option[] options = new Option[] {
152 when(Boolean.getBoolean(KARAF_DEBUG_PROP))
153 .useOptions(KarafDistributionOption.debugConfiguration(KARAF_DEBUG_PORT, true)),
154 karafDistributionConfiguration().frameworkUrl(getKarafDistro())
155 .unpackDirectory(new File(PAX_EXAM_UNPACK_DIRECTORY))
156 .useDeployFolder(false),
157 when(Boolean.getBoolean(KEEP_UNPACK_DIRECTORY_PROP)).useOptions(keepRuntimeFolder()),
158 // Works only if we don't specify the feature repo and name
160 Option[] propertyOptions = getPropertiesOptions();
161 Option[] otherOptions = getOtherOptions();
162 Option[] combinedOptions = new Option[options.length + propertyOptions.length + otherOptions.length];
163 System.arraycopy(options, 0, combinedOptions, 0, options.length);
164 System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length);
165 System.arraycopy(otherOptions, 0, combinedOptions, options.length + propertyOptions.length,
166 otherOptions.length);
167 return combinedOptions;
170 private Option[] getOtherOptions() {
171 return new Option[] {
172 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
178 public String getKarafDistro() {
180 .groupId("org.opendaylight.ovsdb")
181 .artifactId("southbound-karaf")
182 .versionAsInProject()
188 public String getModuleName() {
189 return "southbound-impl";
193 public String getInstanceName() {
194 return "southbound-default";
198 public MavenUrlReference getFeatureRepo() {
200 .groupId("org.opendaylight.ovsdb")
201 .artifactId("southbound-features")
202 .classifier("features")
204 .versionAsInProject();
208 public String getFeatureName() {
209 return "odl-ovsdb-southbound-impl-ui";
212 protected String usage() {
213 return "Integration Test needs a valid connection configuration as follows :\n"
214 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
215 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
219 public Option getLoggingOption() {
221 editConfigurationFilePut(SouthboundITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
222 "log4j.logger.org.opendaylight.ovsdb",
223 LogLevelOption.LogLevel.TRACE.name()),
224 super.getLoggingOption());
227 private Option[] getPropertiesOptions() {
228 Properties props = new Properties(System.getProperties());
229 String addressStr = props.getProperty(SouthboundITConstants.SERVER_IPADDRESS,
230 SouthboundITConstants.DEFAULT_SERVER_IPADDRESS);
231 String portStr = props.getProperty(SouthboundITConstants.SERVER_PORT,
232 SouthboundITConstants.DEFAULT_SERVER_PORT);
233 String connectionType = props.getProperty(SouthboundITConstants.CONNECTION_TYPE,
234 SouthboundITConstants.CONNECTION_TYPE_ACTIVE);
236 LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
237 connectionType, addressStr, portStr);
239 return new Option[] {
240 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
241 SouthboundITConstants.SERVER_IPADDRESS, addressStr),
242 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
243 SouthboundITConstants.SERVER_PORT, portStr),
244 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
245 SouthboundITConstants.CONNECTION_TYPE, connectionType),
251 public void setup() throws InterruptedException {
253 LOG.info("Skipping setUp, already initialized");
259 } catch (Exception e) {
262 //dataBroker = getSession().getSALService(DataBroker.class);
264 DataBroker dataBroker = SouthboundProvider.getDb();
265 Assert.assertNotNull("db should not be null", dataBroker);
267 addressStr = bundleContext.getProperty(SouthboundITConstants.SERVER_IPADDRESS);
268 String portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT);
270 portNumber = Integer.parseInt(portStr);
271 } catch (NumberFormatException e) {
272 fail("Invalid port number " + portStr + System.lineSeparator() + usage());
274 connectionType = bundleContext.getProperty(SouthboundITConstants.CONNECTION_TYPE);
276 LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
277 connectionType, addressStr, portNumber);
278 if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_ACTIVE)) {
279 if (addressStr == null) {
284 mdsalUtils = new MdsalUtils(dataBroker);
289 * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
290 * 6640. This test will wait for incoming connections for {@link SouthboundITConstants#CONNECTION_INIT_TIMEOUT} ms.
292 * @throws InterruptedException
295 public void testPassiveNode() throws InterruptedException {
296 if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_PASSIVE)) {
297 //Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
298 Thread.sleep(SouthboundITConstants.CONNECTION_INIT_TIMEOUT);
302 private ConnectionInfo getConnectionInfo(final String addressStr, final int portNumber) {
303 InetAddress inetAddress = null;
305 inetAddress = InetAddress.getByName(addressStr);
306 } catch (UnknownHostException e) {
307 fail("Could not resolve " + addressStr + ": " + e);
310 IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
311 PortNumber port = new PortNumber(portNumber);
313 final ConnectionInfo connectionInfo = new ConnectionInfoBuilder()
314 .setRemoteIp(address)
317 LOG.info("connectionInfo: {}", connectionInfo);
318 return connectionInfo;
321 private String connectionInfoToString(final ConnectionInfo connectionInfo) {
322 return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
326 public void testNetworkTopology() throws InterruptedException {
327 NetworkTopology networkTopology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION,
328 InstanceIdentifier.create(NetworkTopology.class));
329 Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.CONFIGURATION,
332 networkTopology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
333 InstanceIdentifier.create(NetworkTopology.class));
334 Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.OPERATIONAL,
339 public void testOvsdbTopology() throws InterruptedException {
340 InstanceIdentifier<Topology> path = InstanceIdentifier
341 .create(NetworkTopology.class)
342 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
344 Topology topology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
345 Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
348 topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
350 Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
354 private boolean addOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
355 InstanceIdentifier<Node> iid = createInstanceIdentifier(connectionInfo);
356 // Check that the node doesn't already exist (we don't support connecting twice)
357 Assert.assertNull("The OVSDB node has already been added",
358 mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, iid));
359 boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
361 createNode(connectionInfo));
362 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
366 private InstanceIdentifier<Node> createInstanceIdentifier(
367 ConnectionInfo connectionInfo) {
368 return InstanceIdentifier
369 .create(NetworkTopology.class)
370 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
372 createNodeKey(connectionInfo.getRemoteIp(), connectionInfo.getRemotePort()));
375 private Node getOvsdbNode(final ConnectionInfo connectionInfo) {
376 return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
377 createInstanceIdentifier(connectionInfo));
380 private boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
381 boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
382 createInstanceIdentifier(connectionInfo));
383 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
387 private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
388 Assert.assertTrue(addOvsdbNode(connectionInfo));
389 Node node = getOvsdbNode(connectionInfo);
390 Assert.assertNotNull(node);
391 LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
395 private boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
396 Assert.assertTrue(deleteOvsdbNode(connectionInfo));
397 Node node = getOvsdbNode(connectionInfo);
398 Assert.assertNull(node);
399 LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
404 public void testAddDeleteOvsdbNode() throws InterruptedException {
405 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
406 connectOvsdbNode(connectionInfo);
407 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
411 public void testDpdkSwitch() throws InterruptedException {
412 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
413 Node ovsdbNode = connectOvsdbNode(connectionInfo);
414 List<DatapathTypeEntry> datapathTypeEntries = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class)
415 .getDatapathTypeEntry();
416 if (datapathTypeEntries == null) {
417 LOG.info("DPDK not supported on this node.");
419 for (DatapathTypeEntry dpTypeEntry : datapathTypeEntries) {
420 Class<? extends DatapathTypeBase> dpType = dpTypeEntry.getDatapathType();
421 String dpTypeStr = SouthboundConstants.DATAPATH_TYPE_MAP.get(dpType);
422 LOG.info("dp type is {}", dpTypeStr);
423 if (dpTypeStr.equals(NETDEV_DP_TYPE)) {
424 LOG.info("Found a DPDK node; adding a corresponding netdev device");
425 InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo,
426 new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
427 NodeId bridgeNodeId = createManagedNodeId(bridgeIid);
428 addBridge(connectionInfo, bridgeIid, SouthboundITConstants.BRIDGE_NAME, bridgeNodeId, false, null,
429 true, dpType, null, null, null);
431 // Verify that the device is netdev
432 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
433 Assert.assertNotNull(bridge);
434 Assert.assertEquals(dpType, bridge.getDatapathType());
437 final String TEST_PORT_NAME = "testDPDKPort";
438 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
439 createGenericDpdkOvsdbTerminationPointAugmentationBuilder(TEST_PORT_NAME);
440 Assert.assertTrue(addTerminationPoint(bridgeNodeId, TEST_PORT_NAME, ovsdbTerminationBuilder));
442 // Verify that DPDK port was created
443 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
444 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
445 terminationPointIid);
446 Assert.assertNotNull(terminationPointNode);
448 // Verify that each termination point has DPDK ifType
449 Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
451 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
452 for (TerminationPoint terminationPoint : terminationPoints) {
453 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint
454 .getAugmentation(OvsdbTerminationPointAugmentation.class);
455 if (ovsdbTerminationPointAugmentation.getName().equals(TEST_PORT_NAME)) {
456 Class<? extends InterfaceTypeBase> opPort = ovsdbTerminationPointAugmentation
458 Assert.assertEquals(dpdkIfType, opPort);
461 Assert.assertTrue(deleteBridge(connectionInfo));
466 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
470 public void testOvsdbNodeOvsVersion() throws InterruptedException {
471 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
472 Node ovsdbNode = connectOvsdbNode(connectionInfo);
473 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
474 Assert.assertNotNull(ovsdbNodeAugmentation);
475 assertNotNull(ovsdbNodeAugmentation.getOvsVersion());
476 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
480 public void testOpenVSwitchOtherConfig() throws InterruptedException {
481 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
482 Node ovsdbNode = connectOvsdbNode(connectionInfo);
483 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
484 Assert.assertNotNull(ovsdbNodeAugmentation);
485 List<OpenvswitchOtherConfigs> otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
486 if (otherConfigsList != null) {
487 for (OpenvswitchOtherConfigs otherConfig : otherConfigsList) {
488 if (otherConfig.getOtherConfigKey().equals("local_ip")) {
489 LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
492 LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
496 LOG.info("other_config is not present");
498 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
502 public void testOvsdbBridgeControllerInfo() throws InterruptedException {
503 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
504 Node ovsdbNode = connectOvsdbNode(connectionInfo);
505 String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
506 assertNotNull("Failed to get controller target", controllerTarget);
507 List<ControllerEntry> setControllerEntry = createControllerEntry(controllerTarget);
508 Uri setUri = new Uri(controllerTarget);
509 Assert.assertTrue(addBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true,
510 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
511 setControllerEntry, null));
512 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
513 Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME, bridge);
514 Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
515 bridge.getControllerEntry());
516 List<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
517 for (ControllerEntry entry : getControllerEntries) {
518 if (entry.getTarget() != null) {
519 Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
523 Assert.assertTrue(deleteBridge(connectionInfo));
524 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
527 private List<ControllerEntry> createControllerEntry(String controllerTarget) {
528 List<ControllerEntry> controllerEntriesList = new ArrayList<>();
529 controllerEntriesList.add(new ControllerEntryBuilder()
530 .setTarget(new Uri(controllerTarget))
532 return controllerEntriesList;
535 private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
536 final ConnectionInfo connectionInfo) {
537 InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
538 ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
541 private List<ProtocolEntry> createMdsalProtocols() {
542 List<ProtocolEntry> protocolList = new ArrayList<>();
543 ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
544 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
545 protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
549 private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
550 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
551 new OvsdbTerminationPointAugmentationBuilder();
552 ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
553 new InterfaceTypeEntryBuilder()
555 SouthboundMapper.createInterfaceType("internal"))
556 .build().getInterfaceType());
557 return ovsdbTerminationPointAugmentationBuilder;
560 private OvsdbTerminationPointAugmentationBuilder createGenericDpdkOvsdbTerminationPointAugmentationBuilder(
561 final String portName) {
562 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
563 createGenericOvsdbTerminationPointAugmentationBuilder();
564 ovsdbTerminationBuilder.setName(portName);
565 Class<? extends InterfaceTypeBase> ifType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
567 ovsdbTerminationBuilder.setInterfaceType(ifType);
568 return ovsdbTerminationBuilder;
571 private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
572 final OvsdbTerminationPointAugmentationBuilder
573 ovsdbTerminationPointAugmentationBuilder)
574 throws InterruptedException {
576 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
577 NodeBuilder portNodeBuilder = new NodeBuilder();
578 NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
579 portNodeBuilder.setNodeId(portNodeId);
580 TerminationPointBuilder entry = new TerminationPointBuilder();
581 entry.setKey(new TerminationPointKey(new TpId(portName)));
582 entry.addAugmentation(
583 OvsdbTerminationPointAugmentation.class,
584 ovsdbTerminationPointAugmentationBuilder.build());
585 portNodeBuilder.setTerminationPoint(Lists.newArrayList(entry.build()));
586 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
587 portIid, portNodeBuilder.build());
588 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
593 * base method for adding test bridges. Other helper methods used to create bridges should utilize this method.
595 * @param connectionInfo
596 * @param bridgeIid if passed null, one is created
597 * @param bridgeName cannot be null
598 * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
599 * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
600 * @param failMode toggles whether default fail mode is set for the bridge
601 * @param setManagedBy toggles whether to setManagedBy for the bridge
602 * @param dpType if passed null, this parameter is ignored
603 * @param externalIds if passed null, this parameter is ignored
604 * @param otherConfig if passed null, this parameter is ignored
605 * @return success of bridge addition
606 * @throws InterruptedException
608 private boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
609 final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
610 final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
611 final Class<? extends DatapathTypeBase> dpType,
612 final List<BridgeExternalIds> externalIds,
613 final List<ControllerEntry> controllerEntries,
614 final List<BridgeOtherConfigs> otherConfigs) throws InterruptedException {
616 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
617 if (bridgeIid == null) {
618 bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
620 if (bridgeNodeId == null) {
621 bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
623 bridgeNodeBuilder.setNodeId(bridgeNodeId);
624 OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
625 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
626 if (setProtocolEntries) {
627 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
629 if (failMode != null) {
630 ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
633 setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
635 if (dpType != null) {
636 ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
638 if (externalIds != null) {
639 ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
641 if (controllerEntries != null) {
642 ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
644 if (otherConfigs != null) {
645 ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
647 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
648 LOG.debug("Built with the intent to store bridge data {}",
649 ovsdbBridgeAugmentationBuilder.toString());
650 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
651 bridgeIid, bridgeNodeBuilder.build());
652 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
656 private boolean addBridge(final ConnectionInfo connectionInfo, final String bridgeName)
657 throws InterruptedException {
659 return addBridge(connectionInfo, null, bridgeName, null, true,
660 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
663 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
664 return getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
668 * Extract the <code>store</code> type data store contents for the particular bridge identified by
669 * <code>bridgeName</code>.
671 * @param connectionInfo the connection information
672 * @param bridgeName the bridge name
673 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
674 * @return <code>store</code> type data store contents
676 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
677 LogicalDatastoreType store) {
678 Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
679 Assert.assertNotNull(bridgeNode);
680 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
681 Assert.assertNotNull(ovsdbBridgeAugmentation);
682 return ovsdbBridgeAugmentation;
686 * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
687 * identified by <code>bridgeName</code>
689 * @param connectionInfo the connection information
690 * @param bridgeName the bridge name
691 * @see <code>SouthboundIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
692 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
694 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
695 return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
699 * Extract the node contents from <code>store</code> type data store for the
700 * bridge identified by <code>bridgeName</code>
702 * @param connectionInfo the connection information
703 * @param bridgeName the bridge name
704 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
705 * @return <code>store</code> type data store contents
707 private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
708 InstanceIdentifier<Node> bridgeIid =
709 createInstanceIdentifier(connectionInfo,
710 new OvsdbBridgeName(bridgeName));
711 return mdsalUtils.read(store, bridgeIid);
715 * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
716 * bridge identified by <code>bridgeName</code>
718 * @param connectionInfo the connection information
719 * @param bridgeName the bridge name
720 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
722 private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
723 return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
726 private boolean deleteBridge(ConnectionInfo connectionInfo) throws InterruptedException {
727 return deleteBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
730 private boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName)
731 throws InterruptedException {
733 boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
734 createInstanceIdentifier(connectionInfo,
735 new OvsdbBridgeName(bridgeName)));
736 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
741 public void testAddDeleteBridge() throws InterruptedException {
742 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
743 connectOvsdbNode(connectionInfo);
745 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
746 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
747 Assert.assertNotNull(bridge);
748 LOG.info("bridge: {}", bridge);
750 Assert.assertTrue(deleteBridge(connectionInfo));
752 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
755 private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
756 return createInstanceIdentifier(connectionInfo,
757 bridge.getBridgeName());
761 * Extracts the <code>TerminationPointAugmentation</code> for the <code>index</code> <code>TerminationPoint</code>
762 * on <code>bridgeName</code>
764 * @param connectionInfo the connection information
765 * @param bridgeName the bridge name
766 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
767 * @param index the index we're interested in
768 * @return the augmentation (or {@code null} if none)
770 private OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation(
771 ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index ) {
773 List<TerminationPoint> tpList = getBridgeNode(connectionInfo, bridgeName, store).getTerminationPoint();
774 if (tpList == null) {
777 return tpList.get(index).getAugmentation(OvsdbTerminationPointAugmentation.class);
781 public void testCRDTerminationPointOfPort() throws InterruptedException {
782 final Long OFPORT_EXPECTED = 45002L;
784 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
785 connectOvsdbNode(connectionInfo);
788 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
789 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
790 Assert.assertNotNull(bridge);
791 LOG.info("bridge: {}", bridge);
792 NodeId nodeId = SouthboundMapper.createManagedNodeId(createInstanceIdentifier(
793 connectionInfo, bridge.getBridgeName()));
794 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
795 createGenericOvsdbTerminationPointAugmentationBuilder();
796 String portName = "testOfPort";
797 ovsdbTerminationBuilder.setName(portName);
799 ovsdbTerminationBuilder.setOfport(OFPORT_EXPECTED);
800 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
801 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
802 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
803 Assert.assertNotNull(terminationPointNode);
806 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
807 for (TerminationPoint terminationPoint : terminationPoints) {
808 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
809 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
810 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
811 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
812 // if ephemeral port 45002 is in use, ofPort is set to 1
813 Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(new Long(1)));
814 LOG.info("ofPort: {}", ofPort);
818 // UPDATE- Not Applicable. From the OpenVSwitch Documentation:
819 // "A client should ideally set this column’s value in the same database transaction that it uses to create
823 Assert.assertTrue(deleteBridge(connectionInfo));
824 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
828 public void testCRDTerminationPointOfPortRequest() throws InterruptedException {
829 final Long OFPORT_EXPECTED = 45008L;
830 final Long OFPORT_INPUT = 45008L;
832 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
833 connectOvsdbNode(connectionInfo);
836 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
837 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
838 Assert.assertNotNull(bridge);
839 NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
840 connectionInfo, bridge.getBridgeName()));
841 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
842 createGenericOvsdbTerminationPointAugmentationBuilder();
843 String portName = "testOfPortRequest";
844 ovsdbTerminationBuilder.setName(portName);
845 Integer ofPortRequestExpected = OFPORT_EXPECTED.intValue();
846 ovsdbTerminationBuilder.setOfport(OFPORT_INPUT);
847 ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected);
848 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
849 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
850 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
851 Assert.assertNotNull(terminationPointNode);
854 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
855 for (TerminationPoint terminationPoint : terminationPoints) {
856 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
857 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
858 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
859 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
860 // if ephemeral port 45008 is in use, ofPort is set to 1
861 Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(new Long(1)));
862 LOG.info("ofPort: {}", ofPort);
864 Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest();
865 Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected));
866 LOG.info("ofPortRequest: {}", ofPortRequest);
870 // UPDATE- Not Applicable. From the OpenVSwitch documentation:
871 // "A client should ideally set this column’s value in the same database transaction that it uses to create
875 Assert.assertTrue(deleteBridge(connectionInfo));
876 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
879 private interface KeyValueBuilder<T> {
880 T build(String testName, String key, String value);
881 T[] build(String testName, int count, String key, String value);
886 * Find the real type arguments for the given class (in its hierarchy), with at least {@code nb} arguments.
888 * @param clazz The class to start with.
889 * @param nb The minimum number of type arguments.
890 * @param <T> The type of the starting class.
891 * @return The matching type arguments (a {@link RuntimeException} is thrown if none match).
893 private static <T> Type[] findTypeArguments(final Class<T> clazz, final int nb) {
894 if (clazz == null || clazz.getSuperclass() == null) {
895 throw new RuntimeException("Missing type parameters");
897 Type superClassType = clazz.getGenericSuperclass();
898 if (superClassType instanceof ParameterizedType && ((ParameterizedType) superClassType)
899 .getActualTypeArguments().length >= nb) {
900 return ((ParameterizedType) superClassType).getActualTypeArguments();
902 return findTypeArguments(clazz.getSuperclass(), nb);
905 private abstract static class BaseKeyValueBuilder<T> implements KeyValueBuilder<T> {
906 private static final int COUNTER_START = 0;
907 private int counter = COUNTER_START;
908 @SuppressWarnings("unchecked")
909 private final Class<T> builtClass = (Class<T>) findTypeArguments(getClass(), 1)[0];
911 protected abstract Builder<T> builder();
913 protected abstract void setKey(Builder<T> builder, String key);
915 protected abstract void setValue(Builder<T> builder, String value);
918 public final T build(final String testName, final String key, final String value) {
919 final Builder<T> builder = builder();
922 setKey(builder, String.format(FORMAT_STR, testName, key, this.counter));
925 setValue(builder, String.format(FORMAT_STR, testName, value, this.counter));
927 return builder.build();
930 @SuppressWarnings("unchecked")
932 public final T[] build(final String testName, final int count, final String key, final String value) {
933 final T[] instances = (T[]) Array.newInstance(builtClass, count);
934 for (int idx = 0; idx < count; idx++) {
936 instances[idx] = build(testName, key, value);
937 } catch (ArrayStoreException e) {
938 LOG.error("Error storing a value; we think we're managing {}", builtClass, e);
946 public final void reset() {
947 this.counter = COUNTER_START;
951 private static final class SouthboundPortExternalIdsBuilder extends BaseKeyValueBuilder<PortExternalIds> {
953 protected Builder<PortExternalIds> builder() {
954 return new PortExternalIdsBuilder();
958 protected void setKey(Builder<PortExternalIds> builder, String key) {
959 ((PortExternalIdsBuilder) builder).setExternalIdKey(key);
963 protected void setValue(Builder<PortExternalIds> builder, String value) {
964 ((PortExternalIdsBuilder) builder).setExternalIdValue(value);
968 private static final class SouthboundInterfaceExternalIdsBuilder extends BaseKeyValueBuilder<InterfaceExternalIds> {
970 protected Builder<InterfaceExternalIds> builder() {
971 return new InterfaceExternalIdsBuilder();
975 protected void setKey(Builder<InterfaceExternalIds> builder, String key) {
976 ((InterfaceExternalIdsBuilder) builder).setExternalIdKey(key);
980 protected void setValue(Builder<InterfaceExternalIds> builder, String value) {
981 ((InterfaceExternalIdsBuilder) builder).setExternalIdValue(value);
985 private static final class SouthboundOptionsBuilder extends BaseKeyValueBuilder<Options> {
987 protected Builder<Options> builder() {
988 return new OptionsBuilder();
992 protected void setKey(Builder<Options> builder, String key) {
993 ((OptionsBuilder) builder).setOption(key);
997 protected void setValue(Builder<Options> builder, String value) {
998 ((OptionsBuilder) builder).setValue(value);
1002 private static final class SouthboundInterfaceOtherConfigsBuilder extends BaseKeyValueBuilder<InterfaceOtherConfigs> {
1004 protected Builder<InterfaceOtherConfigs> builder() {
1005 return new InterfaceOtherConfigsBuilder();
1009 protected void setKey(Builder<InterfaceOtherConfigs> builder, String key) {
1010 ((InterfaceOtherConfigsBuilder) builder).setOtherConfigKey(key);
1014 protected void setValue(Builder<InterfaceOtherConfigs> builder, String value) {
1015 ((InterfaceOtherConfigsBuilder) builder).setOtherConfigValue(value);
1019 private static final class SouthboundPortOtherConfigsBuilder extends BaseKeyValueBuilder<PortOtherConfigs> {
1021 protected Builder<PortOtherConfigs> builder() {
1022 return new PortOtherConfigsBuilder();
1026 protected void setKey(Builder<PortOtherConfigs> builder, String key) {
1027 ((PortOtherConfigsBuilder) builder).setOtherConfigKey(key);
1031 protected void setValue(Builder<PortOtherConfigs> builder, String value) {
1032 ((PortOtherConfigsBuilder) builder).setOtherConfigValue(value);
1036 private static final class SouthboundBridgeOtherConfigsBuilder extends BaseKeyValueBuilder<BridgeOtherConfigs> {
1038 protected Builder<BridgeOtherConfigs> builder() {
1039 return new BridgeOtherConfigsBuilder();
1043 protected void setKey(Builder<BridgeOtherConfigs> builder, String key) {
1044 ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigKey(key);
1048 protected void setValue(Builder<BridgeOtherConfigs> builder, String value) {
1049 ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigValue(value);
1053 private static final class SouthboundBridgeExternalIdsBuilder extends BaseKeyValueBuilder<BridgeExternalIds> {
1055 protected Builder<BridgeExternalIds> builder() {
1056 return new BridgeExternalIdsBuilder();
1060 protected void setKey(Builder<BridgeExternalIds> builder, String key) {
1061 ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdKey(key);
1065 protected void setValue(Builder<BridgeExternalIds> builder, String value) {
1066 ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdValue(value);
1071 * Generates the test cases involved in testing key-value-based data. See inline comments for descriptions of
1072 * the particular cases considered.
1074 private static <T> List<SouthboundTestCase<T>> generateKeyValueTestCases(
1075 KeyValueBuilder<T> builder, String idKey, String idValue) {
1076 List<SouthboundTestCase<T>> testCases = new ArrayList<>();
1078 final String GOOD_KEY = "GoodKey";
1079 final String GOOD_VALUE = "GoodValue";
1080 final String NO_VALUE_FOR_KEY = "NoValueForKey";
1081 final String NO_KEY_FOR_VALUE = "NoKeyForValue";
1083 // Test Case 1: TestOne
1084 // Test Type: Positive
1085 // Description: Create a termination point with one value
1086 // Expected: A port is created with the single value specified below
1087 final String testOneName = "TestOne";
1088 testCases.add(new SouthboundTestCaseBuilder<T>()
1090 .input(builder.build(testOneName, idKey, idValue))
1091 .expectInputAsOutput()
1095 // Test Case 2: TestFive
1096 // Test Type: Positive
1097 // Description: Create a termination point with multiple (five) values
1098 // Expected: A port is created with the five values specified below
1099 final String testFiveName = "TestFive";
1100 testCases.add(new SouthboundTestCaseBuilder<T>()
1102 .input(builder.build(testFiveName, 5, idKey, idValue))
1103 .expectInputAsOutput()
1107 // Test Case 3: TestOneGoodOneMalformedValue
1108 // Test Type: Negative
1110 // One perfectly fine input
1111 // (TestOneGoodOneMalformedValue_GoodKey_1,
1112 // TestOneGoodOneMalformedValue_GoodValue_1)
1113 // and one malformed input which only has key specified
1114 // (TestOneGoodOneMalformedValue_NoValueForKey_2,
1116 // Expected: A port is created without any values
1117 final String testOneGoodOneMalformedValueName = "TestOneGoodOneMalformedValue";
1118 testCases.add(new SouthboundTestCaseBuilder<T>()
1119 .name(testOneGoodOneMalformedValueName)
1121 builder.build(testOneGoodOneMalformedValueName, GOOD_KEY, GOOD_VALUE),
1122 builder.build(testOneGoodOneMalformedValueName, NO_VALUE_FOR_KEY, null)
1128 // Test Case 4: TestOneGoodOneMalformedKey
1129 // Test Type: Negative
1131 // One perfectly fine input
1132 // (TestOneGoodOneMalformedKey_GoodKey_1,
1133 // TestOneGoodOneMalformedKey_GoodValue_1)
1134 // and one malformed input which only has value specified
1136 // TestOneGoodOneMalformedKey_NoKeyForValue_2)
1137 // Expected: A port is created without any values
1138 final String testOneGoodOneMalformedKeyName = "TestOneGoodOneMalformedKey";
1139 testCases.add(new SouthboundTestCaseBuilder<T>()
1140 .name(testOneGoodOneMalformedKeyName)
1142 builder.build(testOneGoodOneMalformedKeyName, GOOD_KEY, GOOD_VALUE),
1143 builder.build(testOneGoodOneMalformedKeyName, null, NO_KEY_FOR_VALUE)
1153 * Generates the test cases involved in testing PortExternalIds. See inline comments for descriptions of
1154 * the particular cases considered.
1156 private List<SouthboundTestCase<PortExternalIds>> generatePortExternalIdsTestCases() {
1157 return generateKeyValueTestCases(new SouthboundPortExternalIdsBuilder(), "PortExternalIdKey",
1158 "PortExternalIdValue");
1162 * Tests the CRUD operations for <code>Port</code>
1163 * <code>external_ids</code>.
1165 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for
1166 * specific test case information
1169 public void testCRUDTerminationPointPortExternalIds()
1170 throws InterruptedException, ExecutionException {
1172 final String TEST_PREFIX = "CRUDTPPortExternalIds";
1174 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1175 connectOvsdbNode(connectionInfo);
1177 // updateFromTestCases represent the original test case value.
1178 // updateToTestCases represent the new value after the update has been
1180 List<SouthboundTestCase<PortExternalIds>> updateFromTestCases = generatePortExternalIdsTestCases();
1181 List<SouthboundTestCase<PortExternalIds>> updateToTestCases = generatePortExternalIdsTestCases();
1182 String testBridgeName;
1183 String testPortName;
1186 // multihreads the test using NUM_THREADS
1187 ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
1188 for (SouthboundTestCase<PortExternalIds> fromTestCase : updateFromTestCases) {
1189 for (SouthboundTestCase<PortExternalIds> toTestCase : updateToTestCases) {
1190 testPortName = testBridgeName = String.format(FORMAT_STR,
1191 TEST_PREFIX, toTestCase.name, counter);
1193 executor.submit(new TestCRUDTerminationPointRunnable<>(
1194 new SouthboundTestHelper<PortExternalIds>() {
1196 public List<PortExternalIds> readValues(
1197 OvsdbTerminationPointAugmentation augmentation) {
1198 return augmentation.getPortExternalIds();
1202 public void writeValues(
1203 OvsdbTerminationPointAugmentationBuilder augmentationBuilder,
1204 List<PortExternalIds> updateFromInput) {
1205 augmentationBuilder.setPortExternalIds(updateFromInput);
1208 connectionInfo, testBridgeName, testPortName,
1209 fromTestCase.inputValues,
1210 fromTestCase.expectedValues,
1211 toTestCase.inputValues,
1212 toTestCase.expectedValues));
1215 executor.shutdown();
1216 executor.awaitTermination(5, TimeUnit.MINUTES);
1217 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1221 * Southbound test helper. Classes implementing this interface are used to provide concrete access to the input and
1222 * output of the underlying augmentation for the type being managed.
1224 * @param <T> The type of data used for the test case.
1226 private interface SouthboundTestHelper<T> {
1228 * Read the values from the augmentation. These would usually be checked against the expected values provided
1229 * for the test case.
1231 * @param augmentation The augmentation to read from.
1232 * @return The values read.
1234 List<T> readValues(OvsdbTerminationPointAugmentation augmentation);
1237 * Write the values to the augmentation (via its builder). This would usually be used to apply the input values
1238 * provided for the test case.
1240 * @param augmentationBuilder The augmentation builder.
1241 * @param values The values to write.
1243 void writeValues(OvsdbTerminationPointAugmentationBuilder augmentationBuilder, List<T> values);
1248 * Test runner used to apply a suite of create/read/update/delete tests. Each instance of a runner expects:
1251 * <li>a helper used to manipulate the appropriate data structures in the termination point augmentation (see
1252 * {@link SouthboundTestHelper});</li>
1253 * <li>connection information for the southbound;</li>
1254 * <li>a name to use for the test bridge (this allows multiple tests to be conducted in parallel against different
1256 * <li>a name to use for the test port;</li>
1257 * <li>the initial input values to use for the termination point augmentation;</li>
1258 * <li>the initial expected values to check the augmentation against;</li>
1259 * <li>the target input values to update the terminal point to;</li>
1260 * <li>the target expected values to check the augmentation point against.</li>
1262 * <p>The following tests are performed:</p>
1264 * <li>the bridge is added;</li>
1265 * <li>the termination point is added, with the provided initial input values;</li>
1266 * <li>the termination point is read from the <em>configuration</em> data store, and checked against the provided
1267 * initial expected values;</li>
1268 * <li>the termination point is read from the <em>operational</em> data store, and checked against the provided
1269 * initial expected values;</li>
1270 * <li>the termination point is updated by merging the provided target input values;</li>
1271 * <li>the termination point is read from the <em>configuration</em> data store, and checked against the provided
1272 * initial <b>and</b> target expected values;</li>
1273 * <li>the termination point is read from the <em>operational</em> data store, and checked against the provided
1274 * initial <b>and</b> target expected values;</li>
1275 * <li>the bridge is deleted.</li>
1278 * @param <T> The type of data used for the test case.
1280 private final class TestCRUDTerminationPointRunnable<T> implements Runnable {
1281 private final SouthboundTestHelper<T> helper;
1282 private final ConnectionInfo connectionInfo;
1283 private final String testBridgeName;
1284 private final String testPortName;
1285 private final List<T> updateFromInput;
1286 private final List<T> updateFromExpected;
1287 private final List<T> updateToInput;
1288 private final List<T> updateToExpected;
1290 private TestCRUDTerminationPointRunnable(
1291 SouthboundTestHelper<T> helper, ConnectionInfo connectionInfo, String testBridgeName,
1292 String testPortName, List<T> updateFromInput, List<T> updateFromExpected, List<T> updateToInput,
1293 List<T> updateToExpected) {
1294 this.helper = helper;
1295 this.connectionInfo = connectionInfo;
1296 this.testBridgeName = testBridgeName;
1297 this.testPortName = testPortName;
1298 this.updateFromInput = updateFromInput;
1299 this.updateFromExpected = updateFromExpected;
1300 this.updateToInput = updateToInput;
1301 this.updateToExpected = updateToExpected;
1307 final int TERMINATION_POINT_TEST_INDEX = 0;
1308 // CREATE: Create the test bridge
1309 Assert.assertTrue(addBridge(connectionInfo, null,
1310 testBridgeName, null, true,
1311 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
1312 true, null, null, null, null));
1313 NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
1314 connectionInfo, new OvsdbBridgeName(testBridgeName)));
1315 OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
1316 createGenericOvsdbTerminationPointAugmentationBuilder();
1317 tpCreateAugmentationBuilder.setName(testPortName);
1318 helper.writeValues(tpCreateAugmentationBuilder, updateFromInput);
1319 Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
1321 // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
1322 // then repeat for OPERATIONAL data store
1323 OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
1324 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1325 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1326 List<T> updateFromConfiguration = null;
1327 if (updateFromConfigurationTerminationPointAugmentation != null) {
1328 updateFromConfiguration =
1329 helper.readValues(updateFromConfigurationTerminationPointAugmentation);
1331 if (updateFromConfiguration != null) {
1332 Assert.assertTrue(updateFromConfiguration.containsAll(updateFromExpected));
1334 OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
1335 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1336 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1337 List<T> updateFromOperational = null;
1338 if (updateFromOperationalTerminationPointAugmentation != null) {
1339 updateFromOperational = helper.readValues(updateFromOperationalTerminationPointAugmentation);
1341 if (updateFromOperational != null) {
1342 Assert.assertTrue(updateFromOperational.containsAll(updateFromExpected));
1345 // UPDATE: update the external_ids
1346 testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
1347 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1348 new OvsdbTerminationPointAugmentationBuilder();
1349 helper.writeValues(tpUpdateAugmentationBuilder, updateToInput);
1350 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1351 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1352 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1353 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1354 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1355 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
1356 tpUpdateBuilder.addAugmentation(
1357 OvsdbTerminationPointAugmentation.class,
1358 tpUpdateAugmentationBuilder.build());
1359 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1360 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1361 portIid, portUpdateNodeBuilder.build());
1362 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1363 Assert.assertTrue(result);
1365 // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
1366 // then repeat for OPERATIONAL data store
1367 OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1368 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1369 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1370 List<T> updateToConfiguration = helper.readValues(updateToConfigurationTerminationPointAugmentation);
1371 Assert.assertTrue(updateToConfiguration.containsAll(updateToExpected));
1372 Assert.assertTrue(updateToConfiguration.containsAll(updateFromExpected));
1373 OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1374 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1375 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1376 List<T> updateToOperational = helper.readValues(updateToOperationalTerminationPointAugmentation);
1377 Assert.assertTrue(updateToOperational.containsAll(updateToExpected));
1378 Assert.assertTrue(updateToOperational.containsAll(updateFromExpected));
1381 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
1382 } catch (InterruptedException e) {
1383 LOG.error("Test interrupted", e);
1390 * Generates the test cases involved in testing InterfaceExternalIds. See inline comments for descriptions of
1391 * the particular cases considered.
1393 private static List<SouthboundTestCase<InterfaceExternalIds>> generateInterfaceExternalIdsTestCases() {
1394 return generateKeyValueTestCases(new SouthboundInterfaceExternalIdsBuilder(), "IntExternalIdKey",
1395 "IntExternalIdValue");
1399 * Tests the CRUD operations for <code>Interface</code> <code>external_ids</code>.
1401 * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1404 public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException, ExecutionException {
1405 final String TEST_PREFIX = "CRUDTPInterfaceExternalIds";
1407 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1408 connectOvsdbNode(connectionInfo);
1410 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
1411 // the update has been performed.
1412 List<SouthboundTestCase<InterfaceExternalIds>> updateFromTestCases = generateInterfaceExternalIdsTestCases();
1413 List<SouthboundTestCase<InterfaceExternalIds>> updateToTestCases = generateInterfaceExternalIdsTestCases();
1414 String testBridgeName;
1415 String testPortName;
1418 // multithreads the test using NUM_THREADS
1419 ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
1420 for (SouthboundTestCase<InterfaceExternalIds> fromTestCase : updateFromTestCases) {
1421 for (SouthboundTestCase<InterfaceExternalIds> toTestCase : updateToTestCases) {
1422 testPortName = testBridgeName = String.format(FORMAT_STR,
1423 TEST_PREFIX, toTestCase.name, counter);
1425 executor.submit(new TestCRUDTerminationPointRunnable<>(
1426 new SouthboundTestHelper<InterfaceExternalIds>() {
1428 public List<InterfaceExternalIds> readValues(
1429 OvsdbTerminationPointAugmentation augmentation) {
1430 return augmentation.getInterfaceExternalIds();
1434 public void writeValues(
1435 OvsdbTerminationPointAugmentationBuilder augmentationBuilder,
1436 List<InterfaceExternalIds> values) {
1437 augmentationBuilder.setInterfaceExternalIds(values);
1440 connectionInfo, testBridgeName, testPortName,
1441 fromTestCase.inputValues,
1442 fromTestCase.expectedValues,
1443 toTestCase.inputValues,
1444 toTestCase.expectedValues));
1447 executor.shutdown();
1448 executor.awaitTermination(5, TimeUnit.MINUTES);
1449 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1453 * Generates the test cases involved in testing TP Options. See inline comments for descriptions of
1454 * the particular cases considered.
1456 private List<SouthboundTestCase<Options>> generateTerminationPointOptionsTestCases() {
1457 return generateKeyValueTestCases(new SouthboundOptionsBuilder(), "TOPOptionsKey", "TPOptionsValue");
1461 * Tests the CRUD operations for <code>TerminationPoint</code> <code>options</code>.
1463 * @see <code>SouthboundIT.generateTerminationPointOptions()</code> for specific test case information
1466 public void testCRUDTerminationPointOptions() throws InterruptedException {
1467 final String TEST_PREFIX = "CRUDTPOptions";
1469 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1470 connectOvsdbNode(connectionInfo);
1472 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
1473 // the update has been performed.
1474 List<SouthboundTestCase<Options>> updateFromTestCases = generateTerminationPointOptionsTestCases();
1475 List<SouthboundTestCase<Options>> updateToTestCases = generateTerminationPointOptionsTestCases();
1476 String testBridgeName;
1477 String testPortName;
1480 ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
1481 for (SouthboundTestCase<Options> fromTestCase : updateFromTestCases) {
1482 for (SouthboundTestCase<Options> toTestCase : updateToTestCases) {
1483 testPortName = testBridgeName = String.format(FORMAT_STR,
1484 TEST_PREFIX, toTestCase.name, counter);
1486 executor.submit(new TestCRUDTerminationPointRunnable<>(
1487 new SouthboundTestHelper<Options>() {
1489 public List<Options> readValues(
1490 OvsdbTerminationPointAugmentation augmentation) {
1491 return augmentation.getOptions();
1495 public void writeValues(
1496 OvsdbTerminationPointAugmentationBuilder augmentationBuilder,
1497 List<Options> values) {
1498 augmentationBuilder.setOptions(values);
1501 connectionInfo, testBridgeName, testPortName,
1502 fromTestCase.inputValues,
1503 fromTestCase.expectedValues,
1504 toTestCase.inputValues,
1505 toTestCase.expectedValues));
1508 executor.shutdown();
1509 executor.awaitTermination(5, TimeUnit.MINUTES);
1510 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1514 * Generates the test cases involved in testing Interface other_configs. See inline comments for descriptions of
1515 * the particular cases considered.
1517 private List<SouthboundTestCase<InterfaceOtherConfigs>> generateInterfaceOtherConfigsTestCases() {
1518 return generateKeyValueTestCases(new SouthboundInterfaceOtherConfigsBuilder(), "IntOtherConfigsKey",
1519 "IntOtherConfigsValue");
1523 * Tests the CRUD operations for <code>Interface</code> <code>other_configs</code>.
1525 * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1528 public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException {
1529 final String TEST_PREFIX = "CRUDTPInterfaceOtherConfigs";
1531 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1532 connectOvsdbNode(connectionInfo);
1534 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
1535 // the update has been performed.
1536 List<SouthboundTestCase<InterfaceOtherConfigs>> updateFromTestCases = generateInterfaceOtherConfigsTestCases();
1537 List<SouthboundTestCase<InterfaceOtherConfigs>> updateToTestCases = generateInterfaceOtherConfigsTestCases();
1538 String testBridgeName;
1539 String testPortName;
1542 ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
1543 for (SouthboundTestCase<InterfaceOtherConfigs> fromTestCase : updateFromTestCases) {
1544 for (SouthboundTestCase<InterfaceOtherConfigs> toTestCase : updateToTestCases) {
1545 testPortName = testBridgeName = String.format(FORMAT_STR,
1546 TEST_PREFIX, toTestCase.name, counter);
1548 executor.submit(new TestCRUDTerminationPointRunnable<>(
1549 new SouthboundTestHelper<InterfaceOtherConfigs>() {
1551 public List<InterfaceOtherConfigs> readValues(
1552 OvsdbTerminationPointAugmentation augmentation) {
1553 return augmentation.getInterfaceOtherConfigs();
1557 public void writeValues(
1558 OvsdbTerminationPointAugmentationBuilder augmentationBuilder,
1559 List<InterfaceOtherConfigs> values) {
1560 augmentationBuilder.setInterfaceOtherConfigs(values);
1563 connectionInfo, testBridgeName, testPortName,
1564 fromTestCase.inputValues,
1565 fromTestCase.expectedValues,
1566 toTestCase.inputValues,
1567 toTestCase.expectedValues));
1570 executor.shutdown();
1571 executor.awaitTermination(5, TimeUnit.MINUTES);
1572 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1576 * Generates the test cases involved in testing Port other_configs. See inline comments for descriptions of
1577 * the particular cases considered.
1579 private List<SouthboundTestCase<PortOtherConfigs>> generatePortOtherConfigsTestCases() {
1580 return generateKeyValueTestCases(new SouthboundPortOtherConfigsBuilder(), "PortOtherConfigsKey",
1581 "PortOtherConfigsValue");
1585 * Tests the CRUD operations for <code>Port</code> <code>other_configs</code>.
1587 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1590 public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException {
1591 final String TEST_PREFIX = "CRUDTPPortOtherConfigs";
1593 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1594 connectOvsdbNode(connectionInfo);
1596 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
1597 // the update has been performed.
1598 List<SouthboundTestCase<PortOtherConfigs>> updateFromTestCases = generatePortOtherConfigsTestCases();
1599 List<SouthboundTestCase<PortOtherConfigs>> updateToTestCases = generatePortOtherConfigsTestCases();
1600 String testBridgeName;
1601 String testPortName;
1604 ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
1605 for (SouthboundTestCase<PortOtherConfigs> fromTestCase : updateFromTestCases) {
1606 for (SouthboundTestCase<PortOtherConfigs> toTestCase : updateToTestCases) {
1607 testPortName = testBridgeName = String.format(FORMAT_STR,
1608 TEST_PREFIX, toTestCase.name, counter);
1610 executor.submit(new TestCRUDTerminationPointRunnable<>(
1611 new SouthboundTestHelper<PortOtherConfigs>() {
1613 public List<PortOtherConfigs> readValues(
1614 OvsdbTerminationPointAugmentation augmentation) {
1615 return augmentation.getPortOtherConfigs();
1619 public void writeValues(
1620 OvsdbTerminationPointAugmentationBuilder augmentationBuilder,
1621 List<PortOtherConfigs> values) {
1622 augmentationBuilder.setPortOtherConfigs(values);
1625 connectionInfo, testBridgeName, testPortName,
1626 fromTestCase.inputValues,
1627 fromTestCase.expectedValues,
1628 toTestCase.inputValues,
1629 toTestCase.expectedValues));
1632 executor.shutdown();
1633 executor.awaitTermination(5, TimeUnit.MINUTES);
1634 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1638 public void testCRUDTerminationPointVlan() throws InterruptedException {
1639 final Integer CREATED_VLAN_ID = 4000;
1640 final Integer UPDATED_VLAN_ID = 4001;
1642 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1643 connectOvsdbNode(connectionInfo);
1646 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1647 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1648 Assert.assertNotNull(bridge);
1649 NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
1650 connectionInfo, bridge.getBridgeName()));
1651 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1652 createGenericOvsdbTerminationPointAugmentationBuilder();
1653 String portName = "testTerminationPointVlanId";
1654 ovsdbTerminationBuilder.setName(portName);
1655 ovsdbTerminationBuilder.setVlanTag(new VlanId(CREATED_VLAN_ID));
1656 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1657 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1658 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1659 Assert.assertNotNull(terminationPointNode);
1662 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1663 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation;
1664 for (TerminationPoint terminationPoint : terminationPoints) {
1665 ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1666 OvsdbTerminationPointAugmentation.class);
1667 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1668 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1669 Assert.assertNotNull(actualVlanId);
1670 Integer actualVlanIdInt = actualVlanId.getValue();
1671 Assert.assertEquals(CREATED_VLAN_ID, actualVlanIdInt);
1676 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1677 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1678 new OvsdbTerminationPointAugmentationBuilder();
1679 tpUpdateAugmentationBuilder.setVlanTag(new VlanId(UPDATED_VLAN_ID));
1680 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1681 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1682 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1683 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1684 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1685 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1686 tpUpdateBuilder.addAugmentation(
1687 OvsdbTerminationPointAugmentation.class,
1688 tpUpdateAugmentationBuilder.build());
1689 tpUpdateBuilder.setTpId(new TpId(portName));
1690 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1691 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1692 portIid, portUpdateNodeBuilder.build());
1693 Assert.assertTrue(result);
1694 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1696 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1697 terminationPoints = terminationPointNode.getTerminationPoint();
1698 for (TerminationPoint terminationPoint : terminationPoints) {
1699 ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1700 OvsdbTerminationPointAugmentation.class);
1701 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1702 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1703 Assert.assertNotNull(actualVlanId);
1704 Integer actualVlanIdInt = actualVlanId.getValue();
1705 Assert.assertEquals(UPDATED_VLAN_ID, actualVlanIdInt);
1710 Assert.assertTrue(deleteBridge(connectionInfo));
1711 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1715 public void testCRUDTerminationPointVlanModes() throws InterruptedException {
1716 final VlanMode UPDATED_VLAN_MODE = VlanMode.Access;
1717 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1718 connectOvsdbNode(connectionInfo);
1719 VlanMode []vlanModes = VlanMode.values();
1720 for (VlanMode vlanMode : vlanModes) {
1722 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1723 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1724 Assert.assertNotNull(bridge);
1725 NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
1726 connectionInfo, bridge.getBridgeName()));
1727 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1728 createGenericOvsdbTerminationPointAugmentationBuilder();
1729 String portName = "testTerminationPointVlanMode" + vlanMode.toString();
1730 ovsdbTerminationBuilder.setName(portName);
1731 ovsdbTerminationBuilder.setVlanMode(vlanMode);
1732 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1733 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1734 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1735 Assert.assertNotNull(terminationPointNode);
1738 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1739 for (TerminationPoint terminationPoint : terminationPoints) {
1740 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1741 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1742 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1744 Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode));
1749 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1750 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1751 new OvsdbTerminationPointAugmentationBuilder();
1752 tpUpdateAugmentationBuilder.setVlanMode(UPDATED_VLAN_MODE);
1753 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1754 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1755 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1756 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1757 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1758 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1759 tpUpdateBuilder.addAugmentation(
1760 OvsdbTerminationPointAugmentation.class,
1761 tpUpdateAugmentationBuilder.build());
1762 tpUpdateBuilder.setTpId(new TpId(portName));
1763 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1764 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1765 portIid, portUpdateNodeBuilder.build());
1766 Assert.assertTrue(result);
1767 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1769 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1770 terminationPoints = terminationPointNode.getTerminationPoint();
1771 for (TerminationPoint terminationPoint : terminationPoints) {
1772 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1773 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1774 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1776 Assert.assertEquals(UPDATED_VLAN_MODE, ovsdbTerminationPointAugmentation.getVlanMode());
1781 Assert.assertTrue(deleteBridge(connectionInfo));
1783 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1786 private ArrayList<Set<Integer>> generateVlanSets() {
1787 ArrayList<Set<Integer>> vlanSets = new ArrayList<>();
1789 Set<Integer> emptySet = new HashSet<>();
1790 vlanSets.add(emptySet);
1792 Set<Integer> singleSet = new HashSet<>();
1793 Integer single = 2222;
1794 singleSet.add(single);
1795 vlanSets.add(singleSet);
1797 Set<Integer> minMaxMiddleSet = new HashSet<>();
1799 minMaxMiddleSet.add(min);
1801 minMaxMiddleSet.add(max);
1802 Integer minPlusOne = min + 1;
1803 minMaxMiddleSet.add(minPlusOne);
1804 Integer maxMinusOne = max - 1;
1805 minMaxMiddleSet.add(maxMinusOne);
1806 Integer middle = (max - min) / 2;
1807 minMaxMiddleSet.add(middle);
1808 vlanSets.add(minMaxMiddleSet);
1813 private List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
1814 List<Trunks> trunkList = Lists.newArrayList();
1815 for (Integer trunk : trunkSet) {
1816 TrunksBuilder trunkBuilder = new TrunksBuilder();
1817 trunkBuilder.setTrunk(new VlanId(trunk));
1818 trunkList.add(trunkBuilder.build());
1824 public void testCRUDTerminationPointVlanTrunks() throws InterruptedException {
1825 final List<Trunks> UPDATED_TRUNKS = buildTrunkList(Sets.newHashSet(2011));
1826 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1827 connectOvsdbNode(connectionInfo);
1828 Iterable<Set<Integer>> vlanSets = generateVlanSets();
1830 for (Set<Integer> vlanSet : vlanSets) {
1833 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1834 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1835 Assert.assertNotNull(bridge);
1836 NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
1837 connectionInfo, bridge.getBridgeName()));
1838 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1839 createGenericOvsdbTerminationPointAugmentationBuilder();
1840 String portName = "testTerminationPointVlanTrunks" + testCase;
1841 ovsdbTerminationBuilder.setName(portName);
1842 List<Trunks> trunks = buildTrunkList(vlanSet);
1843 ovsdbTerminationBuilder.setTrunks(trunks);
1844 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1845 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1846 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1847 Assert.assertNotNull(terminationPointNode);
1850 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1851 for (TerminationPoint terminationPoint : terminationPoints) {
1852 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1853 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1854 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1855 List<Trunks> actualTrunks = ovsdbTerminationPointAugmentation.getTrunks();
1856 for (Trunks trunk : trunks) {
1857 Assert.assertTrue(actualTrunks.contains(trunk));
1864 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1865 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1866 new OvsdbTerminationPointAugmentationBuilder();
1867 tpUpdateAugmentationBuilder.setTrunks(UPDATED_TRUNKS);
1868 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1869 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1870 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1871 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1872 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1873 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1874 tpUpdateBuilder.addAugmentation(
1875 OvsdbTerminationPointAugmentation.class,
1876 tpUpdateAugmentationBuilder.build());
1877 tpUpdateBuilder.setTpId(new TpId(portName));
1878 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1879 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1880 portIid, portUpdateNodeBuilder.build());
1881 Assert.assertTrue(result);
1882 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1884 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1885 terminationPoints = terminationPointNode.getTerminationPoint();
1886 for (TerminationPoint terminationPoint : terminationPoints) {
1887 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1888 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1889 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1891 Assert.assertEquals(UPDATED_TRUNKS, ovsdbTerminationPointAugmentation.getTrunks());
1896 Assert.assertTrue(deleteBridge(connectionInfo));
1898 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1902 public void testGetOvsdbNodes() throws InterruptedException {
1903 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1904 connectOvsdbNode(connectionInfo);
1905 InstanceIdentifier<Topology> topologyPath = InstanceIdentifier
1906 .create(NetworkTopology.class)
1907 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
1909 Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath);
1910 InstanceIdentifier<Node> expectedNodeIid = createInstanceIdentifier(connectionInfo);
1911 NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class, NodeKey.class).getNodeId();
1912 Node foundNode = null;
1913 Assert.assertNotNull("Expected to find topology: " + topologyPath, topology);
1914 Assert.assertNotNull("Expected to find some nodes" + topology.getNode());
1915 LOG.info("expectedNodeId: {}, getNode: {}", expectedNodeId, topology.getNode());
1916 for (Node node : topology.getNode()) {
1917 if (node.getNodeId().getValue().equals(expectedNodeId.getValue())) {
1922 Assert.assertNotNull("Expected to find Node: " + expectedNodeId, foundNode);
1923 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1927 * Generates the test cases involved in testing BridgeOtherConfigs. See inline comments for descriptions of
1928 * the particular cases considered.
1930 private List<SouthboundTestCase<BridgeOtherConfigs>> generateBridgeOtherConfigsTestCases() {
1931 return generateKeyValueTestCases(new SouthboundBridgeOtherConfigsBuilder(), "BridgeOtherConfigsKey",
1932 "BridgeOtherConfigsValue");
1936 * @see <code>SouthboundIT.testCRUDBridgeOtherConfigs()</code>
1937 * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
1939 private void assertExpectedBridgeOtherConfigsExist( List<BridgeOtherConfigs> expected,
1940 List<BridgeOtherConfigs> test ) {
1942 if (expected != null) {
1943 for (BridgeOtherConfigs expectedOtherConfig : expected) {
1944 Assert.assertTrue(test.contains(expectedOtherConfig));
1950 * @see <code>SouthboundIT.generateBridgeOtherConfigsTestCases()</code> for specific test case information.
1953 public void testCRUDBridgeOtherConfigs() throws InterruptedException {
1954 final String TEST_BRIDGE_PREFIX = "CRUDBridgeOtherConfigs";
1955 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1956 connectOvsdbNode(connectionInfo);
1957 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
1958 // the update has been performed.
1959 List<SouthboundTestCase<BridgeOtherConfigs>> updateFromTestCases = generateBridgeOtherConfigsTestCases();
1960 List<SouthboundTestCase<BridgeOtherConfigs>> updateToTestCases = generateBridgeOtherConfigsTestCases();
1961 String testBridgeName;
1964 ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
1965 for (SouthboundTestCase<BridgeOtherConfigs> fromTestCase : updateFromTestCases) {
1966 for (SouthboundTestCase<BridgeOtherConfigs> toTestCase : updateToTestCases) {
1967 testBridgeName = String.format(FORMAT_STR, TEST_BRIDGE_PREFIX, toTestCase.name, counter);
1969 TestCRUDBridgeOtherConfigsRunnable testRunnable =
1970 new TestCRUDBridgeOtherConfigsRunnable(
1971 connectionInfo, testBridgeName,
1972 fromTestCase.inputValues,
1973 fromTestCase.expectedValues,
1974 toTestCase.inputValues,
1975 toTestCase.expectedValues);
1976 executor.submit(testRunnable);
1979 executor.shutdown();
1980 executor.awaitTermination(5, TimeUnit.MINUTES);
1982 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1985 class TestCRUDBridgeOtherConfigsRunnable implements Runnable {
1987 ConnectionInfo connectionInfo;
1988 String testBridgeName;
1989 List<BridgeOtherConfigs> updateFromInputOtherConfigs;
1990 List<BridgeOtherConfigs> updateFromExpectedOtherConfigs;
1991 List<BridgeOtherConfigs> updateToInputOtherConfigs;
1992 List<BridgeOtherConfigs> updateToExpectedOtherConfigs;
1994 TestCRUDBridgeOtherConfigsRunnable(
1995 ConnectionInfo connectionInfo, String testBridgeName,
1996 List<BridgeOtherConfigs> updateFromInputOtherConfigs,
1997 List<BridgeOtherConfigs> updateFromExpectedOtherConfigs,
1998 List<BridgeOtherConfigs> updateToInputOtherConfigs,
1999 List<BridgeOtherConfigs> updateToExpectedOtherConfigs) {
2001 this.connectionInfo = connectionInfo;
2002 this.testBridgeName = testBridgeName;
2003 this.updateFromInputOtherConfigs = updateFromInputOtherConfigs;
2004 this.updateFromExpectedOtherConfigs = updateFromExpectedOtherConfigs;
2005 this.updateToInputOtherConfigs = updateToInputOtherConfigs;
2006 this.updateToExpectedOtherConfigs = updateToExpectedOtherConfigs;
2013 } catch (InterruptedException e) {
2014 e.printStackTrace();
2018 public void test() throws InterruptedException {
2019 // CREATE: Create the test bridge
2020 boolean bridgeAdded = addBridge(connectionInfo, null,
2021 testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
2022 true, null, null, null, updateFromInputOtherConfigs);
2023 Assert.assertTrue(bridgeAdded);
2025 // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2026 // then repeat for OPERATIONAL data store
2027 List<BridgeOtherConfigs> updateFromConfigurationOtherConfigs = getBridge(connectionInfo, testBridgeName,
2028 LogicalDatastoreType.CONFIGURATION).getBridgeOtherConfigs();
2029 assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
2030 updateFromConfigurationOtherConfigs);
2031 List<BridgeOtherConfigs> updateFromOperationalOtherConfigs = getBridge(connectionInfo, testBridgeName)
2032 .getBridgeOtherConfigs();
2033 assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
2034 updateFromOperationalOtherConfigs);
2036 // UPDATE: update the external_ids
2037 OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
2038 bridgeAugmentationBuilder.setBridgeOtherConfigs(updateToInputOtherConfigs);
2039 InstanceIdentifier<Node> bridgeIid =
2040 createInstanceIdentifier(connectionInfo,
2041 new OvsdbBridgeName(testBridgeName));
2042 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
2043 Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
2044 bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId());
2045 bridgeNodeBuilder.setKey(bridgeNode.getKey());
2046 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build());
2047 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
2048 bridgeNodeBuilder.build());
2049 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2050 Assert.assertTrue(result);
2052 // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2053 // then repeat for OPERATIONAL data store
2054 List<BridgeOtherConfigs> updateToConfigurationOtherConfigs = getBridge(connectionInfo, testBridgeName,
2055 LogicalDatastoreType.CONFIGURATION).getBridgeOtherConfigs();
2056 assertExpectedBridgeOtherConfigsExist(updateToExpectedOtherConfigs, updateToConfigurationOtherConfigs);
2057 assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
2058 updateToConfigurationOtherConfigs);
2059 List<BridgeOtherConfigs> updateToOperationalOtherConfigs = getBridge(connectionInfo, testBridgeName)
2060 .getBridgeOtherConfigs();
2061 if (updateFromExpectedOtherConfigs != null) {
2062 assertExpectedBridgeOtherConfigsExist(updateToExpectedOtherConfigs,
2063 updateToOperationalOtherConfigs);
2064 assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
2065 updateToOperationalOtherConfigs);
2069 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
2074 * Generates the test cases involved in testing BridgeExternalIds. See inline comments for descriptions of
2075 * the particular cases considered.
2077 private List<SouthboundTestCase<BridgeExternalIds>> generateBridgeExternalIdsTestCases() {
2078 return generateKeyValueTestCases(new SouthboundBridgeExternalIdsBuilder(), "BridgeExternalIdsKey",
2079 "BridgeExternalIdsValue");
2083 * @see <code>SouthboundIT.testCRUDBridgeExternalIds()</code>
2084 * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
2086 private void assertExpectedBridgeExternalIdsExist( List<BridgeExternalIds> expected,
2087 List<BridgeExternalIds> test ) {
2089 if (expected != null) {
2090 for (BridgeExternalIds expectedExternalId : expected) {
2091 Assert.assertTrue(test.contains(expectedExternalId));
2097 * @see <code>SouthboundIT.generateBridgeExternalIdsTestCases()</code> for specific test case information
2100 public void testCRUDBridgeExternalIds() throws InterruptedException {
2101 final String TEST_BRIDGE_PREFIX = "CRUDBridgeExternalIds";
2102 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2103 connectOvsdbNode(connectionInfo);
2104 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
2105 // the update has been performed.
2106 List<SouthboundTestCase<BridgeExternalIds>> updateFromTestCases = generateBridgeExternalIdsTestCases();
2107 List<SouthboundTestCase<BridgeExternalIds>> updateToTestCases = generateBridgeExternalIdsTestCases();
2108 String testBridgeName;
2111 ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
2112 for (SouthboundTestCase<BridgeExternalIds> fromTestCase : updateFromTestCases) {
2113 for (SouthboundTestCase<BridgeExternalIds> toTestCase : updateToTestCases) {
2114 testBridgeName = String.format(FORMAT_STR, TEST_BRIDGE_PREFIX, toTestCase.name, counter);
2116 TestCRUDBridgeExternalIdsRunnable testRunnable =
2117 new TestCRUDBridgeExternalIdsRunnable(
2118 connectionInfo, testBridgeName,
2119 fromTestCase.inputValues,
2120 fromTestCase.expectedValues,
2121 toTestCase.inputValues,
2122 toTestCase.expectedValues);
2123 executor.submit(testRunnable);
2126 executor.shutdown();
2127 executor.awaitTermination(5, TimeUnit.MINUTES);
2129 Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
2132 class TestCRUDBridgeExternalIdsRunnable implements Runnable {
2133 ConnectionInfo connectionInfo;
2134 String testBridgeName;
2135 List<BridgeExternalIds> updateFromInputExternalIds;
2136 List<BridgeExternalIds> updateFromExpectedExternalIds;
2137 List<BridgeExternalIds> updateToInputExternalIds;
2138 List<BridgeExternalIds> updateToExpectedExternalIds;
2140 TestCRUDBridgeExternalIdsRunnable(
2141 ConnectionInfo connectionInfo, String testBridgeName,
2142 List<BridgeExternalIds> updateFromInputExternalIds,
2143 List<BridgeExternalIds> updateFromExpectedExternalIds,
2144 List<BridgeExternalIds> updateToInputExternalIds,
2145 List<BridgeExternalIds> updateToExpectedExternalIds) {
2147 this.connectionInfo = connectionInfo;
2148 this.testBridgeName = testBridgeName;
2149 this.updateFromInputExternalIds = updateFromInputExternalIds;
2150 this.updateFromExpectedExternalIds = updateFromExpectedExternalIds;
2151 this.updateToInputExternalIds = updateToInputExternalIds;
2152 this.updateToExpectedExternalIds = updateToExpectedExternalIds;
2159 } catch (InterruptedException e) {
2160 e.printStackTrace();
2164 public void test() throws InterruptedException {
2165 // CREATE: Create the test bridge
2166 boolean bridgeAdded = addBridge(connectionInfo, null,
2167 testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
2168 true, null, updateFromInputExternalIds, null, null);
2169 Assert.assertTrue(bridgeAdded);
2171 // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2172 // then repeat for OPERATIONAL data store
2173 List<BridgeExternalIds> updateFromConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
2174 LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
2175 assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromConfigurationExternalIds);
2176 List<BridgeExternalIds> updateFromOperationalExternalIds = getBridge(connectionInfo, testBridgeName)
2177 .getBridgeExternalIds();
2178 assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromOperationalExternalIds);
2180 // UPDATE: update the external_ids
2181 OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
2182 bridgeAugmentationBuilder.setBridgeExternalIds(updateToInputExternalIds);
2183 InstanceIdentifier<Node> bridgeIid =
2184 createInstanceIdentifier(connectionInfo,
2185 new OvsdbBridgeName(testBridgeName));
2186 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
2187 Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
2188 bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId());
2189 bridgeNodeBuilder.setKey(bridgeNode.getKey());
2190 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build());
2191 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
2192 bridgeNodeBuilder.build());
2193 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2194 Assert.assertTrue(result);
2196 // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2197 // then repeat for OPERATIONAL data store
2198 List<BridgeExternalIds> updateToConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
2199 LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
2200 assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
2201 assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateToConfigurationExternalIds);
2202 List<BridgeExternalIds> updateToOperationalExternalIds = getBridge(connectionInfo, testBridgeName)
2203 .getBridgeExternalIds();
2204 if (updateFromExpectedExternalIds != null) {
2205 assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds);
2206 assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateToOperationalExternalIds);
2210 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
2214 public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
2215 return SouthboundMapper.createInstanceIdentifier(createManagedNodeId(key, bridgeName));
2218 public static NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
2219 return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
2222 public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
2223 return new NodeId(createNodeId(ip,port).getValue()
2224 + "/" + SouthboundConstants.BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
2227 public static NodeId createNodeId(IpAddress ip, PortNumber port) {
2228 String uriString = SouthboundConstants.OVSDB_URI_PREFIX + "://"
2229 + new String(ip.getValue()) + ":" + port.getValue();
2230 Uri uri = new Uri(uriString);
2231 return new NodeId(uri);
2234 public static NodeKey createNodeKey(IpAddress ip, PortNumber port) {
2235 return new NodeKey(createNodeId(ip,port));
2238 public static Node createNode(ConnectionInfo key) {
2239 NodeBuilder nodeBuilder = new NodeBuilder();
2240 nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(),key.getRemotePort()));
2241 nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
2242 return nodeBuilder.build();
2245 public static OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
2246 OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
2247 ovsdbNodeBuilder.setConnectionInfo(key);
2248 return ovsdbNodeBuilder.build();
2251 public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
2252 NodeKey nodeKey = iid.firstKeyOf(Node.class, NodeKey.class);
2253 return nodeKey.getNodeId();
2258 * Representation of a southbound test case. Each test case has a name, a list of input values and a list of
2259 * expected values. The input values are provided to the augmentation builder, and the expected values are checked
2260 * against the output of the resulting augmentation.
2263 * Instances of this class are immutable.
2266 * @param <T> The type of data used for the test case.
2268 private static final class SouthboundTestCase<T> {
2269 private final String name;
2270 private final List<T> inputValues;
2271 private final List<T> expectedValues;
2274 * Creates an instance of a southbound test case.
2276 * @param name The test case's name.
2277 * @param inputValues The input values (provided as input to the underlying augmentation builder).
2278 * @param expectedValues The expected values (checked against the output of the underlying augmentation).
2280 public SouthboundTestCase(
2281 final String name, final List<T> inputValues, final List<T> expectedValues) {
2283 this.inputValues = inputValues;
2284 this.expectedValues = expectedValues;
2289 * Southbound test case builder.
2291 * @param <T> The type of data used for the test case.
2293 private static final class SouthboundTestCaseBuilder<T> {
2294 private String name;
2295 private List<T> inputValues;
2296 private List<T> expectedValues;
2299 * Creates a builder. Builders may be reused, the generated immutable instances are independent of the
2300 * builders. There are no default values.
2302 public SouthboundTestCaseBuilder() {
2307 * Sets the test case's name.
2309 * @param name The test case's name.
2310 * @return The builder.
2312 public SouthboundTestCaseBuilder<T> name(final String name) {
2318 * Sets the input values.
2320 * @param inputValues The input values.
2321 * @return The builder.
2324 public final SouthboundTestCaseBuilder<T> input(final T... inputValues) {
2325 this.inputValues = Lists.newArrayList(inputValues);
2330 * Sets the expected output values.
2332 * @param expectedValues The expected output values.
2333 * @return The builder.
2336 public final SouthboundTestCaseBuilder<T> expect(final T... expectedValues) {
2337 this.expectedValues = Lists.newArrayList(expectedValues);
2342 * Indicates that the provided input values should be expected as output values.
2344 * @return The builder.
2346 public SouthboundTestCaseBuilder<T> expectInputAsOutput() {
2347 this.expectedValues = this.inputValues;
2352 * Builds an immutable instance representing the test case.
2354 * @return The test case.
2356 @SuppressWarnings("unchecked")
2357 public SouthboundTestCase<T> build() {
2358 return new SouthboundTestCase<>(name, inputValues, expectedValues);