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.karaf.options.KarafDistributionOption.editConfigurationFilePut;
16 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
18 import com.google.common.collect.ImmutableBiMap;
19 import com.google.common.collect.Lists;
20 import com.google.common.collect.Sets;
22 import java.net.InetAddress;
23 import java.net.UnknownHostException;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Properties;
31 import javax.annotation.Nullable;
32 import javax.inject.Inject;
34 import org.junit.Assert;
35 import org.junit.Before;
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
39 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
40 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
41 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
42 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
43 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
44 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
45 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
46 import org.opendaylight.ovsdb.southbound.SouthboundProvider;
47 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
48 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
49 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntry;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
92 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
93 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
94 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
95 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
96 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
97 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
98 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
99 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
100 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
101 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
102 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
103 import org.opendaylight.yangtools.concepts.Builder;
104 import org.opendaylight.yangtools.yang.binding.DataObject;
105 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
106 import org.ops4j.pax.exam.Configuration;
107 import org.ops4j.pax.exam.Option;
108 import org.ops4j.pax.exam.junit.PaxExam;
109 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
110 import org.ops4j.pax.exam.options.MavenUrlReference;
111 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
112 import org.ops4j.pax.exam.spi.reactors.PerClass;
113 import org.osgi.framework.BundleContext;
114 import org.slf4j.Logger;
115 import org.slf4j.LoggerFactory;
118 * Integration tests for southbound-impl
120 * @author Sam Hague (shague@redhat.com)
122 @RunWith(PaxExam.class)
123 @ExamReactorStrategy(PerClass.class)
124 public class SouthboundIT extends AbstractMdsalTestBase {
125 private static final String NETDEV_DP_TYPE = "netdev";
126 private static final Logger LOG = LoggerFactory.getLogger(SouthboundIT.class);
127 private static final int OVSDB_UPDATE_TIMEOUT = 1000;
128 private static final int OVSDB_ROUNDTRIP_TIMEOUT = 10000;
129 private static final String FORMAT_STR = "%s_%s_%d";
130 private static String addressStr;
131 private static int portNumber;
132 private static String connectionType;
133 private static boolean setup = false;
134 private static MdsalUtils mdsalUtils = null;
135 private static Node ovsdbNode;
138 private BundleContext bundleContext;
140 private static final NotifyingDataChangeListener CONFIGURATION_LISTENER =
141 new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION);
142 private static final NotifyingDataChangeListener OPERATIONAL_LISTENER =
143 new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL);
145 private static class NotifyingDataChangeListener implements DataChangeListener {
146 private final LogicalDatastoreType type;
147 private final Set<InstanceIdentifier<?>> createdIids = new HashSet<>();
148 private final Set<InstanceIdentifier<?>> removedIids = new HashSet<>();
149 private final Set<InstanceIdentifier<?>> updatedIids = new HashSet<>();
151 private NotifyingDataChangeListener(LogicalDatastoreType type) {
156 public void onDataChanged(
157 AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> asyncDataChangeEvent) {
158 LOG.info("{} DataChanged: created {}", type, asyncDataChangeEvent.getCreatedData().keySet());
159 LOG.info("{} DataChanged: removed {}", type, asyncDataChangeEvent.getRemovedPaths());
160 LOG.info("{} DataChanged: updated {}", type, asyncDataChangeEvent.getUpdatedData().keySet());
161 createdIids.addAll(asyncDataChangeEvent.getCreatedData().keySet());
162 removedIids.addAll(asyncDataChangeEvent.getRemovedPaths());
163 updatedIids.addAll(asyncDataChangeEvent.getUpdatedData().keySet());
164 // Handled managed iids
165 for (DataObject obj : asyncDataChangeEvent.getCreatedData().values()) {
166 if (obj instanceof ManagedNodeEntry) {
167 ManagedNodeEntry managedNodeEntry = (ManagedNodeEntry) obj;
168 LOG.info("{} DataChanged: created managed {}", managedNodeEntry.getBridgeRef().getValue());
169 createdIids.add(managedNodeEntry.getBridgeRef().getValue());
177 public boolean isCreated(InstanceIdentifier<?> iid) {
178 return createdIids.remove(iid);
181 public boolean isRemoved(InstanceIdentifier<?> iid) {
182 return removedIids.remove(iid);
185 public boolean isUpdated(InstanceIdentifier<?> iid) {
186 return updatedIids.remove(iid);
191 public Option[] config() {
192 Option[] options = super.config();
193 Option[] propertyOptions = getPropertiesOptions();
194 Option[] otherOptions = getOtherOptions();
195 Option[] combinedOptions = new Option[options.length + propertyOptions.length + otherOptions.length];
196 System.arraycopy(options, 0, combinedOptions, 0, options.length);
197 System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length);
198 System.arraycopy(otherOptions, 0, combinedOptions, options.length + propertyOptions.length,
199 otherOptions.length);
200 return combinedOptions;
203 private Option[] getOtherOptions() {
204 return new Option[] {
205 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
211 public String getKarafDistro() {
213 .groupId("org.opendaylight.ovsdb")
214 .artifactId("southbound-karaf")
215 .versionAsInProject()
221 public String getModuleName() {
222 return "southbound-impl";
226 public String getInstanceName() {
227 return "southbound-default";
231 public MavenUrlReference getFeatureRepo() {
233 .groupId("org.opendaylight.ovsdb")
234 .artifactId("southbound-features")
235 .classifier("features")
237 .versionAsInProject();
241 public String getFeatureName() {
242 return "odl-ovsdb-southbound-test";
245 protected String usage() {
246 return "Integration Test needs a valid connection configuration as follows :\n"
247 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
248 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
252 public Option getLoggingOption() {
254 editConfigurationFilePut(SouthboundITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
255 "log4j.logger.org.opendaylight.ovsdb",
256 LogLevelOption.LogLevel.TRACE.name()),
257 super.getLoggingOption());
260 private Option[] getPropertiesOptions() {
261 Properties props = new Properties(System.getProperties());
262 String addressStr = props.getProperty(SouthboundITConstants.SERVER_IPADDRESS,
263 SouthboundITConstants.DEFAULT_SERVER_IPADDRESS);
264 String portStr = props.getProperty(SouthboundITConstants.SERVER_PORT,
265 SouthboundITConstants.DEFAULT_SERVER_PORT);
266 String connectionType = props.getProperty(SouthboundITConstants.CONNECTION_TYPE,
267 SouthboundITConstants.CONNECTION_TYPE_ACTIVE);
269 LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
270 connectionType, addressStr, portStr);
272 return new Option[] {
273 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
274 SouthboundITConstants.SERVER_IPADDRESS, addressStr),
275 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
276 SouthboundITConstants.SERVER_PORT, portStr),
277 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
278 SouthboundITConstants.CONNECTION_TYPE, connectionType),
284 public void setup() throws InterruptedException {
286 LOG.info("Skipping setup, already initialized");
292 } catch (Exception e) {
295 //dataBroker = getSession().getSALService(DataBroker.class);
297 DataBroker dataBroker = SouthboundProvider.getDb();
298 Assert.assertNotNull("db should not be null", dataBroker);
300 addressStr = bundleContext.getProperty(SouthboundITConstants.SERVER_IPADDRESS);
301 String portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT);
303 portNumber = Integer.parseInt(portStr);
304 } catch (NumberFormatException e) {
305 fail("Invalid port number " + portStr + System.lineSeparator() + usage());
307 connectionType = bundleContext.getProperty(SouthboundITConstants.CONNECTION_TYPE);
309 LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
310 connectionType, addressStr, portNumber);
311 if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_ACTIVE)) {
312 if (addressStr == null) {
317 mdsalUtils = new MdsalUtils(dataBroker);
318 final ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
319 final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
320 dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
321 iid, CONFIGURATION_LISTENER, AsyncDataBroker.DataChangeScope.SUBTREE);
322 dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
323 iid, OPERATIONAL_LISTENER, AsyncDataBroker.DataChangeScope.SUBTREE);
325 ovsdbNode = connectOvsdbNode(connectionInfo);
331 * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
332 * 6640. This test will wait for incoming connections for {@link SouthboundITConstants#CONNECTION_INIT_TIMEOUT} ms.
334 * @throws InterruptedException
337 public void testPassiveNode() throws InterruptedException {
338 if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_PASSIVE)) {
339 //Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
340 Thread.sleep(SouthboundITConstants.CONNECTION_INIT_TIMEOUT);
344 private ConnectionInfo getConnectionInfo(final String addressStr, final int portNumber) {
345 InetAddress inetAddress = null;
347 inetAddress = InetAddress.getByName(addressStr);
348 } catch (UnknownHostException e) {
349 fail("Could not resolve " + addressStr + ": " + e);
352 IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
353 PortNumber port = new PortNumber(portNumber);
355 final ConnectionInfo connectionInfo = new ConnectionInfoBuilder()
356 .setRemoteIp(address)
359 LOG.info("connectionInfo: {}", connectionInfo);
360 return connectionInfo;
364 public void testNetworkTopology() throws InterruptedException {
365 NetworkTopology networkTopology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION,
366 InstanceIdentifier.create(NetworkTopology.class));
367 Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.CONFIGURATION,
370 networkTopology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
371 InstanceIdentifier.create(NetworkTopology.class));
372 Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.OPERATIONAL,
377 public void testOvsdbTopology() throws InterruptedException {
378 InstanceIdentifier<Topology> path = InstanceIdentifier
379 .create(NetworkTopology.class)
380 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
382 Topology topology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
383 Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
386 topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
388 Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
392 private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
393 final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
395 mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, iid, SouthboundUtils.createNode(connectionInfo)));
396 waitForOperationalCreation(iid);
397 Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
398 Assert.assertNotNull(node);
399 LOG.info("Connected to {}", SouthboundUtils.connectionInfoToString(connectionInfo));
403 private void waitForOperationalCreation(InstanceIdentifier<Node> iid) throws InterruptedException {
404 synchronized (OPERATIONAL_LISTENER) {
405 long _start = System.currentTimeMillis();
406 LOG.info("Waiting for OPERATIONAL DataChanged creation on {}", iid);
407 while (!OPERATIONAL_LISTENER.isCreated(
408 iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
409 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
411 LOG.info("Woke up, waited {} for creation of {}", (System.currentTimeMillis() - _start), iid);
415 private static void waitForOperationalDeletion(InstanceIdentifier<Node> iid) throws InterruptedException {
416 synchronized (OPERATIONAL_LISTENER) {
417 long _start = System.currentTimeMillis();
418 LOG.info("Waiting for OPERATIONAL DataChanged deletion on {}", iid);
419 while (!OPERATIONAL_LISTENER.isRemoved(
420 iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
421 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
423 LOG.info("Woke up, waited {} for deletion of {}", (System.currentTimeMillis() - _start), iid);
427 private void waitForOperationalUpdate(InstanceIdentifier<Node> iid) throws InterruptedException {
428 synchronized (OPERATIONAL_LISTENER) {
429 long _start = System.currentTimeMillis();
430 LOG.info("Waiting for OPERATIONAL DataChanged update on {}", iid);
431 while (!OPERATIONAL_LISTENER.isUpdated(
432 iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
433 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
435 LOG.info("Woke up, waited {} for update of {}", (System.currentTimeMillis() - _start), iid);
439 private static void disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
440 final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
441 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
442 waitForOperationalDeletion(iid);
443 Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
444 Assert.assertNull(node);
445 LOG.info("Disconnected from {}", SouthboundUtils.connectionInfoToString(connectionInfo));
449 public void testAddDeleteOvsdbNode() throws InterruptedException {
450 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
451 // At this point we're connected, disconnect and reconnect (the connection will be removed at the very end)
452 disconnectOvsdbNode(connectionInfo);
453 connectOvsdbNode(connectionInfo);
457 public void testDpdkSwitch() throws InterruptedException {
458 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
459 List<DatapathTypeEntry> datapathTypeEntries = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class)
460 .getDatapathTypeEntry();
461 if (datapathTypeEntries == null) {
462 LOG.info("DPDK not supported on this node.");
464 for (DatapathTypeEntry dpTypeEntry : datapathTypeEntries) {
465 Class<? extends DatapathTypeBase> dpType = dpTypeEntry.getDatapathType();
466 String dpTypeStr = SouthboundConstants.DATAPATH_TYPE_MAP.get(dpType);
467 LOG.info("dp type is {}", dpTypeStr);
468 if (dpTypeStr.equals(NETDEV_DP_TYPE)) {
469 LOG.info("Found a DPDK node; adding a corresponding netdev device");
470 InstanceIdentifier<Node> bridgeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo,
471 new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
472 NodeId bridgeNodeId = SouthboundUtils.createManagedNodeId(bridgeIid);
473 try (TestBridge testBridge = new TestBridge(connectionInfo, bridgeIid,
474 SouthboundITConstants.BRIDGE_NAME, bridgeNodeId, false, null, true, dpType, null, null,
476 // Verify that the device is netdev
477 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
478 Assert.assertNotNull(bridge);
479 Assert.assertEquals(dpType, bridge.getDatapathType());
481 // Add port for all dpdk interface types (dpdkvhost not supported in existing dpdk ovs)
482 List<String> dpdkTypes = new ArrayList<String>();
483 dpdkTypes.add("dpdk");
484 dpdkTypes.add("dpdkr");
485 dpdkTypes.add("dpdkvhostuser");
486 //dpdkTypes.add("dpdkvhost");
488 for (String dpdkType : dpdkTypes) {
489 String testPortname = "test"+dpdkType+"port";
490 LOG.info("DPDK portname and type is {}, {}", testPortname, dpdkType);
491 Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
493 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationpointBuilder =
494 createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(testPortname,
497 addTerminationPoint(bridgeNodeId, testPortname, ovsdbTerminationpointBuilder));
500 // Verify that all DPDK ports are created
501 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
502 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
503 terminationPointIid);
504 Assert.assertNotNull(terminationPointNode);
506 // Verify that each termination point has the specific DPDK ifType
507 for (String dpdkType : dpdkTypes) {
508 String testPortname = "test"+dpdkType+"port";
509 Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
511 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
512 for (TerminationPoint terminationPoint : terminationPoints) {
513 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint
514 .getAugmentation(OvsdbTerminationPointAugmentation.class);
515 if (ovsdbTerminationPointAugmentation.getName().equals(testPortname)) {
516 Class<? extends InterfaceTypeBase> opPort = ovsdbTerminationPointAugmentation
518 Assert.assertEquals(dpdkIfType, opPort);
530 public void testOvsdbNodeOvsVersion() throws InterruptedException {
531 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
532 Assert.assertNotNull(ovsdbNodeAugmentation);
533 assertNotNull(ovsdbNodeAugmentation.getOvsVersion());
537 public void testOpenVSwitchOtherConfig() throws InterruptedException {
538 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
539 Assert.assertNotNull(ovsdbNodeAugmentation);
540 List<OpenvswitchOtherConfigs> otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
541 if (otherConfigsList != null) {
542 for (OpenvswitchOtherConfigs otherConfig : otherConfigsList) {
543 if (otherConfig.getOtherConfigKey().equals("local_ip")) {
544 LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
547 LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
551 LOG.info("other_config is not present");
556 public void testOvsdbBridgeControllerInfo() throws InterruptedException {
557 ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portNumber);
558 String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
559 assertNotNull("Failed to get controller target", controllerTarget);
560 List<ControllerEntry> setControllerEntry = createControllerEntry(controllerTarget);
561 Uri setUri = new Uri(controllerTarget);
562 try (TestBridge testBridge = new TestBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true,
563 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
564 setControllerEntry, null)) {
565 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
566 Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME, bridge);
567 Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
568 bridge.getControllerEntry());
569 List<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
570 for (ControllerEntry entry : getControllerEntries) {
571 if (entry.getTarget() != null) {
572 Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
578 private List<ControllerEntry> createControllerEntry(String controllerTarget) {
579 List<ControllerEntry> controllerEntriesList = new ArrayList<>();
580 controllerEntriesList.add(new ControllerEntryBuilder()
581 .setTarget(new Uri(controllerTarget))
583 return controllerEntriesList;
586 private static void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
587 final ConnectionInfo connectionInfo) {
588 InstanceIdentifier<Node> connectionNodePath = SouthboundUtils.createInstanceIdentifier(connectionInfo);
589 ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
592 private static List<ProtocolEntry> createMdsalProtocols() {
593 List<ProtocolEntry> protocolList = new ArrayList<>();
594 ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
595 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
596 protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
600 private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
601 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
602 new OvsdbTerminationPointAugmentationBuilder();
603 ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
604 new InterfaceTypeEntryBuilder()
606 SouthboundMapper.createInterfaceType("internal"))
607 .build().getInterfaceType());
608 return ovsdbTerminationPointAugmentationBuilder;
611 private OvsdbTerminationPointAugmentationBuilder createGenericDpdkOvsdbTerminationPointAugmentationBuilder(
612 final String portName) {
613 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
614 createGenericOvsdbTerminationPointAugmentationBuilder();
615 ovsdbTerminationBuilder.setName(portName);
616 Class<? extends InterfaceTypeBase> ifType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
618 ovsdbTerminationBuilder.setInterfaceType(ifType);
619 return ovsdbTerminationBuilder;
622 private OvsdbTerminationPointAugmentationBuilder createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(
623 String testPortname,Class<? extends InterfaceTypeBase> dpdkIfType) {
624 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
625 createGenericOvsdbTerminationPointAugmentationBuilder();
626 ovsdbTerminationBuilder.setName(testPortname);
627 ovsdbTerminationBuilder.setInterfaceType(dpdkIfType);
628 return ovsdbTerminationBuilder;
631 private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
632 final OvsdbTerminationPointAugmentationBuilder
633 ovsdbTerminationPointAugmentationBuilder)
634 throws InterruptedException {
636 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
637 NodeBuilder portNodeBuilder = new NodeBuilder();
638 NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
639 portNodeBuilder.setNodeId(portNodeId);
640 TerminationPointBuilder entry = new TerminationPointBuilder();
641 entry.setKey(new TerminationPointKey(new TpId(portName)));
642 entry.addAugmentation(
643 OvsdbTerminationPointAugmentation.class,
644 ovsdbTerminationPointAugmentationBuilder.build());
645 portNodeBuilder.setTerminationPoint(Lists.newArrayList(entry.build()));
646 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
647 portIid, portNodeBuilder.build());
648 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
652 private static class TestBridge implements AutoCloseable {
653 private final ConnectionInfo connectionInfo;
654 private final String bridgeName;
657 * Creates a test bridge which can be automatically removed when no longer necessary.
659 * @param connectionInfo The connection information.
660 * @param bridgeIid The bridge identifier; if {@code null}, one is created based on {@code bridgeName}.
661 * @param bridgeName The bridge name; must be provided.
662 * @param bridgeNodeId The bridge node identifier; if {@code null}, one is created based on {@code bridgeIid}.
663 * @param setProtocolEntries {@code true} to set default protocol entries for the bridge.
664 * @param failMode The fail mode to set for the bridge.
665 * @param setManagedBy {@code true} to specify {@code setManagedBy} for the bridge.
666 * @param dpType The datapath type.
667 * @param externalIds The external identifiers if any.
668 * @param otherConfigs The other configuration items if any.
670 public TestBridge(final ConnectionInfo connectionInfo, @Nullable InstanceIdentifier<Node> bridgeIid,
671 final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
672 final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
673 @Nullable final Class<? extends DatapathTypeBase> dpType,
674 @Nullable final List<BridgeExternalIds> externalIds,
675 @Nullable final List<ControllerEntry> controllerEntries,
676 @Nullable final List<BridgeOtherConfigs> otherConfigs) {
677 this.connectionInfo = connectionInfo;
678 this.bridgeName = bridgeName;
679 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
680 if (bridgeIid == null) {
681 bridgeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
683 if (bridgeNodeId == null) {
684 bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
686 bridgeNodeBuilder.setNodeId(bridgeNodeId);
687 OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
688 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
689 if (setProtocolEntries) {
690 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
692 ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
694 setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
696 ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
697 ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
698 ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
699 ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
700 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
701 LOG.debug("Built with the intent to store bridge data {}", ovsdbBridgeAugmentationBuilder.toString());
703 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, bridgeNodeBuilder.build()));
705 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
706 } catch (InterruptedException e) {
707 LOG.warn("Sleep interrupted while waiting for bridge creation (bridge {})", bridgeName, e);
711 public TestBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
712 this(connectionInfo, null, bridgeName, null, true,
713 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
717 public void close() {
718 final InstanceIdentifier<Node> iid =
719 SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
720 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
722 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
723 } catch (InterruptedException e) {
724 LOG.warn("Sleep interrupted while waiting for bridge deletion (bridge {})", bridgeName, e);
729 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
730 return getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
734 * Extract the <code>store</code> type data store contents for the particular bridge identified by
735 * <code>bridgeName</code>.
737 * @param connectionInfo the connection information
738 * @param bridgeName the bridge name
739 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
740 * @return <code>store</code> type data store contents
742 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
743 LogicalDatastoreType store) {
744 Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
745 Assert.assertNotNull(bridgeNode);
746 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
747 Assert.assertNotNull(ovsdbBridgeAugmentation);
748 return ovsdbBridgeAugmentation;
752 * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
753 * identified by <code>bridgeName</code>
755 * @param connectionInfo the connection information
756 * @param bridgeName the bridge name
757 * @see <code>SouthboundIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
758 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
760 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
761 return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
765 * Extract the node contents from <code>store</code> type data store for the
766 * bridge identified by <code>bridgeName</code>
768 * @param connectionInfo the connection information
769 * @param bridgeName the bridge name
770 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
771 * @return <code>store</code> type data store contents
773 private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
774 InstanceIdentifier<Node> bridgeIid =
775 SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
776 return mdsalUtils.read(store, bridgeIid);
780 * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
781 * bridge identified by <code>bridgeName</code>
783 * @param connectionInfo the connection information
784 * @param bridgeName the bridge name
785 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
787 private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
788 return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
792 public void testAddDeleteBridge() throws InterruptedException {
793 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
795 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
796 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
797 Assert.assertNotNull(bridge);
798 LOG.info("bridge: {}", bridge);
802 private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
803 return SouthboundUtils.createInstanceIdentifier(connectionInfo, bridge.getBridgeName());
807 * Extracts the <code>TerminationPointAugmentation</code> for the <code>index</code> <code>TerminationPoint</code>
808 * on <code>bridgeName</code>
810 * @param connectionInfo the connection information
811 * @param bridgeName the bridge name
812 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
813 * @param index the index we're interested in
814 * @return the augmentation (or {@code null} if none)
816 private OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation(
817 ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index) {
819 List<TerminationPoint> tpList = getBridgeNode(connectionInfo, bridgeName, store).getTerminationPoint();
820 if (tpList == null) {
823 return tpList.get(index).getAugmentation(OvsdbTerminationPointAugmentation.class);
827 public void testCRDTerminationPointOfPort() throws InterruptedException {
828 final Long OFPORT_EXPECTED = 45002L;
830 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
833 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
834 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
835 Assert.assertNotNull(bridge);
836 LOG.info("bridge: {}", bridge);
837 NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
838 connectionInfo, bridge.getBridgeName()));
839 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
840 createGenericOvsdbTerminationPointAugmentationBuilder();
841 String portName = "testOfPort";
842 ovsdbTerminationBuilder.setName(portName);
844 ovsdbTerminationBuilder.setOfport(OFPORT_EXPECTED);
845 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
846 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
847 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
848 Assert.assertNotNull(terminationPointNode);
851 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
852 for (TerminationPoint terminationPoint : terminationPoints) {
853 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
854 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
855 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
856 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
857 // if ephemeral port 45002 is in use, ofPort is set to 1
858 Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(1L));
859 LOG.info("ofPort: {}", ofPort);
863 // UPDATE- Not Applicable. From the OpenVSwitch Documentation:
864 // "A client should ideally set this column’s value in the same database transaction that it uses to create
867 // DELETE handled by TestBridge
872 public void testCRDTerminationPointOfPortRequest() throws InterruptedException {
873 final Long OFPORT_EXPECTED = 45008L;
874 final Long OFPORT_INPUT = 45008L;
876 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
879 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
880 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
881 Assert.assertNotNull(bridge);
882 NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
883 connectionInfo, bridge.getBridgeName()));
884 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
885 createGenericOvsdbTerminationPointAugmentationBuilder();
886 String portName = "testOfPortRequest";
887 ovsdbTerminationBuilder.setName(portName);
888 Integer ofPortRequestExpected = OFPORT_EXPECTED.intValue();
889 ovsdbTerminationBuilder.setOfport(OFPORT_INPUT);
890 ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected);
891 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
892 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
893 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
894 Assert.assertNotNull(terminationPointNode);
897 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
898 for (TerminationPoint terminationPoint : terminationPoints) {
899 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
900 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
901 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
902 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
903 // if ephemeral port 45008 is in use, ofPort is set to 1
904 Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(1L));
905 LOG.info("ofPort: {}", ofPort);
907 Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest();
908 Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected));
909 LOG.info("ofPortRequest: {}", ofPortRequest);
913 // UPDATE- Not Applicable. From the OpenVSwitch documentation:
914 // "A client should ideally set this column’s value in the same database transaction that it uses to
915 // create the interface. "
917 // DELETE handled by TestBridge
921 private <T> void assertExpectedExist(List<T> expected, List<T> test) {
922 if (expected != null && test != null) {
923 for (T exp : expected) {
924 Assert.assertTrue("The retrieved values don't contain " + exp, test.contains(exp));
929 private interface SouthboundTerminationPointHelper<T> {
930 void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<T> values);
931 List<T> readValues(OvsdbTerminationPointAugmentation augmentation);
935 * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
937 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
939 private <T> void testCRUDTerminationPoint(
940 KeyValueBuilder<T> builder, String prefix, SouthboundTerminationPointHelper<T> helper)
941 throws InterruptedException {
942 final int TERMINATION_POINT_TEST_INDEX = 0;
944 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
946 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
947 // the update has been performed.
948 List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
949 List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
951 for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
952 for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
953 String testBridgeAndPortName = String.format("%s_%s", prefix, updateToTestCase.name);
955 // CREATE: Create the test bridge
956 try (TestBridge testBridge = new TestBridge(connectionInfo, null, testBridgeAndPortName, null, true,
957 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null,
959 NodeId testBridgeNodeId = SouthboundUtils.createManagedNodeId(
960 SouthboundUtils.createInstanceIdentifier(connectionInfo,
961 new OvsdbBridgeName(testBridgeAndPortName)));
962 OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
963 createGenericOvsdbTerminationPointAugmentationBuilder();
964 tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
965 helper.writeValues(tpCreateAugmentationBuilder, updateFromTestCase.inputValues);
967 addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
969 // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
970 // then repeat for OPERATIONAL data store
971 OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
972 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
973 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
974 if (updateFromConfigurationTerminationPointAugmentation != null) {
975 List<T> updateFromConfigurationValues =
976 helper.readValues(updateFromConfigurationTerminationPointAugmentation);
977 assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues);
979 OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
980 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
981 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
982 if (updateFromOperationalTerminationPointAugmentation != null) {
983 List<T> updateFromOperationalValues =
984 helper.readValues(updateFromOperationalTerminationPointAugmentation);
985 assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues);
988 // UPDATE: update the values
989 testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
990 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
991 new OvsdbTerminationPointAugmentationBuilder();
992 helper.writeValues(tpUpdateAugmentationBuilder, updateToTestCase.inputValues);
993 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
994 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
995 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
996 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
997 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
998 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
999 tpUpdateBuilder.addAugmentation(
1000 OvsdbTerminationPointAugmentation.class,
1001 tpUpdateAugmentationBuilder.build());
1002 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1003 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1004 portIid, portUpdateNodeBuilder.build()));
1005 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1007 // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
1008 // then repeat for OPERATIONAL data store
1009 OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1010 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1011 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1012 if (updateToConfigurationTerminationPointAugmentation != null) {
1013 List<T> updateToConfigurationValues =
1014 helper.readValues(updateToConfigurationTerminationPointAugmentation);
1015 assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues);
1016 assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationValues);
1018 OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1019 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1020 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1021 if (updateToOperationalTerminationPointAugmentation != null) {
1022 List<T> updateToOperationalValues =
1023 helper.readValues(updateToOperationalTerminationPointAugmentation);
1024 if (updateFromTestCase.expectedValues != null) {
1025 assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
1026 assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalValues);
1030 // DELETE handled by TestBridge
1037 * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
1039 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1042 public void testCRUDTerminationPointPortExternalIds() throws InterruptedException {
1043 testCRUDTerminationPoint(new SouthboundPortExternalIdsBuilder(), "TPPortExternalIds",
1044 new PortExternalIdsSouthboundHelper());
1048 * Tests the CRUD operations for <code>Interface</code> <code>external_ids</code>.
1050 * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1053 public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException {
1054 testCRUDTerminationPoint(new SouthboundInterfaceExternalIdsBuilder(), "TPInterfaceExternalIds",
1055 new InterfaceExternalIdsSouthboundHelper());
1059 * Tests the CRUD operations for <code>TerminationPoint</code> <code>options</code>.
1061 * @see <code>SouthboundIT.generateTerminationPointOptions()</code> for specific test case information
1064 public void testCRUDTerminationPointOptions() throws InterruptedException {
1065 testCRUDTerminationPoint(new SouthboundOptionsBuilder(), "TPOptions", new OptionsSouthboundHelper());
1069 * Tests the CRUD operations for <code>Interface</code> <code>other_configs</code>.
1071 * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1074 public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException {
1075 testCRUDTerminationPoint(new SouthboundInterfaceOtherConfigsBuilder(), "TPInterfaceOtherConfigs",
1076 new InterfaceOtherConfigsSouthboundHelper());
1080 * Tests the CRUD operations for <code>Port</code> <code>other_configs</code>.
1082 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1085 public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException {
1086 testCRUDTerminationPoint(new SouthboundPortOtherConfigsBuilder(), "TPPortOtherConfigs",
1087 new PortOtherConfigsSouthboundHelper());
1091 public void testCRUDTerminationPointVlan() throws InterruptedException {
1092 final Integer CREATED_VLAN_ID = 4000;
1093 final Integer UPDATED_VLAN_ID = 4001;
1095 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1098 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1099 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1100 Assert.assertNotNull(bridge);
1101 NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1102 connectionInfo, bridge.getBridgeName()));
1103 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1104 createGenericOvsdbTerminationPointAugmentationBuilder();
1105 String portName = "testTerminationPointVlanId";
1106 ovsdbTerminationBuilder.setName(portName);
1107 ovsdbTerminationBuilder.setVlanTag(new VlanId(CREATED_VLAN_ID));
1108 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1109 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1110 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1111 Assert.assertNotNull(terminationPointNode);
1114 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1115 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation;
1116 for (TerminationPoint terminationPoint : terminationPoints) {
1117 ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1118 OvsdbTerminationPointAugmentation.class);
1119 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1120 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1121 Assert.assertNotNull(actualVlanId);
1122 Integer actualVlanIdInt = actualVlanId.getValue();
1123 Assert.assertEquals(CREATED_VLAN_ID, actualVlanIdInt);
1128 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1129 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1130 new OvsdbTerminationPointAugmentationBuilder();
1131 tpUpdateAugmentationBuilder.setVlanTag(new VlanId(UPDATED_VLAN_ID));
1132 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1133 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1134 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1135 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1136 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1137 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1138 tpUpdateBuilder.addAugmentation(
1139 OvsdbTerminationPointAugmentation.class,
1140 tpUpdateAugmentationBuilder.build());
1141 tpUpdateBuilder.setTpId(new TpId(portName));
1142 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1144 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1145 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1147 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1148 terminationPoints = terminationPointNode.getTerminationPoint();
1149 for (TerminationPoint terminationPoint : terminationPoints) {
1150 ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1151 OvsdbTerminationPointAugmentation.class);
1152 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1153 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1154 Assert.assertNotNull(actualVlanId);
1155 Integer actualVlanIdInt = actualVlanId.getValue();
1156 Assert.assertEquals(UPDATED_VLAN_ID, actualVlanIdInt);
1160 // DELETE handled by TestBridge
1165 public void testCRUDTerminationPointVlanModes() throws InterruptedException {
1166 final VlanMode UPDATED_VLAN_MODE = VlanMode.Access;
1167 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1168 VlanMode []vlanModes = VlanMode.values();
1169 for (VlanMode vlanMode : vlanModes) {
1171 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1172 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1173 Assert.assertNotNull(bridge);
1174 NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1175 connectionInfo, bridge.getBridgeName()));
1176 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1177 createGenericOvsdbTerminationPointAugmentationBuilder();
1178 String portName = "testTerminationPointVlanMode" + vlanMode.toString();
1179 ovsdbTerminationBuilder.setName(portName);
1180 ovsdbTerminationBuilder.setVlanMode(vlanMode);
1181 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1182 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1183 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1184 Assert.assertNotNull(terminationPointNode);
1187 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1188 for (TerminationPoint terminationPoint : terminationPoints) {
1189 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1190 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1191 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1193 Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode));
1198 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1199 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1200 new OvsdbTerminationPointAugmentationBuilder();
1201 tpUpdateAugmentationBuilder.setVlanMode(UPDATED_VLAN_MODE);
1202 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1203 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1204 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1205 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1206 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1207 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1208 tpUpdateBuilder.addAugmentation(
1209 OvsdbTerminationPointAugmentation.class,
1210 tpUpdateAugmentationBuilder.build());
1211 tpUpdateBuilder.setTpId(new TpId(portName));
1212 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1214 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1215 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1217 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1218 terminationPoints = terminationPointNode.getTerminationPoint();
1219 for (TerminationPoint terminationPoint : terminationPoints) {
1220 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1221 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1222 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1224 Assert.assertEquals(UPDATED_VLAN_MODE, ovsdbTerminationPointAugmentation.getVlanMode());
1228 // DELETE handled by TestBridge
1233 @SuppressWarnings("unchecked")
1234 private List<Set<Integer>> generateVlanSets() {
1237 return Lists.newArrayList(
1238 Collections.<Integer>emptySet(),
1239 Sets.newHashSet(2222),
1240 Sets.newHashSet(min, max, min + 1, max - 1, (max - min) / 2));
1243 private List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
1244 List<Trunks> trunkList = Lists.newArrayList();
1245 for (Integer trunk : trunkSet) {
1246 TrunksBuilder trunkBuilder = new TrunksBuilder();
1247 trunkBuilder.setTrunk(new VlanId(trunk));
1248 trunkList.add(trunkBuilder.build());
1254 public void testCRUDTerminationPointVlanTrunks() throws InterruptedException {
1255 final List<Trunks> UPDATED_TRUNKS = buildTrunkList(Sets.newHashSet(2011));
1256 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1257 Iterable<Set<Integer>> vlanSets = generateVlanSets();
1259 for (Set<Integer> vlanSet : vlanSets) {
1262 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1263 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1264 Assert.assertNotNull(bridge);
1265 NodeId nodeId = SouthboundUtils.createManagedNodeId(connectionInfo, bridge.getBridgeName());
1266 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1267 createGenericOvsdbTerminationPointAugmentationBuilder();
1268 String portName = "testTerminationPointVlanTrunks" + testCase;
1269 ovsdbTerminationBuilder.setName(portName);
1270 List<Trunks> trunks = buildTrunkList(vlanSet);
1271 ovsdbTerminationBuilder.setTrunks(trunks);
1272 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1273 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1274 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1275 Assert.assertNotNull(terminationPointNode);
1278 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1279 for (TerminationPoint terminationPoint : terminationPoints) {
1280 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1281 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1282 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1283 List<Trunks> actualTrunks = ovsdbTerminationPointAugmentation.getTrunks();
1284 for (Trunks trunk : trunks) {
1285 Assert.assertTrue(actualTrunks.contains(trunk));
1292 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1293 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1294 new OvsdbTerminationPointAugmentationBuilder();
1295 tpUpdateAugmentationBuilder.setTrunks(UPDATED_TRUNKS);
1296 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1297 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1298 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1299 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1300 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1301 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1302 tpUpdateBuilder.addAugmentation(
1303 OvsdbTerminationPointAugmentation.class,
1304 tpUpdateAugmentationBuilder.build());
1305 tpUpdateBuilder.setTpId(new TpId(portName));
1306 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1308 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1309 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1311 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1312 terminationPoints = terminationPointNode.getTerminationPoint();
1313 for (TerminationPoint terminationPoint : terminationPoints) {
1314 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1315 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1316 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1318 Assert.assertEquals(UPDATED_TRUNKS, ovsdbTerminationPointAugmentation.getTrunks());
1322 // DELETE handled by TestBridge
1328 public void testGetOvsdbNodes() throws InterruptedException {
1329 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1330 InstanceIdentifier<Topology> topologyPath = InstanceIdentifier
1331 .create(NetworkTopology.class)
1332 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
1334 Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath);
1335 InstanceIdentifier<Node> expectedNodeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
1336 NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class, NodeKey.class).getNodeId();
1337 Node foundNode = null;
1338 Assert.assertNotNull("Expected to find topology: " + topologyPath, topology);
1339 Assert.assertNotNull("Expected to find some nodes" + topology.getNode());
1340 LOG.info("expectedNodeId: {}, getNode: {}", expectedNodeId, topology.getNode());
1341 for (Node node : topology.getNode()) {
1342 if (node.getNodeId().getValue().equals(expectedNodeId.getValue())) {
1347 Assert.assertNotNull("Expected to find Node: " + expectedNodeId, foundNode);
1351 * @see <code>SouthboundIT.generateBridgeOtherConfigsTestCases()</code> for specific test case information.
1354 public void testCRUDBridgeOtherConfigs() throws InterruptedException {
1355 testCRUDBridge("BridgeOtherConfigs", new SouthboundBridgeOtherConfigsBuilder(),
1356 new BridgeOtherConfigsSouthboundHelper());
1359 private interface SouthboundBridgeHelper<T> {
1360 void writeValues(OvsdbBridgeAugmentationBuilder builder, List<T> values);
1361 List<T> readValues(OvsdbBridgeAugmentation augmentation);
1364 private <T> void testCRUDBridge(String prefix, KeyValueBuilder<T> builder, SouthboundBridgeHelper<T> helper)
1365 throws InterruptedException {
1366 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1367 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
1368 // the update has been performed.
1369 List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
1370 List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
1371 for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
1372 for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
1373 String testBridgeName = String.format("%s_%s", prefix, updateToTestCase.name);
1375 // CREATE: Create the test bridge
1376 final OvsdbBridgeName ovsdbBridgeName = new OvsdbBridgeName(testBridgeName);
1377 final InstanceIdentifier<Node> bridgeIid =
1378 SouthboundUtils.createInstanceIdentifier(connectionInfo, ovsdbBridgeName);
1379 final NodeId bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
1380 final NodeBuilder bridgeCreateNodeBuilder = new NodeBuilder();
1381 bridgeCreateNodeBuilder.setNodeId(bridgeNodeId);
1382 OvsdbBridgeAugmentationBuilder bridgeCreateAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
1383 bridgeCreateAugmentationBuilder.setBridgeName(ovsdbBridgeName);
1384 bridgeCreateAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
1385 bridgeCreateAugmentationBuilder.setFailMode(
1386 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
1387 setManagedBy(bridgeCreateAugmentationBuilder, connectionInfo);
1388 helper.writeValues(bridgeCreateAugmentationBuilder, updateFromTestCase.inputValues);
1389 bridgeCreateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
1390 bridgeCreateAugmentationBuilder.build());
1391 LOG.debug("Built with the intent to store bridge data {}", bridgeCreateAugmentationBuilder.toString());
1392 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
1393 bridgeCreateNodeBuilder.build()));
1394 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1396 // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
1397 // then repeat for OPERATIONAL data store
1398 List<T> updateFromConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
1399 LogicalDatastoreType.CONFIGURATION));
1400 assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationExternalIds);
1401 List<T> updateFromOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName));
1402 assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalExternalIds);
1404 // UPDATE: update the values
1405 final OvsdbBridgeAugmentationBuilder bridgeUpdateAugmentationBuilder =
1406 new OvsdbBridgeAugmentationBuilder();
1407 helper.writeValues(bridgeUpdateAugmentationBuilder, updateToTestCase.inputValues);
1408 final NodeBuilder bridgeUpdateNodeBuilder = new NodeBuilder();
1409 final Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
1410 bridgeUpdateNodeBuilder.setNodeId(bridgeNode.getNodeId());
1411 bridgeUpdateNodeBuilder.setKey(bridgeNode.getKey());
1412 bridgeUpdateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
1413 bridgeUpdateAugmentationBuilder.build());
1414 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
1415 bridgeUpdateNodeBuilder.build()));
1416 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1418 // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
1419 // then repeat for OPERATIONAL data store
1420 List<T> updateToConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
1421 LogicalDatastoreType.CONFIGURATION));
1422 assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationExternalIds);
1423 assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationExternalIds);
1424 List<T> updateToOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName));
1425 if (updateFromTestCase.expectedValues != null) {
1426 assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalExternalIds);
1427 assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalExternalIds);
1431 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, bridgeIid));
1432 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1438 * @see <code>SouthboundIT.generateBridgeExternalIdsTestCases()</code> for specific test case information
1441 public void testCRUDBridgeExternalIds() throws InterruptedException {
1442 testCRUDBridge("BridgeExternalIds", new SouthboundBridgeExternalIdsBuilder(),
1443 new BridgeExternalIdsSouthboundHelper());
1448 * Representation of a southbound test case. Each test case has a name, a list of input values and a list of
1449 * expected values. The input values are provided to the augmentation builder, and the expected values are checked
1450 * against the output of the resulting augmentation.
1453 * Instances of this class are immutable.
1456 * @param <T> The type of data used for the test case.
1458 private static final class SouthboundTestCase<T> {
1459 private final String name;
1460 private final List<T> inputValues;
1461 private final List<T> expectedValues;
1464 * Creates an instance of a southbound test case.
1466 * @param name The test case's name.
1467 * @param inputValues The input values (provided as input to the underlying augmentation builder).
1468 * @param expectedValues The expected values (checked against the output of the underlying augmentation).
1470 public SouthboundTestCase(
1471 final String name, final List<T> inputValues, final List<T> expectedValues) {
1473 this.inputValues = inputValues;
1474 this.expectedValues = expectedValues;
1479 * Southbound test case builder.
1481 * @param <T> The type of data used for the test case.
1483 private static final class SouthboundTestCaseBuilder<T> {
1484 private String name;
1485 private List<T> inputValues;
1486 private List<T> expectedValues;
1489 * Creates a builder. Builders may be reused, the generated immutable instances are independent of the
1490 * builders. There are no default values.
1492 public SouthboundTestCaseBuilder() {
1497 * Sets the test case's name.
1499 * @param name The test case's name.
1500 * @return The builder.
1502 public SouthboundTestCaseBuilder<T> name(final String name) {
1508 * Sets the input values.
1510 * @param inputValues The input values.
1511 * @return The builder.
1514 public final SouthboundTestCaseBuilder<T> input(final T... inputValues) {
1515 this.inputValues = Lists.newArrayList(inputValues);
1520 * Indicates that the provided input values should be expected as output values.
1522 * @return The builder.
1524 public SouthboundTestCaseBuilder<T> expectInputAsOutput() {
1525 this.expectedValues = this.inputValues;
1530 * Indicates that no output should be expected.
1532 * @return The builder.
1534 public SouthboundTestCaseBuilder<T> expectNoOutput() {
1535 this.expectedValues = null;
1540 * Builds an immutable instance representing the test case.
1542 * @return The test case.
1544 @SuppressWarnings("unchecked")
1545 public SouthboundTestCase<T> build() {
1546 return new SouthboundTestCase<>(name, inputValues, expectedValues);
1550 private abstract static class KeyValueBuilder<T> {
1551 private static final int COUNTER_START = 0;
1552 private int counter = COUNTER_START;
1554 protected abstract Builder<T> builder();
1556 protected abstract void setKey(Builder<T> builder, String key);
1558 protected abstract void setValue(Builder<T> builder, String value);
1560 public final T build(final String testName, final String key, final String value) {
1561 final Builder<T> builder = builder();
1564 setKey(builder, String.format(FORMAT_STR, testName, key, this.counter));
1566 if (value != null) {
1567 setValue(builder, String.format(FORMAT_STR, testName, value, this.counter));
1569 return builder.build();
1572 public final void reset() {
1573 this.counter = COUNTER_START;
1577 private static final class SouthboundPortExternalIdsBuilder extends KeyValueBuilder<PortExternalIds> {
1579 protected Builder<PortExternalIds> builder() {
1580 return new PortExternalIdsBuilder();
1584 protected void setKey(Builder<PortExternalIds> builder, String key) {
1585 ((PortExternalIdsBuilder) builder).setExternalIdKey(key);
1589 protected void setValue(Builder<PortExternalIds> builder, String value) {
1590 ((PortExternalIdsBuilder) builder).setExternalIdValue(value);
1594 private static final class SouthboundInterfaceExternalIdsBuilder extends KeyValueBuilder<InterfaceExternalIds> {
1596 protected Builder<InterfaceExternalIds> builder() {
1597 return new InterfaceExternalIdsBuilder();
1601 protected void setKey(Builder<InterfaceExternalIds> builder, String key) {
1602 ((InterfaceExternalIdsBuilder) builder).setExternalIdKey(key);
1606 protected void setValue(Builder<InterfaceExternalIds> builder, String value) {
1607 ((InterfaceExternalIdsBuilder) builder).setExternalIdValue(value);
1611 private static final class SouthboundOptionsBuilder extends KeyValueBuilder<Options> {
1613 protected Builder<Options> builder() {
1614 return new OptionsBuilder();
1618 protected void setKey(Builder<Options> builder, String key) {
1619 ((OptionsBuilder) builder).setOption(key);
1623 protected void setValue(Builder<Options> builder, String value) {
1624 ((OptionsBuilder) builder).setValue(value);
1628 private static final class SouthboundInterfaceOtherConfigsBuilder extends KeyValueBuilder<InterfaceOtherConfigs> {
1630 protected Builder<InterfaceOtherConfigs> builder() {
1631 return new InterfaceOtherConfigsBuilder();
1635 protected void setKey(Builder<InterfaceOtherConfigs> builder, String key) {
1636 ((InterfaceOtherConfigsBuilder) builder).setOtherConfigKey(key);
1640 protected void setValue(Builder<InterfaceOtherConfigs> builder, String value) {
1641 ((InterfaceOtherConfigsBuilder) builder).setOtherConfigValue(value);
1645 private static final class SouthboundPortOtherConfigsBuilder extends KeyValueBuilder<PortOtherConfigs> {
1647 protected Builder<PortOtherConfigs> builder() {
1648 return new PortOtherConfigsBuilder();
1652 protected void setKey(Builder<PortOtherConfigs> builder, String key) {
1653 ((PortOtherConfigsBuilder) builder).setOtherConfigKey(key);
1657 protected void setValue(Builder<PortOtherConfigs> builder, String value) {
1658 ((PortOtherConfigsBuilder) builder).setOtherConfigValue(value);
1662 private static final class SouthboundBridgeOtherConfigsBuilder extends KeyValueBuilder<BridgeOtherConfigs> {
1664 protected Builder<BridgeOtherConfigs> builder() {
1665 return new BridgeOtherConfigsBuilder();
1669 protected void setKey(Builder<BridgeOtherConfigs> builder, String key) {
1670 ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigKey(key);
1674 protected void setValue(Builder<BridgeOtherConfigs> builder, String value) {
1675 ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigValue(value);
1679 private static final class SouthboundBridgeExternalIdsBuilder extends KeyValueBuilder<BridgeExternalIds> {
1681 protected Builder<BridgeExternalIds> builder() {
1682 return new BridgeExternalIdsBuilder();
1686 protected void setKey(Builder<BridgeExternalIds> builder, String key) {
1687 ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdKey(key);
1691 protected void setValue(Builder<BridgeExternalIds> builder, String value) {
1692 ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdValue(value);
1697 * Generates the test cases involved in testing key-value-based data. See inline comments for descriptions of
1698 * the particular cases considered.
1700 private static <T> List<SouthboundTestCase<T>> generateKeyValueTestCases(
1701 KeyValueBuilder<T> builder, String testName) {
1702 List<SouthboundTestCase<T>> testCases = new ArrayList<>();
1704 final String GOOD_KEY = "GoodKey";
1705 final String GOOD_VALUE = "GoodValue";
1706 final String NO_VALUE_FOR_KEY = "NoValueForKey";
1708 final String idKey = testName + "Key";
1709 final String idValue = testName + "Value";
1711 // Test Case 1: TestOne
1712 // Test Type: Positive
1713 // Description: Create a termination point with one value
1714 // Expected: A port is created with the single value specified below
1715 final String testOneName = "TestOne" + testName;
1716 testCases.add(new SouthboundTestCaseBuilder<T>()
1718 .input(builder.build(testOneName, idKey, idValue))
1719 .expectInputAsOutput()
1722 // Test Case 2: TestFive
1723 // Test Type: Positive
1724 // Description: Create a termination point with multiple (five) values
1725 // Expected: A port is created with the five values specified below
1726 final String testFiveName = "TestFive" + testName;
1728 testCases.add(new SouthboundTestCaseBuilder<T>()
1731 builder.build(testFiveName, idKey, idValue),
1732 builder.build(testFiveName, idKey, idValue),
1733 builder.build(testFiveName, idKey, idValue),
1734 builder.build(testFiveName, idKey, idValue),
1735 builder.build(testFiveName, idKey, idValue))
1736 .expectInputAsOutput()
1739 // Test Case 3: TestOneGoodOneMalformedValue
1740 // Test Type: Negative
1742 // One perfectly fine input
1743 // (TestOneGoodOneMalformedValue_GoodKey_1,
1744 // TestOneGoodOneMalformedValue_GoodValue_1)
1745 // and one malformed input which only has key specified
1746 // (TestOneGoodOneMalformedValue_NoValueForKey_2,
1748 // Expected: A port is created without any values
1749 final String testOneGoodOneMalformedValueName = "TestOneGoodOneMalformedValue" + testName;
1751 testCases.add(new SouthboundTestCaseBuilder<T>()
1752 .name(testOneGoodOneMalformedValueName)
1754 builder.build(testOneGoodOneMalformedValueName, GOOD_KEY, GOOD_VALUE),
1755 builder.build(testOneGoodOneMalformedValueName, NO_VALUE_FOR_KEY, null))
1763 private static class PortExternalIdsSouthboundHelper implements SouthboundTerminationPointHelper<PortExternalIds> {
1765 public void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<PortExternalIds> values) {
1766 builder.setPortExternalIds(values);
1770 public List<PortExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
1771 return augmentation.getPortExternalIds();
1775 private static class InterfaceExternalIdsSouthboundHelper implements
1776 SouthboundTerminationPointHelper<InterfaceExternalIds> {
1778 public void writeValues(
1779 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceExternalIds> values) {
1780 builder.setInterfaceExternalIds(values);
1784 public List<InterfaceExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
1785 return augmentation.getInterfaceExternalIds();
1789 private static class OptionsSouthboundHelper implements SouthboundTerminationPointHelper<Options> {
1791 public void writeValues(
1792 OvsdbTerminationPointAugmentationBuilder builder, List<Options> values) {
1793 builder.setOptions(values);
1797 public List<Options> readValues(OvsdbTerminationPointAugmentation augmentation) {
1798 return augmentation.getOptions();
1802 private static class InterfaceOtherConfigsSouthboundHelper implements
1803 SouthboundTerminationPointHelper<InterfaceOtherConfigs> {
1805 public void writeValues(
1806 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceOtherConfigs> values) {
1807 builder.setInterfaceOtherConfigs(values);
1811 public List<InterfaceOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
1812 return augmentation.getInterfaceOtherConfigs();
1816 private static class PortOtherConfigsSouthboundHelper implements
1817 SouthboundTerminationPointHelper<PortOtherConfigs> {
1819 public void writeValues(
1820 OvsdbTerminationPointAugmentationBuilder builder, List<PortOtherConfigs> values) {
1821 builder.setPortOtherConfigs(values);
1825 public List<PortOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
1826 return augmentation.getPortOtherConfigs();
1830 private static class BridgeExternalIdsSouthboundHelper implements SouthboundBridgeHelper<BridgeExternalIds> {
1832 public void writeValues(
1833 OvsdbBridgeAugmentationBuilder builder, List<BridgeExternalIds> values) {
1834 builder.setBridgeExternalIds(values);
1838 public List<BridgeExternalIds> readValues(OvsdbBridgeAugmentation augmentation) {
1839 return augmentation.getBridgeExternalIds();
1843 private static class BridgeOtherConfigsSouthboundHelper implements SouthboundBridgeHelper<BridgeOtherConfigs> {
1845 public void writeValues(
1846 OvsdbBridgeAugmentationBuilder builder, List<BridgeOtherConfigs> values) {
1847 builder.setBridgeOtherConfigs(values);
1851 public List<BridgeOtherConfigs> readValues(OvsdbBridgeAugmentation augmentation) {
1852 return augmentation.getBridgeOtherConfigs();